10d16fef4Smrg/* 20a1d3ae0Smrg * Copyright © 2001 Keith Packard 30d16fef4Smrg * 2010 Intel Corporation 40d16fef4Smrg * 2012,2015 Advanced Micro Devices, Inc. 50d16fef4Smrg * 60a1d3ae0Smrg * Partly based on code Copyright © 2008 Red Hat, Inc. 70a1d3ae0Smrg * Partly based on code Copyright © 2000 SuSE, Inc. 80d16fef4Smrg * 90a1d3ae0Smrg * Partly based on code that is Copyright © The XFree86 Project Inc. 100d16fef4Smrg * 110d16fef4Smrg * Permission to use, copy, modify, distribute, and sell this software and its 120d16fef4Smrg * documentation for any purpose is hereby granted without fee, provided that 130d16fef4Smrg * the above copyright notice appear in all copies and that both that 140d16fef4Smrg * copyright notice and this permission notice appear in supporting 150d16fef4Smrg * documentation, and that the name of the opyright holders not be used in 160d16fef4Smrg * advertising or publicity pertaining to distribution of the software without 170d16fef4Smrg * specific, written prior permission. The copyright holders make no 180d16fef4Smrg * representations about the suitability of this software for any purpose. It 190d16fef4Smrg * is provided "as is" without express or implied warranty. 200d16fef4Smrg * 210d16fef4Smrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 220d16fef4Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 230d16fef4Smrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 240d16fef4Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 250d16fef4Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 260d16fef4Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 270d16fef4Smrg * PERFORMANCE OF THIS SOFTWARE. 280d16fef4Smrg */ 290d16fef4Smrg 300d16fef4Smrg 310d16fef4Smrg#ifdef HAVE_CONFIG_H 320d16fef4Smrg#include <config.h> 330d16fef4Smrg#endif 340d16fef4Smrg 350d16fef4Smrg#ifdef USE_GLAMOR 360d16fef4Smrg 370d16fef4Smrg#include "radeon.h" 387314432eSmrg#include "radeon_bo_helper.h" 390d16fef4Smrg#include "radeon_glamor.h" 400d16fef4Smrg 410d16fef4Smrg 420d16fef4Smrg/* Are there any outstanding GPU operations for this pixmap? */ 430d16fef4Smrgstatic Bool 440d16fef4Smrgradeon_glamor_gpu_pending(uint_fast32_t gpu_synced, uint_fast32_t gpu_access) 450d16fef4Smrg{ 460d16fef4Smrg return (int_fast32_t)(gpu_access - gpu_synced) > 0; 470d16fef4Smrg} 480d16fef4Smrg 490d16fef4Smrg/* 500d16fef4Smrg * Pixmap CPU access wrappers 510d16fef4Smrg */ 520d16fef4Smrg 530d16fef4Smrgstatic Bool 540d16fef4Smrgradeon_glamor_prepare_access_cpu(ScrnInfoPtr scrn, RADEONInfoPtr info, 550d16fef4Smrg PixmapPtr pixmap, struct radeon_pixmap *priv, 560d16fef4Smrg Bool need_sync) 570d16fef4Smrg{ 5839413783Smrg struct radeon_buffer *bo = priv->bo; 590d16fef4Smrg int ret; 600d16fef4Smrg 610d16fef4Smrg if (!pixmap->devPrivate.ptr) { 6239413783Smrg /* When falling back to swrast, flush all pending operations */ 6339413783Smrg if (need_sync) { 6439413783Smrg glamor_block_handler(scrn->pScreen); 6539413783Smrg info->gpu_flushed++; 6639413783Smrg } 6739413783Smrg 6839413783Smrg ret = radeon_bo_map(bo->bo.radeon, 1); 690d16fef4Smrg if (ret) { 700d16fef4Smrg xf86DrvMsg(scrn->scrnIndex, X_WARNING, 710d16fef4Smrg "%s: bo map (tiling_flags %d) failed: %s\n", 720d16fef4Smrg __FUNCTION__, 730d16fef4Smrg priv->tiling_flags, 740d16fef4Smrg strerror(-ret)); 750d16fef4Smrg return FALSE; 760d16fef4Smrg } 770d16fef4Smrg 7839413783Smrg pixmap->devPrivate.ptr = bo->bo.radeon->ptr; 7939413783Smrg } else if (need_sync) 8039413783Smrg radeon_finish(scrn, bo); 8139413783Smrg 8239413783Smrg info->gpu_synced = info->gpu_flushed; 830d16fef4Smrg 840d16fef4Smrg return TRUE; 850d16fef4Smrg} 860d16fef4Smrg 870d16fef4Smrgstatic Bool 880d16fef4Smrgradeon_glamor_prepare_access_cpu_ro(ScrnInfoPtr scrn, PixmapPtr pixmap, 890d16fef4Smrg struct radeon_pixmap *priv) 900d16fef4Smrg{ 910d16fef4Smrg RADEONInfoPtr info; 920d16fef4Smrg Bool need_sync; 930d16fef4Smrg 940d16fef4Smrg if (!priv) 950d16fef4Smrg return TRUE; 960d16fef4Smrg 970d16fef4Smrg info = RADEONPTR(scrn); 980d16fef4Smrg need_sync = radeon_glamor_gpu_pending(info->gpu_synced, priv->gpu_write); 990d16fef4Smrg return radeon_glamor_prepare_access_cpu(scrn, RADEONPTR(scrn), pixmap, 1000d16fef4Smrg priv, need_sync); 1010d16fef4Smrg} 1020d16fef4Smrg 1030d16fef4Smrgstatic Bool 1040d16fef4Smrgradeon_glamor_prepare_access_cpu_rw(ScrnInfoPtr scrn, PixmapPtr pixmap, 1050d16fef4Smrg struct radeon_pixmap *priv) 1060d16fef4Smrg{ 1070d16fef4Smrg RADEONInfoPtr info; 1080d16fef4Smrg uint_fast32_t gpu_synced; 1090d16fef4Smrg Bool need_sync; 1100d16fef4Smrg 1110d16fef4Smrg if (!priv) 1120d16fef4Smrg return TRUE; 1130d16fef4Smrg 1140d16fef4Smrg info = RADEONPTR(scrn); 1150d16fef4Smrg gpu_synced = info->gpu_synced; 1160d16fef4Smrg need_sync = radeon_glamor_gpu_pending(gpu_synced, priv->gpu_write) | 1170d16fef4Smrg radeon_glamor_gpu_pending(gpu_synced, priv->gpu_read); 1180d16fef4Smrg return radeon_glamor_prepare_access_cpu(scrn, info, pixmap, priv, 1190d16fef4Smrg need_sync); 1200d16fef4Smrg} 1210d16fef4Smrg 1220d16fef4Smrgstatic void 1230d16fef4Smrgradeon_glamor_finish_access_cpu(PixmapPtr pixmap) 1240d16fef4Smrg{ 1250d16fef4Smrg /* Nothing to do */ 1260d16fef4Smrg} 1270d16fef4Smrg 1280d16fef4Smrg/* 1290d16fef4Smrg * Pixmap GPU access wrappers 1300d16fef4Smrg */ 1310d16fef4Smrg 1320d16fef4Smrgstatic Bool 1330d16fef4Smrgradeon_glamor_prepare_access_gpu(struct radeon_pixmap *priv) 1340d16fef4Smrg{ 13539413783Smrg return !!priv; 1360d16fef4Smrg} 1370d16fef4Smrg 1380d16fef4Smrgstatic void 1390d16fef4Smrgradeon_glamor_finish_access_gpu_ro(RADEONInfoPtr info, 1400d16fef4Smrg struct radeon_pixmap *priv) 1410d16fef4Smrg{ 1420d16fef4Smrg priv->gpu_read = info->gpu_flushed + 1; 1430d16fef4Smrg} 1440d16fef4Smrg 1450d16fef4Smrgstatic void 1460d16fef4Smrgradeon_glamor_finish_access_gpu_rw(RADEONInfoPtr info, 1470d16fef4Smrg struct radeon_pixmap *priv) 1480d16fef4Smrg{ 1490d16fef4Smrg priv->gpu_write = priv->gpu_read = info->gpu_flushed + 1; 1500d16fef4Smrg} 1510d16fef4Smrg 1520d16fef4Smrg/* 1530d16fef4Smrg * GC CPU access wrappers 1540d16fef4Smrg */ 1550d16fef4Smrg 1560d16fef4Smrgstatic Bool 1570d16fef4Smrgradeon_glamor_prepare_access_gc(ScrnInfoPtr scrn, GCPtr pGC) 1580d16fef4Smrg{ 1590d16fef4Smrg struct radeon_pixmap *priv; 1600d16fef4Smrg 1610d16fef4Smrg if (pGC->stipple) { 1620d16fef4Smrg priv = radeon_get_pixmap_private(pGC->stipple); 1630d16fef4Smrg if (!radeon_glamor_prepare_access_cpu_ro(scrn, pGC->stipple, priv)) 1640d16fef4Smrg return FALSE; 1650d16fef4Smrg } 1660d16fef4Smrg if (pGC->fillStyle == FillTiled) { 1670d16fef4Smrg priv = radeon_get_pixmap_private(pGC->tile.pixmap); 1680d16fef4Smrg if (!radeon_glamor_prepare_access_cpu_ro(scrn, pGC->tile.pixmap, 1690d16fef4Smrg priv)) { 1700d16fef4Smrg if (pGC->stipple) 1710d16fef4Smrg radeon_glamor_finish_access_cpu(pGC->stipple); 1720d16fef4Smrg return FALSE; 1730d16fef4Smrg } 1740d16fef4Smrg } 1750d16fef4Smrg return TRUE; 1760d16fef4Smrg} 1770d16fef4Smrg 1780d16fef4Smrgstatic void 1790d16fef4Smrgradeon_glamor_finish_access_gc(GCPtr pGC) 1800d16fef4Smrg{ 1810d16fef4Smrg if (pGC->fillStyle == FillTiled) 1820d16fef4Smrg radeon_glamor_finish_access_cpu(pGC->tile.pixmap); 1830d16fef4Smrg if (pGC->stipple) 1840d16fef4Smrg radeon_glamor_finish_access_cpu(pGC->stipple); 1850d16fef4Smrg} 1860d16fef4Smrg 1870d16fef4Smrg/* 1880d16fef4Smrg * Picture CPU access wrappers 1890d16fef4Smrg */ 1900d16fef4Smrg 1910d16fef4Smrgstatic void 1920d16fef4Smrgradeon_glamor_picture_finish_access_cpu(PicturePtr picture) 1930d16fef4Smrg{ 1940d16fef4Smrg /* Nothing to do */ 1950d16fef4Smrg} 1960d16fef4Smrg 1970d16fef4Smrgstatic Bool 1980d16fef4Smrgradeon_glamor_picture_prepare_access_cpu_ro(ScrnInfoPtr scrn, 1990d16fef4Smrg PicturePtr picture) 2000d16fef4Smrg{ 2010d16fef4Smrg PixmapPtr pixmap; 2020d16fef4Smrg struct radeon_pixmap *priv; 2030d16fef4Smrg 20439413783Smrg if (!picture->pDrawable) 2050d16fef4Smrg return TRUE; 2060d16fef4Smrg 2070d16fef4Smrg pixmap = get_drawable_pixmap(picture->pDrawable); 2080d16fef4Smrg priv = radeon_get_pixmap_private(pixmap); 2090d16fef4Smrg if (!radeon_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) 2100d16fef4Smrg return FALSE; 2110d16fef4Smrg 2120d16fef4Smrg if (picture->alphaMap) { 2130d16fef4Smrg pixmap = get_drawable_pixmap(picture->alphaMap->pDrawable); 2140d16fef4Smrg priv = radeon_get_pixmap_private(pixmap); 2150d16fef4Smrg if (!radeon_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) { 2160d16fef4Smrg radeon_glamor_picture_finish_access_cpu(picture); 2170d16fef4Smrg return FALSE; 2180d16fef4Smrg } 2190d16fef4Smrg } 2200d16fef4Smrg 2210d16fef4Smrg return TRUE; 2220d16fef4Smrg} 2230d16fef4Smrg 2240d16fef4Smrgstatic Bool 2250d16fef4Smrgradeon_glamor_picture_prepare_access_cpu_rw(ScrnInfoPtr scrn, 2260d16fef4Smrg PicturePtr picture) 2270d16fef4Smrg{ 2280d16fef4Smrg PixmapPtr pixmap; 2290d16fef4Smrg struct radeon_pixmap *priv; 2300d16fef4Smrg 2310d16fef4Smrg pixmap = get_drawable_pixmap(picture->pDrawable); 2320d16fef4Smrg priv = radeon_get_pixmap_private(pixmap); 2330d16fef4Smrg if (!radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) 2340d16fef4Smrg return FALSE; 2350d16fef4Smrg 2360d16fef4Smrg if (picture->alphaMap) { 2370d16fef4Smrg pixmap = get_drawable_pixmap(picture->alphaMap->pDrawable); 2380d16fef4Smrg priv = radeon_get_pixmap_private(pixmap); 2390d16fef4Smrg if (!radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 2400d16fef4Smrg radeon_glamor_picture_finish_access_cpu(picture); 2410d16fef4Smrg return FALSE; 2420d16fef4Smrg } 2430d16fef4Smrg } 2440d16fef4Smrg 2450d16fef4Smrg return TRUE; 2460d16fef4Smrg} 2470d16fef4Smrg 2480d16fef4Smrg/* 2490d16fef4Smrg * GC rendering wrappers 2500d16fef4Smrg */ 2510d16fef4Smrg 2520d16fef4Smrgstatic void 2530d16fef4Smrgradeon_glamor_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int nspans, 2540d16fef4Smrg DDXPointPtr ppt, int *pwidth, int fSorted) 2550d16fef4Smrg{ 2560d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 2570d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 2580d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 2590d16fef4Smrg 2600d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 2610d16fef4Smrg if (radeon_glamor_prepare_access_gc(scrn, pGC)) { 2620d16fef4Smrg fbFillSpans(pDrawable, pGC, nspans, ppt, pwidth, 2630d16fef4Smrg fSorted); 2640d16fef4Smrg radeon_glamor_finish_access_gc(pGC); 2650d16fef4Smrg } 2660d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 2670d16fef4Smrg } 2680d16fef4Smrg} 2690d16fef4Smrg 2700d16fef4Smrgstatic void 2710d16fef4Smrgradeon_glamor_set_spans(DrawablePtr pDrawable, GCPtr pGC, char *psrc, 2720d16fef4Smrg DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) 2730d16fef4Smrg{ 2740d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 2750d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 2760d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 2770d16fef4Smrg 2780d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 2790d16fef4Smrg fbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); 2800d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 2810d16fef4Smrg } 2820d16fef4Smrg} 2830d16fef4Smrg 2840d16fef4Smrgstatic void 2850d16fef4Smrgradeon_glamor_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, 2860d16fef4Smrg int x, int y, int w, int h, int leftPad, int format, 2870d16fef4Smrg char *bits) 2880d16fef4Smrg{ 2890d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 2900d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 2910d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 2920d16fef4Smrg 2930d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 2940d16fef4Smrg fbPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, 2950d16fef4Smrg bits); 2960d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 2970d16fef4Smrg } 2980d16fef4Smrg} 2990d16fef4Smrg 3000d16fef4Smrgstatic RegionPtr 3010d16fef4Smrgradeon_glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 3020d16fef4Smrg int srcx, int srcy, int w, int h, int dstx, int dsty, 3030d16fef4Smrg unsigned long bitPlane) 3040d16fef4Smrg{ 3050d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pScreen); 3060d16fef4Smrg PixmapPtr dst_pix = get_drawable_pixmap(pDst); 3070d16fef4Smrg struct radeon_pixmap *dst_priv = radeon_get_pixmap_private(dst_pix); 3080d16fef4Smrg RegionPtr ret = NULL; 3090d16fef4Smrg 3100d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, dst_pix, dst_priv)) { 3110d16fef4Smrg PixmapPtr src_pix = get_drawable_pixmap(pSrc); 3120d16fef4Smrg struct radeon_pixmap *src_priv = radeon_get_pixmap_private(src_pix); 3130d16fef4Smrg if (radeon_glamor_prepare_access_cpu_ro(scrn, src_pix, src_priv)) { 3140d16fef4Smrg ret = 3150d16fef4Smrg fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, 3160d16fef4Smrg dsty, bitPlane); 3170d16fef4Smrg radeon_glamor_finish_access_cpu(src_pix); 3180d16fef4Smrg } 3190d16fef4Smrg radeon_glamor_finish_access_cpu(dst_pix); 3200d16fef4Smrg } 3210d16fef4Smrg return ret; 3220d16fef4Smrg} 3230d16fef4Smrg 3240d16fef4Smrgstatic RegionPtr 3250d16fef4Smrgradeon_glamor_copy_plane_nodstbo(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 3260d16fef4Smrg int srcx, int srcy, int w, int h, 3270d16fef4Smrg int dstx, int dsty, unsigned long bitPlane) 3280d16fef4Smrg{ 3290d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pScreen); 3300d16fef4Smrg PixmapPtr src_pix = get_drawable_pixmap(pSrc); 3310d16fef4Smrg struct radeon_pixmap *src_priv = radeon_get_pixmap_private(src_pix); 3320d16fef4Smrg RegionPtr ret = NULL; 3330d16fef4Smrg 3340d16fef4Smrg if (radeon_glamor_prepare_access_cpu_ro(scrn, src_pix, src_priv)) { 3350d16fef4Smrg ret = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, 3360d16fef4Smrg dstx, dsty, bitPlane); 3370d16fef4Smrg radeon_glamor_finish_access_cpu(src_pix); 3380d16fef4Smrg } 3390d16fef4Smrg return ret; 3400d16fef4Smrg} 3410d16fef4Smrg 3420d16fef4Smrgstatic void 3430d16fef4Smrgradeon_glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, 3440d16fef4Smrg DDXPointPtr pptInit) 3450d16fef4Smrg{ 3460d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 3470d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 3480d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 3490d16fef4Smrg 3500d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 3510d16fef4Smrg fbPolyPoint(pDrawable, pGC, mode, npt, pptInit); 3520d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 3530d16fef4Smrg } 3540d16fef4Smrg} 3550d16fef4Smrg 3560d16fef4Smrgstatic void 3570d16fef4Smrgradeon_glamor_poly_lines(DrawablePtr pDrawable, GCPtr pGC, 3580d16fef4Smrg int mode, int npt, DDXPointPtr ppt) 3590d16fef4Smrg{ 3600d16fef4Smrg if (pGC->lineWidth == 0) { 3610d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 3620d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 3630d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 3640d16fef4Smrg 3650d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 3660d16fef4Smrg if (radeon_glamor_prepare_access_gc(scrn, pGC)) { 3670d16fef4Smrg fbPolyLine(pDrawable, pGC, mode, npt, ppt); 3680d16fef4Smrg radeon_glamor_finish_access_gc(pGC); 3690d16fef4Smrg } 3700d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 3710d16fef4Smrg } 3720d16fef4Smrg return; 3730d16fef4Smrg } 3740d16fef4Smrg /* fb calls mi functions in the lineWidth != 0 case. */ 3750d16fef4Smrg fbPolyLine(pDrawable, pGC, mode, npt, ppt); 3760d16fef4Smrg} 3770d16fef4Smrg 3780d16fef4Smrgstatic void 3790d16fef4Smrgradeon_glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, 3800d16fef4Smrg int nsegInit, xSegment *pSegInit) 3810d16fef4Smrg{ 3820d16fef4Smrg if (pGC->lineWidth == 0) { 3830d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 3840d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 3850d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 3860d16fef4Smrg 3870d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 3880d16fef4Smrg if (radeon_glamor_prepare_access_gc(scrn, pGC)) { 3890d16fef4Smrg fbPolySegment(pDrawable, pGC, nsegInit, 3900d16fef4Smrg pSegInit); 3910d16fef4Smrg radeon_glamor_finish_access_gc(pGC); 3920d16fef4Smrg } 3930d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 3940d16fef4Smrg } 3950d16fef4Smrg return; 3960d16fef4Smrg } 3970d16fef4Smrg /* fb calls mi functions in the lineWidth != 0 case. */ 3980d16fef4Smrg fbPolySegment(pDrawable, pGC, nsegInit, pSegInit); 3990d16fef4Smrg} 4000d16fef4Smrg 4010d16fef4Smrgstatic void 4020d16fef4Smrgradeon_glamor_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC, 4030d16fef4Smrg int nrect, xRectangle *prect) 4040d16fef4Smrg{ 4050d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 4060d16fef4Smrg RADEONInfoPtr info = RADEONPTR(scrn); 4070d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 4080d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 4090d16fef4Smrg 4100d16fef4Smrg if ((info->accel_state->force || (priv && !priv->bo)) && 4110d16fef4Smrg radeon_glamor_prepare_access_gpu(priv)) { 4120d16fef4Smrg info->glamor.SavedPolyFillRect(pDrawable, pGC, nrect, prect); 4130d16fef4Smrg radeon_glamor_finish_access_gpu_rw(info, priv); 4140d16fef4Smrg return; 4150d16fef4Smrg } 4160d16fef4Smrg 4170d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 4180d16fef4Smrg if (radeon_glamor_prepare_access_gc(scrn, pGC)) { 4190d16fef4Smrg fbPolyFillRect(pDrawable, pGC, nrect, prect); 4200d16fef4Smrg radeon_glamor_finish_access_gc(pGC); 4210d16fef4Smrg } 4220d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 4230d16fef4Smrg } 4240d16fef4Smrg} 4250d16fef4Smrg 4260d16fef4Smrgstatic void 4270d16fef4Smrgradeon_glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, 4280d16fef4Smrg int x, int y, unsigned int nglyph, 4290d16fef4Smrg CharInfoPtr *ppci, pointer pglyphBase) 4300d16fef4Smrg{ 4310d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 4320d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 4330d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 4340d16fef4Smrg 4350d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 4360d16fef4Smrg if (radeon_glamor_prepare_access_gc(scrn, pGC)) { 4370d16fef4Smrg fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, 4380d16fef4Smrg pglyphBase); 4390d16fef4Smrg radeon_glamor_finish_access_gc(pGC); 4400d16fef4Smrg } 4410d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 4420d16fef4Smrg } 4430d16fef4Smrg} 4440d16fef4Smrg 4450d16fef4Smrgstatic void 4460d16fef4Smrgradeon_glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, 4470d16fef4Smrg int x, int y, unsigned int nglyph, 4480d16fef4Smrg CharInfoPtr *ppci, pointer pglyphBase) 4490d16fef4Smrg{ 4500d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 4510d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 4520d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 4530d16fef4Smrg 4540d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 4550d16fef4Smrg if (radeon_glamor_prepare_access_gc(scrn, pGC)) { 4560d16fef4Smrg fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, 4570d16fef4Smrg pglyphBase); 4580d16fef4Smrg radeon_glamor_finish_access_gc(pGC); 4590d16fef4Smrg } 4600d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 4610d16fef4Smrg } 4620d16fef4Smrg} 4630d16fef4Smrg 4640d16fef4Smrgstatic void 4650d16fef4Smrgradeon_glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, 4660d16fef4Smrg DrawablePtr pDrawable, int w, int h, int x, int y) 4670d16fef4Smrg{ 4680d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 4690d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 4700d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 4710d16fef4Smrg 4720d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 4730d16fef4Smrg priv = radeon_get_pixmap_private(pBitmap); 4740d16fef4Smrg if (radeon_glamor_prepare_access_cpu_ro(scrn, pBitmap, priv)) { 4750d16fef4Smrg if (radeon_glamor_prepare_access_gc(scrn, pGC)) { 4760d16fef4Smrg fbPushPixels(pGC, pBitmap, pDrawable, w, h, x, 4770d16fef4Smrg y); 4780d16fef4Smrg radeon_glamor_finish_access_gc(pGC); 4790d16fef4Smrg } 4800d16fef4Smrg radeon_glamor_finish_access_cpu(pBitmap); 4810d16fef4Smrg } 4820d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 4830d16fef4Smrg } 4840d16fef4Smrg} 4850d16fef4Smrg 4860d16fef4Smrgstatic void 4870d16fef4Smrgradeon_glamor_push_pixels_nodstbo(GCPtr pGC, PixmapPtr pBitmap, 4880d16fef4Smrg DrawablePtr pDrawable, int w, int h, 4890d16fef4Smrg int x, int y) 4900d16fef4Smrg{ 4910d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 4920d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pBitmap); 4930d16fef4Smrg 4940d16fef4Smrg if (radeon_glamor_prepare_access_cpu_ro(scrn, pBitmap, priv)) { 4950d16fef4Smrg fbPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); 4960d16fef4Smrg radeon_glamor_finish_access_cpu(pBitmap); 4970d16fef4Smrg } 4980d16fef4Smrg} 4990d16fef4Smrg 5000d16fef4Smrgstatic RegionPtr 5010d16fef4Smrgradeon_glamor_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, 5020d16fef4Smrg GCPtr pGC, int srcx, int srcy, int width, int height, 5030d16fef4Smrg int dstx, int dsty) 5040d16fef4Smrg{ 5050d16fef4Smrg ScreenPtr screen = pDstDrawable->pScreen; 5060d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 5070d16fef4Smrg RADEONInfoPtr info = RADEONPTR(scrn); 5080d16fef4Smrg PixmapPtr src_pixmap = get_drawable_pixmap(pSrcDrawable); 5090d16fef4Smrg PixmapPtr dst_pixmap = get_drawable_pixmap(pDstDrawable); 5100d16fef4Smrg struct radeon_pixmap *src_priv = radeon_get_pixmap_private(src_pixmap); 5110d16fef4Smrg struct radeon_pixmap *dst_priv = radeon_get_pixmap_private(dst_pixmap); 5120d16fef4Smrg RegionPtr ret = NULL; 5130d16fef4Smrg 5140d16fef4Smrg if (info->accel_state->force || (src_priv && !src_priv->bo) || 5150d16fef4Smrg (dst_priv && !dst_priv->bo)) { 5160d16fef4Smrg if (!radeon_glamor_prepare_access_gpu(dst_priv)) 5170d16fef4Smrg goto fallback; 5180d16fef4Smrg if (src_priv != dst_priv && 5190d16fef4Smrg !radeon_glamor_prepare_access_gpu(src_priv)) 5200d16fef4Smrg goto fallback; 5210d16fef4Smrg 5220d16fef4Smrg ret = info->glamor.SavedCopyArea(pSrcDrawable, pDstDrawable, 5230d16fef4Smrg pGC, srcx, srcy, 5240d16fef4Smrg width, height, dstx, dsty); 5250d16fef4Smrg radeon_glamor_finish_access_gpu_rw(info, dst_priv); 5260d16fef4Smrg if (src_priv != dst_priv) 5270d16fef4Smrg radeon_glamor_finish_access_gpu_ro(info, src_priv); 5280d16fef4Smrg 5290d16fef4Smrg return ret; 5300d16fef4Smrg } 5310d16fef4Smrg 5320d16fef4Smrgfallback: 5330d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, dst_pixmap, dst_priv)) { 5340d16fef4Smrg if (pSrcDrawable == pDstDrawable || 5350d16fef4Smrg radeon_glamor_prepare_access_cpu_ro(scrn, src_pixmap, 5360d16fef4Smrg src_priv)) { 5370d16fef4Smrg ret = fbCopyArea(pSrcDrawable, pDstDrawable, pGC, 5380d16fef4Smrg srcx, srcy, width, height, dstx, dsty); 5390d16fef4Smrg if (pSrcDrawable != pDstDrawable) 5400d16fef4Smrg radeon_glamor_finish_access_cpu(src_pixmap); 5410d16fef4Smrg } 5420d16fef4Smrg radeon_glamor_finish_access_cpu(dst_pixmap); 5430d16fef4Smrg } 5440d16fef4Smrg 5450d16fef4Smrg return ret; 5460d16fef4Smrg} 5470d16fef4Smrg 5480d16fef4Smrgstatic RegionPtr 5490d16fef4Smrgradeon_glamor_copy_area_nodstbo(DrawablePtr pSrcDrawable, 5500d16fef4Smrg DrawablePtr pDstDrawable, GCPtr pGC, 5510d16fef4Smrg int srcx, int srcy, int width, int height, 5520d16fef4Smrg int dstx, int dsty) 5530d16fef4Smrg{ 5540d16fef4Smrg ScreenPtr screen = pDstDrawable->pScreen; 5550d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 5560d16fef4Smrg PixmapPtr src_pixmap = get_drawable_pixmap(pSrcDrawable); 5570d16fef4Smrg PixmapPtr dst_pixmap = get_drawable_pixmap(pDstDrawable); 5580d16fef4Smrg struct radeon_pixmap *src_priv; 5590d16fef4Smrg RegionPtr ret = NULL; 5600d16fef4Smrg 5610d16fef4Smrg if (src_pixmap != dst_pixmap) { 5620d16fef4Smrg src_priv = radeon_get_pixmap_private(src_pixmap); 5630d16fef4Smrg 5640d16fef4Smrg if (!radeon_glamor_prepare_access_cpu_ro(scrn, src_pixmap, 5650d16fef4Smrg src_priv)) 5660d16fef4Smrg return ret; 5670d16fef4Smrg } 5680d16fef4Smrg 5690d16fef4Smrg ret = fbCopyArea(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, 5700d16fef4Smrg width, height, dstx, dsty); 5710d16fef4Smrg 5720d16fef4Smrg if (src_pixmap != dst_pixmap) 5730d16fef4Smrg radeon_glamor_finish_access_cpu(src_pixmap); 5740d16fef4Smrg 5750d16fef4Smrg return ret; 5760d16fef4Smrg} 5770d16fef4Smrg 5780d16fef4Smrgstatic const GCOps radeon_glamor_ops = { 5790d16fef4Smrg radeon_glamor_fill_spans, 5800d16fef4Smrg radeon_glamor_set_spans, 5810d16fef4Smrg radeon_glamor_put_image, 5820d16fef4Smrg radeon_glamor_copy_area, 5830d16fef4Smrg radeon_glamor_copy_plane, 5840d16fef4Smrg radeon_glamor_poly_point, 5850d16fef4Smrg radeon_glamor_poly_lines, 5860d16fef4Smrg radeon_glamor_poly_segment, 5870d16fef4Smrg miPolyRectangle, 5880d16fef4Smrg miPolyArc, 5890d16fef4Smrg miFillPolygon, 5900d16fef4Smrg radeon_glamor_poly_fill_rect, 5910d16fef4Smrg miPolyFillArc, 5920d16fef4Smrg miPolyText8, 5930d16fef4Smrg miPolyText16, 5940d16fef4Smrg miImageText8, 5950d16fef4Smrg miImageText16, 5960d16fef4Smrg radeon_glamor_image_glyph_blt, 5970d16fef4Smrg radeon_glamor_poly_glyph_blt, 5980d16fef4Smrg radeon_glamor_push_pixels, 5990d16fef4Smrg}; 6000d16fef4Smrg 6010d16fef4Smrgstatic GCOps radeon_glamor_nodstbo_ops; 6020d16fef4Smrg 6030d16fef4Smrg/** 6040d16fef4Smrg * radeon_glamor_validate_gc() sets the ops to our implementations, which may be 6050d16fef4Smrg * accelerated or may sync the card and fall back to fb. 6060d16fef4Smrg */ 6070d16fef4Smrgstatic void 6080d16fef4Smrgradeon_glamor_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 6090d16fef4Smrg{ 6100d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pGC->pScreen); 6110d16fef4Smrg RADEONInfoPtr info = RADEONPTR(scrn); 6120d16fef4Smrg 6130d16fef4Smrg glamor_validate_gc(pGC, changes, pDrawable); 6140d16fef4Smrg info->glamor.SavedCopyArea = pGC->ops->CopyArea; 6150d16fef4Smrg info->glamor.SavedPolyFillRect = pGC->ops->PolyFillRect; 6160d16fef4Smrg 6170d16fef4Smrg if (radeon_get_pixmap_private(get_drawable_pixmap(pDrawable)) || 6180d16fef4Smrg (pGC->stipple && radeon_get_pixmap_private(pGC->stipple)) || 6190d16fef4Smrg (pGC->fillStyle == FillTiled && 6200d16fef4Smrg radeon_get_pixmap_private(pGC->tile.pixmap))) 6210d16fef4Smrg pGC->ops = (GCOps *)&radeon_glamor_ops; 6220d16fef4Smrg else 6230d16fef4Smrg pGC->ops = &radeon_glamor_nodstbo_ops; 6240d16fef4Smrg} 6250d16fef4Smrg 6260d16fef4Smrgstatic GCFuncs glamorGCFuncs = { 6270d16fef4Smrg radeon_glamor_validate_gc, 6280d16fef4Smrg miChangeGC, 6290d16fef4Smrg miCopyGC, 6300d16fef4Smrg miDestroyGC, 6310d16fef4Smrg miChangeClip, 6320d16fef4Smrg miDestroyClip, 6330d16fef4Smrg miCopyClip 6340d16fef4Smrg}; 6350d16fef4Smrg 6360d16fef4Smrg/** 6370d16fef4Smrg * radeon_glamor_create_gc makes a new GC and hooks up its funcs handler, so that 6380d16fef4Smrg * radeon_glamor_validate_gc() will get called. 6390d16fef4Smrg */ 6400d16fef4Smrgstatic int 6410d16fef4Smrgradeon_glamor_create_gc(GCPtr pGC) 6420d16fef4Smrg{ 6430d16fef4Smrg static Bool nodstbo_ops_initialized; 6440d16fef4Smrg 6450d16fef4Smrg if (!fbCreateGC(pGC)) 6460d16fef4Smrg return FALSE; 6470d16fef4Smrg 6480d16fef4Smrg if (!nodstbo_ops_initialized) { 6490d16fef4Smrg radeon_glamor_nodstbo_ops = radeon_glamor_ops; 6500d16fef4Smrg 6510d16fef4Smrg radeon_glamor_nodstbo_ops.FillSpans = pGC->ops->FillSpans; 6520d16fef4Smrg radeon_glamor_nodstbo_ops.SetSpans = pGC->ops->SetSpans; 6530d16fef4Smrg radeon_glamor_nodstbo_ops.PutImage = pGC->ops->PutImage; 6540d16fef4Smrg radeon_glamor_nodstbo_ops.CopyArea = radeon_glamor_copy_area_nodstbo; 6550d16fef4Smrg radeon_glamor_nodstbo_ops.CopyPlane = radeon_glamor_copy_plane_nodstbo; 6560d16fef4Smrg radeon_glamor_nodstbo_ops.PolyPoint = pGC->ops->PolyPoint; 6570d16fef4Smrg radeon_glamor_nodstbo_ops.Polylines = pGC->ops->Polylines; 6580d16fef4Smrg radeon_glamor_nodstbo_ops.PolySegment = pGC->ops->PolySegment; 6590d16fef4Smrg radeon_glamor_nodstbo_ops.PolyFillRect = pGC->ops->PolyFillRect; 6600d16fef4Smrg radeon_glamor_nodstbo_ops.ImageGlyphBlt = pGC->ops->ImageGlyphBlt; 6610d16fef4Smrg radeon_glamor_nodstbo_ops.PolyGlyphBlt = pGC->ops->PolyGlyphBlt; 6620d16fef4Smrg radeon_glamor_nodstbo_ops.PushPixels = radeon_glamor_push_pixels_nodstbo; 6630d16fef4Smrg 6640d16fef4Smrg nodstbo_ops_initialized = TRUE; 6650d16fef4Smrg } 6660d16fef4Smrg 6670d16fef4Smrg pGC->funcs = &glamorGCFuncs; 6680d16fef4Smrg 6690d16fef4Smrg return TRUE; 6700d16fef4Smrg} 6710d16fef4Smrg 6720d16fef4Smrg/* 6730d16fef4Smrg * Screen rendering wrappers 6740d16fef4Smrg */ 6750d16fef4Smrg 6760d16fef4Smrgstatic RegionPtr 6770d16fef4Smrgradeon_glamor_bitmap_to_region(PixmapPtr pPix) 6780d16fef4Smrg{ 6790d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen); 6800d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pPix); 6810d16fef4Smrg RegionPtr ret; 6820d16fef4Smrg 6830d16fef4Smrg if (!radeon_glamor_prepare_access_cpu_ro(scrn, pPix, priv)) 6840d16fef4Smrg return NULL; 6850d16fef4Smrg ret = fbPixmapToRegion(pPix); 6860d16fef4Smrg radeon_glamor_finish_access_cpu(pPix); 6870d16fef4Smrg return ret; 6880d16fef4Smrg} 6890d16fef4Smrg 6900d16fef4Smrgstatic void 6910d16fef4Smrgradeon_glamor_copy_window(WindowPtr pWin, DDXPointRec ptOldOrg, 6920d16fef4Smrg RegionPtr prgnSrc) 6930d16fef4Smrg{ 6940d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pWin->drawable.pScreen); 6950d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(&pWin->drawable); 6960d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 6970d16fef4Smrg 6980d16fef4Smrg if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 6990d16fef4Smrg fbCopyWindow(pWin, ptOldOrg, prgnSrc); 7000d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 7010d16fef4Smrg } 7020d16fef4Smrg} 7030d16fef4Smrg 7040d16fef4Smrgstatic void 7050d16fef4Smrgradeon_glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, 7060d16fef4Smrg unsigned int format, unsigned long planeMask, char *d) 7070d16fef4Smrg{ 7080d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 7090d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 7100d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 7110d16fef4Smrg 7120d16fef4Smrg if (radeon_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) { 7130d16fef4Smrg fbGetImage(pDrawable, x, y, w, h, format, planeMask, d); 7140d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 7150d16fef4Smrg } 7160d16fef4Smrg} 7170d16fef4Smrg 7180d16fef4Smrgstatic void 7190d16fef4Smrgradeon_glamor_get_spans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, 7200d16fef4Smrg int *pwidth, int nspans, char *pdstStart) 7210d16fef4Smrg{ 7220d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 7230d16fef4Smrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 7240d16fef4Smrg struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); 7250d16fef4Smrg 7260d16fef4Smrg if (radeon_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) { 7270d16fef4Smrg fbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); 7280d16fef4Smrg radeon_glamor_finish_access_cpu(pixmap); 7290d16fef4Smrg } 7300d16fef4Smrg} 7310d16fef4Smrg 7320d16fef4Smrg/* 7330d16fef4Smrg * Picture screen rendering wrappers 7340d16fef4Smrg */ 7350d16fef4Smrg 7360d16fef4Smrg#ifdef RENDER 7370d16fef4Smrg 7380d16fef4Smrgstatic void 7390d16fef4Smrgradeon_glamor_composite(CARD8 op, 7400d16fef4Smrg PicturePtr pSrc, 7410d16fef4Smrg PicturePtr pMask, 7420d16fef4Smrg PicturePtr pDst, 7430d16fef4Smrg INT16 xSrc, INT16 ySrc, 7440d16fef4Smrg INT16 xMask, INT16 yMask, 7450d16fef4Smrg INT16 xDst, INT16 yDst, 7460d16fef4Smrg CARD16 width, CARD16 height) 7470d16fef4Smrg{ 7480d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pDrawable->pScreen); 7490d16fef4Smrg RADEONInfoPtr info; 7500d16fef4Smrg PixmapPtr pixmap; 7510d16fef4Smrg struct radeon_pixmap *dst_priv, *src_priv = NULL, *mask_priv = NULL; 7520d16fef4Smrg Bool gpu_done = FALSE; 7530d16fef4Smrg 7540d16fef4Smrg if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) 7550d16fef4Smrg goto fallback; 7560d16fef4Smrg 7570d16fef4Smrg pixmap = get_drawable_pixmap(pDst->pDrawable); 7580d16fef4Smrg if (&pixmap->drawable != pDst->pDrawable || 7590d16fef4Smrg pixmap->usage_hint != RADEON_CREATE_PIXMAP_SCANOUT) 7600d16fef4Smrg goto fallback; 7610d16fef4Smrg 7620d16fef4Smrg dst_priv = radeon_get_pixmap_private(pixmap); 7630d16fef4Smrg if (!radeon_glamor_prepare_access_gpu(dst_priv)) 7640d16fef4Smrg goto fallback; 7650d16fef4Smrg 7660d16fef4Smrg info = RADEONPTR(scrn); 7670d16fef4Smrg if (!pSrc->pDrawable || 7680d16fef4Smrg ((pixmap = get_drawable_pixmap(pSrc->pDrawable)) && 7690d16fef4Smrg (src_priv = radeon_get_pixmap_private(pixmap)) && 7700d16fef4Smrg radeon_glamor_prepare_access_gpu(src_priv))) { 7710d16fef4Smrg if (!pMask || !pMask->pDrawable || 7720d16fef4Smrg ((pixmap = get_drawable_pixmap(pMask->pDrawable)) && 7730d16fef4Smrg (mask_priv = radeon_get_pixmap_private(pixmap)) && 7740d16fef4Smrg radeon_glamor_prepare_access_gpu(mask_priv))) { 7750d16fef4Smrg info->glamor.SavedComposite(op, pSrc, pMask, pDst, 7760d16fef4Smrg xSrc, ySrc, xMask, yMask, 7770d16fef4Smrg xDst, yDst, width, height); 7780d16fef4Smrg gpu_done = TRUE; 7790d16fef4Smrg 7800d16fef4Smrg if (mask_priv) 7810d16fef4Smrg radeon_glamor_finish_access_gpu_ro(info, mask_priv); 7820d16fef4Smrg } 7830d16fef4Smrg 7840d16fef4Smrg if (src_priv) 7850d16fef4Smrg radeon_glamor_finish_access_gpu_ro(info, src_priv); 7860d16fef4Smrg } 7870d16fef4Smrg radeon_glamor_finish_access_gpu_rw(info, dst_priv); 7880d16fef4Smrg 7890d16fef4Smrg if (gpu_done) 7900d16fef4Smrg return; 7910d16fef4Smrg 7920d16fef4Smrgfallback: 7930d16fef4Smrg if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, pDst)) { 7940d16fef4Smrg if (radeon_glamor_picture_prepare_access_cpu_ro(scrn, pSrc)) { 7950d16fef4Smrg if (!pMask || 7960d16fef4Smrg radeon_glamor_picture_prepare_access_cpu_ro(scrn, pMask)) { 7970d16fef4Smrg fbComposite(op, pSrc, pMask, pDst, 7980d16fef4Smrg xSrc, ySrc, 7990d16fef4Smrg xMask, yMask, 8000d16fef4Smrg xDst, yDst, 8010d16fef4Smrg width, height); 8020d16fef4Smrg if (pMask) 8030d16fef4Smrg radeon_glamor_picture_finish_access_cpu(pMask); 8040d16fef4Smrg } 8050d16fef4Smrg radeon_glamor_picture_finish_access_cpu(pSrc); 8060d16fef4Smrg } 8070d16fef4Smrg radeon_glamor_picture_finish_access_cpu(pDst); 8080d16fef4Smrg } 8090d16fef4Smrg} 8100d16fef4Smrg 8110d16fef4Smrgstatic void 8120d16fef4Smrgradeon_glamor_add_traps(PicturePtr pPicture, 8130d16fef4Smrg INT16 x_off, INT16 y_off, int ntrap, xTrap *traps) 8140d16fef4Smrg{ 8150d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(pPicture->pDrawable->pScreen); 8160d16fef4Smrg 8170d16fef4Smrg if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, pPicture)) { 8180d16fef4Smrg fbAddTraps(pPicture, x_off, y_off, ntrap, traps); 8190d16fef4Smrg radeon_glamor_picture_finish_access_cpu(pPicture); 8200d16fef4Smrg } 8210d16fef4Smrg} 8220d16fef4Smrg 8230d16fef4Smrgstatic void 8240d16fef4Smrgradeon_glamor_glyphs(CARD8 op, 8250d16fef4Smrg PicturePtr src, 8260d16fef4Smrg PicturePtr dst, 8270d16fef4Smrg PictFormatPtr maskFormat, 8280d16fef4Smrg INT16 xSrc, 8290d16fef4Smrg INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs) 8300d16fef4Smrg{ 8310d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(dst->pDrawable->pScreen); 8320d16fef4Smrg 8330d16fef4Smrg if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, dst)) { 8340d16fef4Smrg if (radeon_glamor_picture_prepare_access_cpu_ro(scrn, src)) { 8350d16fef4Smrg RADEONInfoPtr info = RADEONPTR(scrn); 8360d16fef4Smrg 8370d16fef4Smrg info->glamor.SavedGlyphs(op, src, dst, maskFormat, xSrc, 8380d16fef4Smrg ySrc, nlist, list, glyphs); 8390d16fef4Smrg radeon_glamor_picture_finish_access_cpu(src); 8400d16fef4Smrg } 8410d16fef4Smrg radeon_glamor_picture_finish_access_cpu(dst); 8420d16fef4Smrg } 8430d16fef4Smrg} 8440d16fef4Smrg 8450d16fef4Smrgstatic void 8460d16fef4Smrgradeon_glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, 8470d16fef4Smrg PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, 8480d16fef4Smrg int ntrap, xTrapezoid *traps) 8490d16fef4Smrg{ 8500d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(dst->pDrawable->pScreen); 8510d16fef4Smrg 8520d16fef4Smrg if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, dst)) { 8530d16fef4Smrg if (radeon_glamor_picture_prepare_access_cpu_ro(scrn, src)) { 8540d16fef4Smrg RADEONInfoPtr info = RADEONPTR(scrn); 8550d16fef4Smrg 8560d16fef4Smrg info->glamor.SavedTrapezoids(op, src, dst, maskFormat, 8570d16fef4Smrg xSrc, ySrc, ntrap, traps); 8580d16fef4Smrg radeon_glamor_picture_finish_access_cpu(src); 8590d16fef4Smrg } 8600d16fef4Smrg radeon_glamor_picture_finish_access_cpu(dst); 8610d16fef4Smrg } 8620d16fef4Smrg} 8630d16fef4Smrg 8640d16fef4Smrgstatic void 8650d16fef4Smrgradeon_glamor_triangles(CARD8 op, PicturePtr src, PicturePtr dst, 8660d16fef4Smrg PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, 8670d16fef4Smrg int ntri, xTriangle *tri) 8680d16fef4Smrg{ 8690d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(dst->pDrawable->pScreen); 8700d16fef4Smrg 8710d16fef4Smrg if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, dst)) { 8720d16fef4Smrg if (radeon_glamor_picture_prepare_access_cpu_ro(scrn, src)) { 8730d16fef4Smrg RADEONInfoPtr info = RADEONPTR(scrn); 8740d16fef4Smrg 8750d16fef4Smrg info->glamor.SavedTriangles(op, src, dst, maskFormat, 8760d16fef4Smrg xSrc, ySrc, ntri, tri); 8770d16fef4Smrg radeon_glamor_picture_finish_access_cpu(src); 8780d16fef4Smrg } 8790d16fef4Smrg radeon_glamor_picture_finish_access_cpu(dst); 8800d16fef4Smrg } 8810d16fef4Smrg} 8820d16fef4Smrg 8830d16fef4Smrg#endif /* RENDER */ 8840d16fef4Smrg 8850d16fef4Smrg 8860d16fef4Smrg/** 8870d16fef4Smrg * radeon_glamor_close_screen() unwraps its wrapped screen functions and tears 8880d16fef4Smrg * down our screen private, before calling down to the next CloseScreen. 8890d16fef4Smrg */ 8900d16fef4Smrgstatic Bool 8918bf5c682Smrgradeon_glamor_close_screen(ScreenPtr pScreen) 8920d16fef4Smrg{ 8930d16fef4Smrg RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pScreen)); 8940d16fef4Smrg#ifdef RENDER 8950d16fef4Smrg PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); 8960d16fef4Smrg#endif 8970d16fef4Smrg 8980d16fef4Smrg pScreen->CreateGC = info->glamor.SavedCreateGC; 8990d16fef4Smrg pScreen->CloseScreen = info->glamor.SavedCloseScreen; 9000d16fef4Smrg pScreen->GetImage = info->glamor.SavedGetImage; 9010d16fef4Smrg pScreen->GetSpans = info->glamor.SavedGetSpans; 9020d16fef4Smrg pScreen->CopyWindow = info->glamor.SavedCopyWindow; 9030d16fef4Smrg pScreen->ChangeWindowAttributes = 9040d16fef4Smrg info->glamor.SavedChangeWindowAttributes; 9050d16fef4Smrg pScreen->BitmapToRegion = info->glamor.SavedBitmapToRegion; 9060d16fef4Smrg#ifdef RENDER 9070d16fef4Smrg if (ps) { 9080d16fef4Smrg ps->Composite = info->glamor.SavedComposite; 9090d16fef4Smrg ps->Glyphs = info->glamor.SavedGlyphs; 9100d16fef4Smrg ps->UnrealizeGlyph = info->glamor.SavedUnrealizeGlyph; 9110d16fef4Smrg ps->Trapezoids = info->glamor.SavedTrapezoids; 9120d16fef4Smrg ps->AddTraps = info->glamor.SavedAddTraps; 9130d16fef4Smrg ps->Triangles = info->glamor.SavedTriangles; 9140d16fef4Smrg 9150d16fef4Smrg ps->UnrealizeGlyph = info->glamor.SavedUnrealizeGlyph; 9160d16fef4Smrg } 9170d16fef4Smrg#endif 9180d16fef4Smrg 9198bf5c682Smrg return pScreen->CloseScreen(pScreen); 9200d16fef4Smrg} 9210d16fef4Smrg 9220d16fef4Smrg/** 9230d16fef4Smrg * @param screen screen being initialized 9240d16fef4Smrg */ 9250d16fef4Smrgvoid 9260d16fef4Smrgradeon_glamor_screen_init(ScreenPtr screen) 9270d16fef4Smrg{ 9280d16fef4Smrg RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen)); 9290d16fef4Smrg 9300d16fef4Smrg /* 9310d16fef4Smrg * Replace various fb screen functions 9320d16fef4Smrg */ 9330d16fef4Smrg info->glamor.SavedCloseScreen = screen->CloseScreen; 9340d16fef4Smrg screen->CloseScreen = radeon_glamor_close_screen; 9350d16fef4Smrg 9360d16fef4Smrg info->glamor.SavedCreateGC = screen->CreateGC; 9370d16fef4Smrg screen->CreateGC = radeon_glamor_create_gc; 9380d16fef4Smrg 9390d16fef4Smrg info->glamor.SavedGetImage = screen->GetImage; 9400d16fef4Smrg screen->GetImage = radeon_glamor_get_image; 9410d16fef4Smrg 9420d16fef4Smrg info->glamor.SavedGetSpans = screen->GetSpans; 9430d16fef4Smrg screen->GetSpans = radeon_glamor_get_spans; 9440d16fef4Smrg 9450d16fef4Smrg info->glamor.SavedCopyWindow = screen->CopyWindow; 9460d16fef4Smrg screen->CopyWindow = radeon_glamor_copy_window; 9470d16fef4Smrg 9480d16fef4Smrg info->glamor.SavedBitmapToRegion = screen->BitmapToRegion; 9490d16fef4Smrg screen->BitmapToRegion = radeon_glamor_bitmap_to_region; 9500d16fef4Smrg 9510d16fef4Smrg#ifdef RENDER 9520d16fef4Smrg { 9530d16fef4Smrg PictureScreenPtr ps = GetPictureScreenIfSet(screen); 9540d16fef4Smrg if (ps) { 9550d16fef4Smrg info->glamor.SavedComposite = ps->Composite; 9560d16fef4Smrg ps->Composite = radeon_glamor_composite; 9570d16fef4Smrg 9580d16fef4Smrg info->glamor.SavedUnrealizeGlyph = ps->UnrealizeGlyph; 9590d16fef4Smrg 9600d16fef4Smrg ps->Glyphs = radeon_glamor_glyphs; 9610d16fef4Smrg ps->Triangles = radeon_glamor_triangles; 9620d16fef4Smrg ps->Trapezoids = radeon_glamor_trapezoids; 9630d16fef4Smrg 9640d16fef4Smrg info->glamor.SavedAddTraps = ps->AddTraps; 9650d16fef4Smrg ps->AddTraps = radeon_glamor_add_traps; 9660d16fef4Smrg } 9670d16fef4Smrg } 9680d16fef4Smrg#endif 9690d16fef4Smrg} 9700d16fef4Smrg 9710d16fef4Smrg#endif /* USE_GLAMOR */ 972