1d6c0b56eSmrg/* 2d6c0b56eSmrg * Copyright © 2001 Keith Packard 3d6c0b56eSmrg * 2010 Intel Corporation 4d6c0b56eSmrg * 2012,2015 Advanced Micro Devices, Inc. 5d6c0b56eSmrg * 6d6c0b56eSmrg * Partly based on code Copyright © 2008 Red Hat, Inc. 7d6c0b56eSmrg * Partly based on code Copyright © 2000 SuSE, Inc. 8d6c0b56eSmrg * 9d6c0b56eSmrg * Partly based on code that is Copyright © The XFree86 Project Inc. 10d6c0b56eSmrg * 11d6c0b56eSmrg * Permission to use, copy, modify, distribute, and sell this software and its 12d6c0b56eSmrg * documentation for any purpose is hereby granted without fee, provided that 13d6c0b56eSmrg * the above copyright notice appear in all copies and that both that 14d6c0b56eSmrg * copyright notice and this permission notice appear in supporting 15d6c0b56eSmrg * documentation, and that the name of the opyright holders not be used in 16d6c0b56eSmrg * advertising or publicity pertaining to distribution of the software without 17d6c0b56eSmrg * specific, written prior permission. The copyright holders make no 18d6c0b56eSmrg * representations about the suitability of this software for any purpose. It 19d6c0b56eSmrg * is provided "as is" without express or implied warranty. 20d6c0b56eSmrg * 21d6c0b56eSmrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 22d6c0b56eSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 23d6c0b56eSmrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 24d6c0b56eSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 25d6c0b56eSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 26d6c0b56eSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 27d6c0b56eSmrg * PERFORMANCE OF THIS SOFTWARE. 28d6c0b56eSmrg */ 29d6c0b56eSmrg 30d6c0b56eSmrg 31d6c0b56eSmrg#ifdef HAVE_CONFIG_H 32d6c0b56eSmrg#include <config.h> 33d6c0b56eSmrg#endif 34d6c0b56eSmrg 35d6c0b56eSmrg#ifdef USE_GLAMOR 36d6c0b56eSmrg 37d6c0b56eSmrg#include "amdgpu_drv.h" 38d6c0b56eSmrg#include "amdgpu_glamor.h" 39d6c0b56eSmrg#include "amdgpu_pixmap.h" 40d6c0b56eSmrg 41d6c0b56eSmrg 42d6c0b56eSmrg/* Are there any outstanding GPU operations for this pixmap? */ 43d6c0b56eSmrgstatic Bool 44d6c0b56eSmrgamdgpu_glamor_gpu_pending(uint_fast32_t gpu_synced, uint_fast32_t gpu_access) 45d6c0b56eSmrg{ 46d6c0b56eSmrg return (int_fast32_t)(gpu_access - gpu_synced) > 0; 47d6c0b56eSmrg} 48d6c0b56eSmrg 49d6c0b56eSmrg/* 50d6c0b56eSmrg * Pixmap CPU access wrappers 51d6c0b56eSmrg */ 52d6c0b56eSmrg 53d6c0b56eSmrgstatic Bool 54d6c0b56eSmrgamdgpu_glamor_prepare_access_cpu(ScrnInfoPtr scrn, AMDGPUInfoPtr info, 55d6c0b56eSmrg PixmapPtr pixmap, struct amdgpu_pixmap *priv, 56d6c0b56eSmrg Bool need_sync) 57d6c0b56eSmrg{ 58d6c0b56eSmrg struct amdgpu_buffer *bo = priv->bo; 59d6c0b56eSmrg int ret; 60d6c0b56eSmrg 61d6c0b56eSmrg /* When falling back to swrast, flush all pending operations */ 62d6c0b56eSmrg if (need_sync) 63d6c0b56eSmrg amdgpu_glamor_flush(scrn); 64d6c0b56eSmrg 65d6c0b56eSmrg if (!pixmap->devPrivate.ptr) { 66d6c0b56eSmrg ret = amdgpu_bo_map(scrn, bo); 67d6c0b56eSmrg if (ret) { 68d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_WARNING, 69d6c0b56eSmrg "%s: bo map failed: %s\n", __FUNCTION__, 70d6c0b56eSmrg strerror(-ret)); 71d6c0b56eSmrg return FALSE; 72d6c0b56eSmrg } 73d6c0b56eSmrg 74d6c0b56eSmrg pixmap->devPrivate.ptr = bo->cpu_ptr; 75d6c0b56eSmrg info->gpu_synced = info->gpu_flushed; 76d6c0b56eSmrg } else if (need_sync) { 77d6c0b56eSmrg char pixel[4]; 78d6c0b56eSmrg 79d6c0b56eSmrg info->glamor.SavedGetImage(&pixmap->drawable, 0, 0, 1, 1, 80d6c0b56eSmrg ZPixmap, ~0, pixel); 81d6c0b56eSmrg info->gpu_synced = info->gpu_flushed; 82d6c0b56eSmrg } 83d6c0b56eSmrg 84d6c0b56eSmrg return TRUE; 85d6c0b56eSmrg} 86d6c0b56eSmrg 87d6c0b56eSmrgstatic Bool 88d6c0b56eSmrgamdgpu_glamor_prepare_access_cpu_ro(ScrnInfoPtr scrn, PixmapPtr pixmap, 89d6c0b56eSmrg struct amdgpu_pixmap *priv) 90d6c0b56eSmrg{ 91d6c0b56eSmrg AMDGPUInfoPtr info; 92d6c0b56eSmrg Bool need_sync; 93d6c0b56eSmrg 94d6c0b56eSmrg if (!priv) 95d6c0b56eSmrg return TRUE; 96d6c0b56eSmrg 97d6c0b56eSmrg info = AMDGPUPTR(scrn); 98d6c0b56eSmrg need_sync = amdgpu_glamor_gpu_pending(info->gpu_synced, priv->gpu_write); 99d6c0b56eSmrg return amdgpu_glamor_prepare_access_cpu(scrn, AMDGPUPTR(scrn), pixmap, 100d6c0b56eSmrg priv, need_sync); 101d6c0b56eSmrg} 102d6c0b56eSmrg 103d6c0b56eSmrgstatic Bool 104d6c0b56eSmrgamdgpu_glamor_prepare_access_cpu_rw(ScrnInfoPtr scrn, PixmapPtr pixmap, 105d6c0b56eSmrg struct amdgpu_pixmap *priv) 106d6c0b56eSmrg{ 107d6c0b56eSmrg AMDGPUInfoPtr info; 108d6c0b56eSmrg uint_fast32_t gpu_synced; 109d6c0b56eSmrg Bool need_sync; 110d6c0b56eSmrg 111d6c0b56eSmrg if (!priv) 112d6c0b56eSmrg return TRUE; 113d6c0b56eSmrg 114d6c0b56eSmrg info = AMDGPUPTR(scrn); 115d6c0b56eSmrg gpu_synced = info->gpu_synced; 116d6c0b56eSmrg need_sync = amdgpu_glamor_gpu_pending(gpu_synced, priv->gpu_write) | 117d6c0b56eSmrg amdgpu_glamor_gpu_pending(gpu_synced, priv->gpu_read); 118d6c0b56eSmrg return amdgpu_glamor_prepare_access_cpu(scrn, info, pixmap, priv, 119d6c0b56eSmrg need_sync); 120d6c0b56eSmrg} 121d6c0b56eSmrg 122d6c0b56eSmrgstatic void 123d6c0b56eSmrgamdgpu_glamor_finish_access_cpu(PixmapPtr pixmap) 124d6c0b56eSmrg{ 125d6c0b56eSmrg /* Nothing to do */ 126d6c0b56eSmrg} 127d6c0b56eSmrg 128d6c0b56eSmrg/* 129d6c0b56eSmrg * Pixmap GPU access wrappers 130d6c0b56eSmrg */ 131d6c0b56eSmrg 132d6c0b56eSmrgstatic Bool 133d6c0b56eSmrgamdgpu_glamor_use_gpu(PixmapPtr pixmap, struct amdgpu_pixmap *priv) 134d6c0b56eSmrg{ 135d6c0b56eSmrg return (pixmap->usage_hint & 136d6c0b56eSmrg (AMDGPU_CREATE_PIXMAP_SCANOUT | AMDGPU_CREATE_PIXMAP_DRI2)) != 0 || 137d6c0b56eSmrg (priv && !priv->bo); 138d6c0b56eSmrg} 139d6c0b56eSmrg 140d6c0b56eSmrgstatic Bool 141d6c0b56eSmrgamdgpu_glamor_prepare_access_gpu(struct amdgpu_pixmap *priv) 142d6c0b56eSmrg{ 143d6c0b56eSmrg return priv != NULL; 144d6c0b56eSmrg} 145d6c0b56eSmrg 146d6c0b56eSmrgstatic void 147d6c0b56eSmrgamdgpu_glamor_finish_access_gpu_ro(AMDGPUInfoPtr info, 148d6c0b56eSmrg struct amdgpu_pixmap *priv) 149d6c0b56eSmrg{ 150d6c0b56eSmrg priv->gpu_read = info->gpu_flushed + 1; 151d6c0b56eSmrg} 152d6c0b56eSmrg 153d6c0b56eSmrgstatic void 154d6c0b56eSmrgamdgpu_glamor_finish_access_gpu_rw(AMDGPUInfoPtr info, 155d6c0b56eSmrg struct amdgpu_pixmap *priv) 156d6c0b56eSmrg{ 157d6c0b56eSmrg priv->gpu_write = priv->gpu_read = info->gpu_flushed + 1; 158d6c0b56eSmrg} 159d6c0b56eSmrg 160d6c0b56eSmrg/* 161d6c0b56eSmrg * GC CPU access wrappers 162d6c0b56eSmrg */ 163d6c0b56eSmrg 164d6c0b56eSmrgstatic Bool 165d6c0b56eSmrgamdgpu_glamor_prepare_access_gc(ScrnInfoPtr scrn, GCPtr pGC) 166d6c0b56eSmrg{ 167d6c0b56eSmrg struct amdgpu_pixmap *priv; 168d6c0b56eSmrg 169d6c0b56eSmrg if (pGC->stipple) { 170d6c0b56eSmrg priv = amdgpu_get_pixmap_private(pGC->stipple); 171d6c0b56eSmrg if (!amdgpu_glamor_prepare_access_cpu_ro(scrn, pGC->stipple, priv)) 172d6c0b56eSmrg return FALSE; 173d6c0b56eSmrg } 174d6c0b56eSmrg if (pGC->fillStyle == FillTiled) { 175d6c0b56eSmrg priv = amdgpu_get_pixmap_private(pGC->tile.pixmap); 176d6c0b56eSmrg if (!amdgpu_glamor_prepare_access_cpu_ro(scrn, pGC->tile.pixmap, 177d6c0b56eSmrg priv)) { 178d6c0b56eSmrg if (pGC->stipple) 179d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pGC->stipple); 180d6c0b56eSmrg return FALSE; 181d6c0b56eSmrg } 182d6c0b56eSmrg } 183d6c0b56eSmrg return TRUE; 184d6c0b56eSmrg} 185d6c0b56eSmrg 186d6c0b56eSmrgstatic void 187d6c0b56eSmrgamdgpu_glamor_finish_access_gc(GCPtr pGC) 188d6c0b56eSmrg{ 189d6c0b56eSmrg if (pGC->fillStyle == FillTiled) 190d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pGC->tile.pixmap); 191d6c0b56eSmrg if (pGC->stipple) 192d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pGC->stipple); 193d6c0b56eSmrg} 194d6c0b56eSmrg 195d6c0b56eSmrg/* 196d6c0b56eSmrg * Picture CPU access wrappers 197d6c0b56eSmrg */ 198d6c0b56eSmrg 199d6c0b56eSmrgstatic void 200d6c0b56eSmrgamdgpu_glamor_picture_finish_access_cpu(PicturePtr picture) 201d6c0b56eSmrg{ 202d6c0b56eSmrg /* Nothing to do */ 203d6c0b56eSmrg} 204d6c0b56eSmrg 205d6c0b56eSmrgstatic Bool 206d6c0b56eSmrgamdgpu_glamor_picture_prepare_access_cpu_ro(ScrnInfoPtr scrn, 207d6c0b56eSmrg PicturePtr picture) 208d6c0b56eSmrg{ 209d6c0b56eSmrg PixmapPtr pixmap; 210d6c0b56eSmrg struct amdgpu_pixmap *priv; 211d6c0b56eSmrg 21235d5b7c7Smrg if (!picture->pDrawable) 213d6c0b56eSmrg return TRUE; 214d6c0b56eSmrg 215d6c0b56eSmrg pixmap = get_drawable_pixmap(picture->pDrawable); 216d6c0b56eSmrg priv = amdgpu_get_pixmap_private(pixmap); 217d6c0b56eSmrg if (!amdgpu_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) 218d6c0b56eSmrg return FALSE; 219d6c0b56eSmrg 220d6c0b56eSmrg if (picture->alphaMap) { 221d6c0b56eSmrg pixmap = get_drawable_pixmap(picture->alphaMap->pDrawable); 222d6c0b56eSmrg priv = amdgpu_get_pixmap_private(pixmap); 223d6c0b56eSmrg if (!amdgpu_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) { 224d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(picture); 225d6c0b56eSmrg return FALSE; 226d6c0b56eSmrg } 227d6c0b56eSmrg } 228d6c0b56eSmrg 229d6c0b56eSmrg return TRUE; 230d6c0b56eSmrg} 231d6c0b56eSmrg 232d6c0b56eSmrgstatic Bool 233d6c0b56eSmrgamdgpu_glamor_picture_prepare_access_cpu_rw(ScrnInfoPtr scrn, 234d6c0b56eSmrg PicturePtr picture) 235d6c0b56eSmrg{ 236d6c0b56eSmrg PixmapPtr pixmap; 237d6c0b56eSmrg struct amdgpu_pixmap *priv; 238d6c0b56eSmrg 239d6c0b56eSmrg pixmap = get_drawable_pixmap(picture->pDrawable); 240d6c0b56eSmrg priv = amdgpu_get_pixmap_private(pixmap); 241d6c0b56eSmrg if (!amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) 242d6c0b56eSmrg return FALSE; 243d6c0b56eSmrg 244d6c0b56eSmrg if (picture->alphaMap) { 245d6c0b56eSmrg pixmap = get_drawable_pixmap(picture->alphaMap->pDrawable); 246d6c0b56eSmrg priv = amdgpu_get_pixmap_private(pixmap); 247d6c0b56eSmrg if (!amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 248d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(picture); 249d6c0b56eSmrg return FALSE; 250d6c0b56eSmrg } 251d6c0b56eSmrg } 252d6c0b56eSmrg 253d6c0b56eSmrg return TRUE; 254d6c0b56eSmrg} 255d6c0b56eSmrg 256d6c0b56eSmrg/* 257d6c0b56eSmrg * GC rendering wrappers 258d6c0b56eSmrg */ 259d6c0b56eSmrg 260d6c0b56eSmrgstatic void 261d6c0b56eSmrgamdgpu_glamor_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int nspans, 262d6c0b56eSmrg DDXPointPtr ppt, int *pwidth, int fSorted) 263d6c0b56eSmrg{ 264d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 265d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 266d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 267d6c0b56eSmrg 268d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 269d6c0b56eSmrg if (amdgpu_glamor_prepare_access_gc(scrn, pGC)) { 270d6c0b56eSmrg fbFillSpans(pDrawable, pGC, nspans, ppt, pwidth, 271d6c0b56eSmrg fSorted); 272d6c0b56eSmrg amdgpu_glamor_finish_access_gc(pGC); 273d6c0b56eSmrg } 274d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 275d6c0b56eSmrg } 276d6c0b56eSmrg} 277d6c0b56eSmrg 278d6c0b56eSmrgstatic void 279d6c0b56eSmrgamdgpu_glamor_set_spans(DrawablePtr pDrawable, GCPtr pGC, char *psrc, 280d6c0b56eSmrg DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) 281d6c0b56eSmrg{ 282d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 283d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 284d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 285d6c0b56eSmrg 286d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 287d6c0b56eSmrg fbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); 288d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 289d6c0b56eSmrg } 290d6c0b56eSmrg} 291d6c0b56eSmrg 292d6c0b56eSmrgstatic void 293d6c0b56eSmrgamdgpu_glamor_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, 294d6c0b56eSmrg int x, int y, int w, int h, int leftPad, int format, 295d6c0b56eSmrg char *bits) 296d6c0b56eSmrg{ 297d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 298d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 299d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 300d6c0b56eSmrg 301d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 302d6c0b56eSmrg fbPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, 303d6c0b56eSmrg bits); 304d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 305d6c0b56eSmrg } 306d6c0b56eSmrg} 307d6c0b56eSmrg 308d6c0b56eSmrgstatic RegionPtr 309d6c0b56eSmrgamdgpu_glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 310d6c0b56eSmrg int srcx, int srcy, int w, int h, int dstx, int dsty, 311d6c0b56eSmrg unsigned long bitPlane) 312d6c0b56eSmrg{ 313d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pScreen); 314d6c0b56eSmrg PixmapPtr dst_pix = get_drawable_pixmap(pDst); 315d6c0b56eSmrg struct amdgpu_pixmap *dst_priv = amdgpu_get_pixmap_private(dst_pix); 316d6c0b56eSmrg RegionPtr ret = NULL; 317d6c0b56eSmrg 318d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, dst_pix, dst_priv)) { 319d6c0b56eSmrg PixmapPtr src_pix = get_drawable_pixmap(pSrc); 320d6c0b56eSmrg struct amdgpu_pixmap *src_priv = amdgpu_get_pixmap_private(src_pix); 321d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_ro(scrn, src_pix, src_priv)) { 322d6c0b56eSmrg ret = 323d6c0b56eSmrg fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, 324d6c0b56eSmrg dsty, bitPlane); 325d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(src_pix); 326d6c0b56eSmrg } 327d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(dst_pix); 328d6c0b56eSmrg } 329d6c0b56eSmrg return ret; 330d6c0b56eSmrg} 331d6c0b56eSmrg 332d6c0b56eSmrgstatic RegionPtr 333d6c0b56eSmrgamdgpu_glamor_copy_plane_nodstbo(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 334d6c0b56eSmrg int srcx, int srcy, int w, int h, 335d6c0b56eSmrg int dstx, int dsty, unsigned long bitPlane) 336d6c0b56eSmrg{ 337d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pScreen); 338d6c0b56eSmrg PixmapPtr src_pix = get_drawable_pixmap(pSrc); 339d6c0b56eSmrg struct amdgpu_pixmap *src_priv = amdgpu_get_pixmap_private(src_pix); 340d6c0b56eSmrg RegionPtr ret = NULL; 341d6c0b56eSmrg 342d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_ro(scrn, src_pix, src_priv)) { 343d6c0b56eSmrg ret = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, 344d6c0b56eSmrg dstx, dsty, bitPlane); 345d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(src_pix); 346d6c0b56eSmrg } 347d6c0b56eSmrg return ret; 348d6c0b56eSmrg} 349d6c0b56eSmrg 350d6c0b56eSmrgstatic void 351d6c0b56eSmrgamdgpu_glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, 352d6c0b56eSmrg DDXPointPtr pptInit) 353d6c0b56eSmrg{ 354d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 355d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 356d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 357d6c0b56eSmrg 358d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 359d6c0b56eSmrg fbPolyPoint(pDrawable, pGC, mode, npt, pptInit); 360d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 361d6c0b56eSmrg } 362d6c0b56eSmrg} 363d6c0b56eSmrg 364d6c0b56eSmrgstatic void 365d6c0b56eSmrgamdgpu_glamor_poly_lines(DrawablePtr pDrawable, GCPtr pGC, 366d6c0b56eSmrg int mode, int npt, DDXPointPtr ppt) 367d6c0b56eSmrg{ 368d6c0b56eSmrg if (pGC->lineWidth == 0) { 369d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 370d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 371d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 372d6c0b56eSmrg 373d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 374d6c0b56eSmrg if (amdgpu_glamor_prepare_access_gc(scrn, pGC)) { 375d6c0b56eSmrg fbPolyLine(pDrawable, pGC, mode, npt, ppt); 376d6c0b56eSmrg amdgpu_glamor_finish_access_gc(pGC); 377d6c0b56eSmrg } 378d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 379d6c0b56eSmrg } 380d6c0b56eSmrg return; 381d6c0b56eSmrg } 382d6c0b56eSmrg /* fb calls mi functions in the lineWidth != 0 case. */ 383d6c0b56eSmrg fbPolyLine(pDrawable, pGC, mode, npt, ppt); 384d6c0b56eSmrg} 385d6c0b56eSmrg 386d6c0b56eSmrgstatic void 387d6c0b56eSmrgamdgpu_glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, 388d6c0b56eSmrg int nsegInit, xSegment *pSegInit) 389d6c0b56eSmrg{ 390d6c0b56eSmrg if (pGC->lineWidth == 0) { 391d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 392d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 393d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 394d6c0b56eSmrg 395d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 396d6c0b56eSmrg if (amdgpu_glamor_prepare_access_gc(scrn, pGC)) { 397d6c0b56eSmrg fbPolySegment(pDrawable, pGC, nsegInit, 398d6c0b56eSmrg pSegInit); 399d6c0b56eSmrg amdgpu_glamor_finish_access_gc(pGC); 400d6c0b56eSmrg } 401d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 402d6c0b56eSmrg } 403d6c0b56eSmrg return; 404d6c0b56eSmrg } 405d6c0b56eSmrg /* fb calls mi functions in the lineWidth != 0 case. */ 406d6c0b56eSmrg fbPolySegment(pDrawable, pGC, nsegInit, pSegInit); 407d6c0b56eSmrg} 408d6c0b56eSmrg 409d6c0b56eSmrgstatic void 410d6c0b56eSmrgamdgpu_glamor_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC, 411d6c0b56eSmrg int nrect, xRectangle *prect) 412d6c0b56eSmrg{ 413d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 414d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 415d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 416d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 417d6c0b56eSmrg 418d6c0b56eSmrg if ((info->force_accel || amdgpu_glamor_use_gpu(pixmap, priv)) && 419d6c0b56eSmrg amdgpu_glamor_prepare_access_gpu(priv)) { 420d6c0b56eSmrg info->glamor.SavedPolyFillRect(pDrawable, pGC, nrect, prect); 421d6c0b56eSmrg amdgpu_glamor_finish_access_gpu_rw(info, priv); 422d6c0b56eSmrg return; 423d6c0b56eSmrg } 424d6c0b56eSmrg 425d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 426d6c0b56eSmrg if (amdgpu_glamor_prepare_access_gc(scrn, pGC)) { 427d6c0b56eSmrg fbPolyFillRect(pDrawable, pGC, nrect, prect); 428d6c0b56eSmrg amdgpu_glamor_finish_access_gc(pGC); 429d6c0b56eSmrg } 430d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 431d6c0b56eSmrg } 432d6c0b56eSmrg} 433d6c0b56eSmrg 434d6c0b56eSmrgstatic void 435d6c0b56eSmrgamdgpu_glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, 436d6c0b56eSmrg int x, int y, unsigned int nglyph, 437d6c0b56eSmrg CharInfoPtr *ppci, pointer pglyphBase) 438d6c0b56eSmrg{ 439d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 440d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 441d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 442d6c0b56eSmrg 443d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 444d6c0b56eSmrg if (amdgpu_glamor_prepare_access_gc(scrn, pGC)) { 445d6c0b56eSmrg fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, 446d6c0b56eSmrg pglyphBase); 447d6c0b56eSmrg amdgpu_glamor_finish_access_gc(pGC); 448d6c0b56eSmrg } 449d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 450d6c0b56eSmrg } 451d6c0b56eSmrg} 452d6c0b56eSmrg 453d6c0b56eSmrgstatic void 454d6c0b56eSmrgamdgpu_glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, 455d6c0b56eSmrg int x, int y, unsigned int nglyph, 456d6c0b56eSmrg CharInfoPtr *ppci, pointer pglyphBase) 457d6c0b56eSmrg{ 458d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 459d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 460d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 461d6c0b56eSmrg 462d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 463d6c0b56eSmrg if (amdgpu_glamor_prepare_access_gc(scrn, pGC)) { 464d6c0b56eSmrg fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, 465d6c0b56eSmrg pglyphBase); 466d6c0b56eSmrg amdgpu_glamor_finish_access_gc(pGC); 467d6c0b56eSmrg } 468d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 469d6c0b56eSmrg } 470d6c0b56eSmrg} 471d6c0b56eSmrg 472d6c0b56eSmrgstatic void 473d6c0b56eSmrgamdgpu_glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, 474d6c0b56eSmrg DrawablePtr pDrawable, int w, int h, int x, int y) 475d6c0b56eSmrg{ 476d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 477d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 478d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 479d6c0b56eSmrg 480d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 481d6c0b56eSmrg priv = amdgpu_get_pixmap_private(pBitmap); 482d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_ro(scrn, pBitmap, priv)) { 483d6c0b56eSmrg if (amdgpu_glamor_prepare_access_gc(scrn, pGC)) { 484d6c0b56eSmrg fbPushPixels(pGC, pBitmap, pDrawable, w, h, x, 485d6c0b56eSmrg y); 486d6c0b56eSmrg amdgpu_glamor_finish_access_gc(pGC); 487d6c0b56eSmrg } 488d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pBitmap); 489d6c0b56eSmrg } 490d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 491d6c0b56eSmrg } 492d6c0b56eSmrg} 493d6c0b56eSmrg 494d6c0b56eSmrgstatic void 495d6c0b56eSmrgamdgpu_glamor_push_pixels_nodstbo(GCPtr pGC, PixmapPtr pBitmap, 496d6c0b56eSmrg DrawablePtr pDrawable, int w, int h, 497d6c0b56eSmrg int x, int y) 498d6c0b56eSmrg{ 499d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 500d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pBitmap); 501d6c0b56eSmrg 502d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_ro(scrn, pBitmap, priv)) { 503d6c0b56eSmrg fbPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); 504d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pBitmap); 505d6c0b56eSmrg } 506d6c0b56eSmrg} 507d6c0b56eSmrg 508d6c0b56eSmrgstatic RegionPtr 509d6c0b56eSmrgamdgpu_glamor_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, 510d6c0b56eSmrg GCPtr pGC, int srcx, int srcy, int width, int height, 511d6c0b56eSmrg int dstx, int dsty) 512d6c0b56eSmrg{ 513d6c0b56eSmrg ScreenPtr screen = pDstDrawable->pScreen; 514d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 515d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 516d6c0b56eSmrg PixmapPtr src_pixmap = get_drawable_pixmap(pSrcDrawable); 517d6c0b56eSmrg PixmapPtr dst_pixmap = get_drawable_pixmap(pDstDrawable); 518d6c0b56eSmrg struct amdgpu_pixmap *src_priv = amdgpu_get_pixmap_private(src_pixmap); 519d6c0b56eSmrg struct amdgpu_pixmap *dst_priv = amdgpu_get_pixmap_private(dst_pixmap); 520d6c0b56eSmrg RegionPtr ret = NULL; 521d6c0b56eSmrg 522d6c0b56eSmrg if (amdgpu_glamor_use_gpu(dst_pixmap, dst_priv) || 523d6c0b56eSmrg amdgpu_glamor_use_gpu(src_pixmap, src_priv)) { 524d6c0b56eSmrg if (!amdgpu_glamor_prepare_access_gpu(dst_priv)) 525d6c0b56eSmrg goto fallback; 526d6c0b56eSmrg if (src_priv != dst_priv && 527d6c0b56eSmrg !amdgpu_glamor_prepare_access_gpu(src_priv)) 528d6c0b56eSmrg goto fallback; 529d6c0b56eSmrg 530d6c0b56eSmrg ret = info->glamor.SavedCopyArea(pSrcDrawable, pDstDrawable, 531d6c0b56eSmrg pGC, srcx, srcy, 532d6c0b56eSmrg width, height, dstx, dsty); 533d6c0b56eSmrg amdgpu_glamor_finish_access_gpu_rw(info, dst_priv); 534d6c0b56eSmrg if (src_priv != dst_priv) 535d6c0b56eSmrg amdgpu_glamor_finish_access_gpu_ro(info, src_priv); 536d6c0b56eSmrg 537d6c0b56eSmrg return ret; 538d6c0b56eSmrg } 539d6c0b56eSmrg 540d6c0b56eSmrgfallback: 541d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, dst_pixmap, dst_priv)) { 542d6c0b56eSmrg if (pSrcDrawable == pDstDrawable || 543d6c0b56eSmrg amdgpu_glamor_prepare_access_cpu_ro(scrn, src_pixmap, 544d6c0b56eSmrg src_priv)) { 545d6c0b56eSmrg ret = fbCopyArea(pSrcDrawable, pDstDrawable, pGC, 546d6c0b56eSmrg srcx, srcy, width, height, dstx, dsty); 547d6c0b56eSmrg if (pSrcDrawable != pDstDrawable) 548d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(src_pixmap); 549d6c0b56eSmrg } 550d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(dst_pixmap); 551d6c0b56eSmrg } 552d6c0b56eSmrg 553d6c0b56eSmrg return ret; 554d6c0b56eSmrg} 555d6c0b56eSmrg 556d6c0b56eSmrgstatic RegionPtr 557d6c0b56eSmrgamdgpu_glamor_copy_area_nodstbo(DrawablePtr pSrcDrawable, 558d6c0b56eSmrg DrawablePtr pDstDrawable, GCPtr pGC, 559d6c0b56eSmrg int srcx, int srcy, int width, int height, 560d6c0b56eSmrg int dstx, int dsty) 561d6c0b56eSmrg{ 562d6c0b56eSmrg ScreenPtr screen = pDstDrawable->pScreen; 563d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 564d6c0b56eSmrg PixmapPtr src_pixmap = get_drawable_pixmap(pSrcDrawable); 565d6c0b56eSmrg PixmapPtr dst_pixmap = get_drawable_pixmap(pDstDrawable); 566d6c0b56eSmrg struct amdgpu_pixmap *src_priv; 567d6c0b56eSmrg RegionPtr ret = NULL; 568d6c0b56eSmrg 569d6c0b56eSmrg if (src_pixmap != dst_pixmap) { 570d6c0b56eSmrg src_priv = amdgpu_get_pixmap_private(src_pixmap); 571d6c0b56eSmrg 572d6c0b56eSmrg if (!amdgpu_glamor_prepare_access_cpu_ro(scrn, src_pixmap, 573d6c0b56eSmrg src_priv)) 574d6c0b56eSmrg return ret; 575d6c0b56eSmrg } 576d6c0b56eSmrg 577d6c0b56eSmrg ret = fbCopyArea(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, 578d6c0b56eSmrg width, height, dstx, dsty); 579d6c0b56eSmrg 580d6c0b56eSmrg if (src_pixmap != dst_pixmap) 581d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(src_pixmap); 582d6c0b56eSmrg 583d6c0b56eSmrg return ret; 584d6c0b56eSmrg} 585d6c0b56eSmrg 586d6c0b56eSmrgstatic const GCOps amdgpu_glamor_ops = { 587d6c0b56eSmrg amdgpu_glamor_fill_spans, 588d6c0b56eSmrg amdgpu_glamor_set_spans, 589d6c0b56eSmrg amdgpu_glamor_put_image, 590d6c0b56eSmrg amdgpu_glamor_copy_area, 591d6c0b56eSmrg amdgpu_glamor_copy_plane, 592d6c0b56eSmrg amdgpu_glamor_poly_point, 593d6c0b56eSmrg amdgpu_glamor_poly_lines, 594d6c0b56eSmrg amdgpu_glamor_poly_segment, 595d6c0b56eSmrg miPolyRectangle, 596d6c0b56eSmrg miPolyArc, 597d6c0b56eSmrg miFillPolygon, 598d6c0b56eSmrg amdgpu_glamor_poly_fill_rect, 599d6c0b56eSmrg miPolyFillArc, 600d6c0b56eSmrg miPolyText8, 601d6c0b56eSmrg miPolyText16, 602d6c0b56eSmrg miImageText8, 603d6c0b56eSmrg miImageText16, 604d6c0b56eSmrg amdgpu_glamor_image_glyph_blt, 605d6c0b56eSmrg amdgpu_glamor_poly_glyph_blt, 606d6c0b56eSmrg amdgpu_glamor_push_pixels, 607d6c0b56eSmrg}; 608d6c0b56eSmrg 609d6c0b56eSmrgstatic GCOps amdgpu_glamor_nodstbo_ops; 610d6c0b56eSmrg 611d6c0b56eSmrg/** 612d6c0b56eSmrg * amdgpu_glamor_validate_gc() sets the ops to our implementations, which may be 613d6c0b56eSmrg * accelerated or may sync the card and fall back to fb. 614d6c0b56eSmrg */ 615d6c0b56eSmrgstatic void 616d6c0b56eSmrgamdgpu_glamor_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 617d6c0b56eSmrg{ 618d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pGC->pScreen); 619d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 620d6c0b56eSmrg 621d6c0b56eSmrg glamor_validate_gc(pGC, changes, pDrawable); 622d6c0b56eSmrg info->glamor.SavedCopyArea = pGC->ops->CopyArea; 623d6c0b56eSmrg info->glamor.SavedPolyFillRect = pGC->ops->PolyFillRect; 624d6c0b56eSmrg 625d6c0b56eSmrg if (amdgpu_get_pixmap_private(get_drawable_pixmap(pDrawable)) || 626d6c0b56eSmrg (pGC->stipple && amdgpu_get_pixmap_private(pGC->stipple)) || 627d6c0b56eSmrg (pGC->fillStyle == FillTiled && 628d6c0b56eSmrg amdgpu_get_pixmap_private(pGC->tile.pixmap))) 629d6c0b56eSmrg pGC->ops = (GCOps *)&amdgpu_glamor_ops; 630d6c0b56eSmrg else 631d6c0b56eSmrg pGC->ops = &amdgpu_glamor_nodstbo_ops; 632d6c0b56eSmrg} 633d6c0b56eSmrg 634d6c0b56eSmrgstatic GCFuncs glamorGCFuncs = { 635d6c0b56eSmrg amdgpu_glamor_validate_gc, 636d6c0b56eSmrg miChangeGC, 637d6c0b56eSmrg miCopyGC, 638d6c0b56eSmrg miDestroyGC, 639d6c0b56eSmrg miChangeClip, 640d6c0b56eSmrg miDestroyClip, 641d6c0b56eSmrg miCopyClip 642d6c0b56eSmrg}; 643d6c0b56eSmrg 644d6c0b56eSmrg/** 645d6c0b56eSmrg * amdgpu_glamor_create_gc makes a new GC and hooks up its funcs handler, so that 646d6c0b56eSmrg * amdgpu_glamor_validate_gc() will get called. 647d6c0b56eSmrg */ 648d6c0b56eSmrgstatic int 649d6c0b56eSmrgamdgpu_glamor_create_gc(GCPtr pGC) 650d6c0b56eSmrg{ 651d6c0b56eSmrg static Bool nodstbo_ops_initialized; 652d6c0b56eSmrg 653d6c0b56eSmrg if (!fbCreateGC(pGC)) 654d6c0b56eSmrg return FALSE; 655d6c0b56eSmrg 656d6c0b56eSmrg if (!nodstbo_ops_initialized) { 657d6c0b56eSmrg amdgpu_glamor_nodstbo_ops = amdgpu_glamor_ops; 658d6c0b56eSmrg 659d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.FillSpans = pGC->ops->FillSpans; 660d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.SetSpans = pGC->ops->SetSpans; 661d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.PutImage = pGC->ops->PutImage; 662d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.CopyArea = amdgpu_glamor_copy_area_nodstbo; 663d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.CopyPlane = amdgpu_glamor_copy_plane_nodstbo; 664d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.PolyPoint = pGC->ops->PolyPoint; 665d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.Polylines = pGC->ops->Polylines; 666d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.PolySegment = pGC->ops->PolySegment; 667d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.PolyFillRect = pGC->ops->PolyFillRect; 668d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.ImageGlyphBlt = pGC->ops->ImageGlyphBlt; 669d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.PolyGlyphBlt = pGC->ops->PolyGlyphBlt; 670d6c0b56eSmrg amdgpu_glamor_nodstbo_ops.PushPixels = amdgpu_glamor_push_pixels_nodstbo; 671d6c0b56eSmrg 672d6c0b56eSmrg nodstbo_ops_initialized = TRUE; 673d6c0b56eSmrg } 674d6c0b56eSmrg 675d6c0b56eSmrg pGC->funcs = &glamorGCFuncs; 676d6c0b56eSmrg 677d6c0b56eSmrg return TRUE; 678d6c0b56eSmrg} 679d6c0b56eSmrg 680d6c0b56eSmrg/* 681d6c0b56eSmrg * Screen rendering wrappers 682d6c0b56eSmrg */ 683d6c0b56eSmrg 684d6c0b56eSmrgstatic RegionPtr 685d6c0b56eSmrgamdgpu_glamor_bitmap_to_region(PixmapPtr pPix) 686d6c0b56eSmrg{ 687d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen); 688d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pPix); 689d6c0b56eSmrg RegionPtr ret; 690d6c0b56eSmrg 691d6c0b56eSmrg if (!amdgpu_glamor_prepare_access_cpu_ro(scrn, pPix, priv)) 692d6c0b56eSmrg return NULL; 693d6c0b56eSmrg ret = fbPixmapToRegion(pPix); 694d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pPix); 695d6c0b56eSmrg return ret; 696d6c0b56eSmrg} 697d6c0b56eSmrg 698d6c0b56eSmrgstatic void 699d6c0b56eSmrgamdgpu_glamor_copy_window(WindowPtr pWin, DDXPointRec ptOldOrg, 700d6c0b56eSmrg RegionPtr prgnSrc) 701d6c0b56eSmrg{ 702d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pWin->drawable.pScreen); 703d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(&pWin->drawable); 704d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 705d6c0b56eSmrg 706d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) { 707d6c0b56eSmrg fbCopyWindow(pWin, ptOldOrg, prgnSrc); 708d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 709d6c0b56eSmrg } 710d6c0b56eSmrg} 711d6c0b56eSmrg 712d6c0b56eSmrgstatic void 713d6c0b56eSmrgamdgpu_glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, 714d6c0b56eSmrg unsigned int format, unsigned long planeMask, char *d) 715d6c0b56eSmrg{ 716d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 717d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 718d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 719d6c0b56eSmrg 720d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) { 721d6c0b56eSmrg fbGetImage(pDrawable, x, y, w, h, format, planeMask, d); 722d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 723d6c0b56eSmrg } 724d6c0b56eSmrg} 725d6c0b56eSmrg 726d6c0b56eSmrgstatic void 727d6c0b56eSmrgamdgpu_glamor_get_spans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, 728d6c0b56eSmrg int *pwidth, int nspans, char *pdstStart) 729d6c0b56eSmrg{ 730d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen); 731d6c0b56eSmrg PixmapPtr pixmap = get_drawable_pixmap(pDrawable); 732d6c0b56eSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 733d6c0b56eSmrg 734d6c0b56eSmrg if (amdgpu_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) { 735d6c0b56eSmrg fbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); 736d6c0b56eSmrg amdgpu_glamor_finish_access_cpu(pixmap); 737d6c0b56eSmrg } 738d6c0b56eSmrg} 739d6c0b56eSmrg 740d6c0b56eSmrg/* 741d6c0b56eSmrg * Picture screen rendering wrappers 742d6c0b56eSmrg */ 743d6c0b56eSmrg 744d6c0b56eSmrg#ifdef RENDER 745d6c0b56eSmrg 746d6c0b56eSmrgstatic void 747d6c0b56eSmrgamdgpu_glamor_composite(CARD8 op, 748d6c0b56eSmrg PicturePtr pSrc, 749d6c0b56eSmrg PicturePtr pMask, 750d6c0b56eSmrg PicturePtr pDst, 751d6c0b56eSmrg INT16 xSrc, INT16 ySrc, 752d6c0b56eSmrg INT16 xMask, INT16 yMask, 753d6c0b56eSmrg INT16 xDst, INT16 yDst, 754d6c0b56eSmrg CARD16 width, CARD16 height) 755d6c0b56eSmrg{ 756d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pDrawable->pScreen); 757d6c0b56eSmrg AMDGPUInfoPtr info; 758d6c0b56eSmrg PixmapPtr pixmap; 759d6c0b56eSmrg struct amdgpu_pixmap *dst_priv, *src_priv = NULL, *mask_priv = NULL; 760d6c0b56eSmrg Bool gpu_done = FALSE; 761d6c0b56eSmrg 762d6c0b56eSmrg if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) 763d6c0b56eSmrg goto fallback; 764d6c0b56eSmrg 765d6c0b56eSmrg pixmap = get_drawable_pixmap(pDst->pDrawable); 766d6c0b56eSmrg if (&pixmap->drawable != pDst->pDrawable || 767d6c0b56eSmrg pixmap->usage_hint != AMDGPU_CREATE_PIXMAP_SCANOUT) 768d6c0b56eSmrg goto fallback; 769d6c0b56eSmrg 770d6c0b56eSmrg dst_priv = amdgpu_get_pixmap_private(pixmap); 771d6c0b56eSmrg if (!amdgpu_glamor_prepare_access_gpu(dst_priv)) 772d6c0b56eSmrg goto fallback; 773d6c0b56eSmrg 774d6c0b56eSmrg info = AMDGPUPTR(scrn); 775d6c0b56eSmrg if (!pSrc->pDrawable || 776d6c0b56eSmrg ((pixmap = get_drawable_pixmap(pSrc->pDrawable)) && 777d6c0b56eSmrg (src_priv = amdgpu_get_pixmap_private(pixmap)) && 778d6c0b56eSmrg amdgpu_glamor_prepare_access_gpu(src_priv))) { 779d6c0b56eSmrg if (!pMask || !pMask->pDrawable || 780d6c0b56eSmrg ((pixmap = get_drawable_pixmap(pMask->pDrawable)) && 781d6c0b56eSmrg (mask_priv = amdgpu_get_pixmap_private(pixmap)) && 782d6c0b56eSmrg amdgpu_glamor_prepare_access_gpu(mask_priv))) { 783d6c0b56eSmrg info->glamor.SavedComposite(op, pSrc, pMask, pDst, 784d6c0b56eSmrg xSrc, ySrc, xMask, yMask, 785d6c0b56eSmrg xDst, yDst, width, height); 786d6c0b56eSmrg gpu_done = TRUE; 787d6c0b56eSmrg 788d6c0b56eSmrg if (mask_priv) 789d6c0b56eSmrg amdgpu_glamor_finish_access_gpu_ro(info, mask_priv); 790d6c0b56eSmrg } 791d6c0b56eSmrg 792d6c0b56eSmrg if (src_priv) 793d6c0b56eSmrg amdgpu_glamor_finish_access_gpu_ro(info, src_priv); 794d6c0b56eSmrg } 795d6c0b56eSmrg amdgpu_glamor_finish_access_gpu_rw(info, dst_priv); 796d6c0b56eSmrg 797d6c0b56eSmrg if (gpu_done) 798d6c0b56eSmrg return; 799d6c0b56eSmrg 800d6c0b56eSmrgfallback: 801d6c0b56eSmrg if (amdgpu_glamor_picture_prepare_access_cpu_rw(scrn, pDst)) { 802d6c0b56eSmrg if (amdgpu_glamor_picture_prepare_access_cpu_ro(scrn, pSrc)) { 803d6c0b56eSmrg if (!pMask || 804d6c0b56eSmrg amdgpu_glamor_picture_prepare_access_cpu_ro(scrn, pMask)) { 805d6c0b56eSmrg fbComposite(op, pSrc, pMask, pDst, 806d6c0b56eSmrg xSrc, ySrc, 807d6c0b56eSmrg xMask, yMask, 808d6c0b56eSmrg xDst, yDst, 809d6c0b56eSmrg width, height); 810d6c0b56eSmrg if (pMask) 811d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(pMask); 812d6c0b56eSmrg } 813d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(pSrc); 814d6c0b56eSmrg } 815d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(pDst); 816d6c0b56eSmrg } 817d6c0b56eSmrg} 818d6c0b56eSmrg 819d6c0b56eSmrgstatic void 820d6c0b56eSmrgamdgpu_glamor_add_traps(PicturePtr pPicture, 821d6c0b56eSmrg INT16 x_off, INT16 y_off, int ntrap, xTrap *traps) 822d6c0b56eSmrg{ 823d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pPicture->pDrawable->pScreen); 824d6c0b56eSmrg 825d6c0b56eSmrg if (amdgpu_glamor_picture_prepare_access_cpu_rw(scrn, pPicture)) { 826d6c0b56eSmrg fbAddTraps(pPicture, x_off, y_off, ntrap, traps); 827d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(pPicture); 828d6c0b56eSmrg } 829d6c0b56eSmrg} 830d6c0b56eSmrg 831d6c0b56eSmrgstatic void 832d6c0b56eSmrgamdgpu_glamor_glyphs(CARD8 op, 833d6c0b56eSmrg PicturePtr src, 834d6c0b56eSmrg PicturePtr dst, 835d6c0b56eSmrg PictFormatPtr maskFormat, 836d6c0b56eSmrg INT16 xSrc, 837d6c0b56eSmrg INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs) 838d6c0b56eSmrg{ 839d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(dst->pDrawable->pScreen); 840d6c0b56eSmrg 841d6c0b56eSmrg if (amdgpu_glamor_picture_prepare_access_cpu_rw(scrn, dst)) { 842d6c0b56eSmrg if (amdgpu_glamor_picture_prepare_access_cpu_ro(scrn, src)) { 843d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 844d6c0b56eSmrg 845d6c0b56eSmrg info->glamor.SavedGlyphs(op, src, dst, maskFormat, xSrc, 846d6c0b56eSmrg ySrc, nlist, list, glyphs); 847d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(src); 848d6c0b56eSmrg } 849d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(dst); 850d6c0b56eSmrg } 851d6c0b56eSmrg} 852d6c0b56eSmrg 853d6c0b56eSmrgstatic void 854d6c0b56eSmrgamdgpu_glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, 855d6c0b56eSmrg PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, 856d6c0b56eSmrg int ntrap, xTrapezoid *traps) 857d6c0b56eSmrg{ 858d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(dst->pDrawable->pScreen); 859d6c0b56eSmrg 860d6c0b56eSmrg if (amdgpu_glamor_picture_prepare_access_cpu_rw(scrn, dst)) { 861d6c0b56eSmrg if (amdgpu_glamor_picture_prepare_access_cpu_ro(scrn, src)) { 862d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 863d6c0b56eSmrg 864d6c0b56eSmrg info->glamor.SavedTrapezoids(op, src, dst, maskFormat, 865d6c0b56eSmrg xSrc, ySrc, ntrap, traps); 866d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(src); 867d6c0b56eSmrg } 868d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(dst); 869d6c0b56eSmrg } 870d6c0b56eSmrg} 871d6c0b56eSmrg 872d6c0b56eSmrgstatic void 873d6c0b56eSmrgamdgpu_glamor_triangles(CARD8 op, PicturePtr src, PicturePtr dst, 874d6c0b56eSmrg PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, 875d6c0b56eSmrg int ntri, xTriangle *tri) 876d6c0b56eSmrg{ 877d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(dst->pDrawable->pScreen); 878d6c0b56eSmrg 879d6c0b56eSmrg if (amdgpu_glamor_picture_prepare_access_cpu_rw(scrn, dst)) { 880d6c0b56eSmrg if (amdgpu_glamor_picture_prepare_access_cpu_ro(scrn, src)) { 881d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 882d6c0b56eSmrg 883d6c0b56eSmrg info->glamor.SavedTriangles(op, src, dst, maskFormat, 884d6c0b56eSmrg xSrc, ySrc, ntri, tri); 885d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(src); 886d6c0b56eSmrg } 887d6c0b56eSmrg amdgpu_glamor_picture_finish_access_cpu(dst); 888d6c0b56eSmrg } 889d6c0b56eSmrg} 890d6c0b56eSmrg 891d6c0b56eSmrg#endif /* RENDER */ 892d6c0b56eSmrg 893d6c0b56eSmrg 894d6c0b56eSmrg/** 895d6c0b56eSmrg * amdgpu_glamor_close_screen() unwraps its wrapped screen functions and tears 896d6c0b56eSmrg * down our screen private, before calling down to the next CloseScreen. 897d6c0b56eSmrg */ 898d6c0b56eSmrgstatic Bool 89924b90cf4Smrgamdgpu_glamor_close_screen(ScreenPtr pScreen) 900d6c0b56eSmrg{ 901d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(xf86ScreenToScrn(pScreen)); 902d6c0b56eSmrg#ifdef RENDER 903d6c0b56eSmrg PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); 904d6c0b56eSmrg#endif 905d6c0b56eSmrg 906d6c0b56eSmrg pScreen->CreateGC = info->glamor.SavedCreateGC; 907d6c0b56eSmrg pScreen->CloseScreen = info->glamor.SavedCloseScreen; 908d6c0b56eSmrg pScreen->GetImage = info->glamor.SavedGetImage; 909d6c0b56eSmrg pScreen->GetSpans = info->glamor.SavedGetSpans; 910d6c0b56eSmrg pScreen->CopyWindow = info->glamor.SavedCopyWindow; 911d6c0b56eSmrg pScreen->ChangeWindowAttributes = 912d6c0b56eSmrg info->glamor.SavedChangeWindowAttributes; 913d6c0b56eSmrg pScreen->BitmapToRegion = info->glamor.SavedBitmapToRegion; 914d6c0b56eSmrg#ifdef RENDER 915d6c0b56eSmrg if (ps) { 916d6c0b56eSmrg ps->Composite = info->glamor.SavedComposite; 917d6c0b56eSmrg ps->Glyphs = info->glamor.SavedGlyphs; 918d6c0b56eSmrg ps->UnrealizeGlyph = info->glamor.SavedUnrealizeGlyph; 919d6c0b56eSmrg ps->Trapezoids = info->glamor.SavedTrapezoids; 920d6c0b56eSmrg ps->AddTraps = info->glamor.SavedAddTraps; 921d6c0b56eSmrg ps->Triangles = info->glamor.SavedTriangles; 922d6c0b56eSmrg 923d6c0b56eSmrg ps->UnrealizeGlyph = info->glamor.SavedUnrealizeGlyph; 924d6c0b56eSmrg } 925d6c0b56eSmrg#endif 926d6c0b56eSmrg 92724b90cf4Smrg return pScreen->CloseScreen(pScreen); 928d6c0b56eSmrg} 929d6c0b56eSmrg 930d6c0b56eSmrg/** 931d6c0b56eSmrg * @param screen screen being initialized 932d6c0b56eSmrg */ 933d6c0b56eSmrgvoid 934d6c0b56eSmrgamdgpu_glamor_screen_init(ScreenPtr screen) 935d6c0b56eSmrg{ 936d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(xf86ScreenToScrn(screen)); 937d6c0b56eSmrg 938d6c0b56eSmrg /* 939d6c0b56eSmrg * Replace various fb screen functions 940d6c0b56eSmrg */ 941d6c0b56eSmrg info->glamor.SavedCloseScreen = screen->CloseScreen; 942d6c0b56eSmrg screen->CloseScreen = amdgpu_glamor_close_screen; 943d6c0b56eSmrg 944d6c0b56eSmrg info->glamor.SavedCreateGC = screen->CreateGC; 945d6c0b56eSmrg screen->CreateGC = amdgpu_glamor_create_gc; 946d6c0b56eSmrg 947d6c0b56eSmrg info->glamor.SavedGetImage = screen->GetImage; 948d6c0b56eSmrg screen->GetImage = amdgpu_glamor_get_image; 949d6c0b56eSmrg 950d6c0b56eSmrg info->glamor.SavedGetSpans = screen->GetSpans; 951d6c0b56eSmrg screen->GetSpans = amdgpu_glamor_get_spans; 952d6c0b56eSmrg 953d6c0b56eSmrg info->glamor.SavedCopyWindow = screen->CopyWindow; 954d6c0b56eSmrg screen->CopyWindow = amdgpu_glamor_copy_window; 955d6c0b56eSmrg 956d6c0b56eSmrg info->glamor.SavedBitmapToRegion = screen->BitmapToRegion; 957d6c0b56eSmrg screen->BitmapToRegion = amdgpu_glamor_bitmap_to_region; 958d6c0b56eSmrg 959d6c0b56eSmrg#ifdef RENDER 960d6c0b56eSmrg { 961d6c0b56eSmrg PictureScreenPtr ps = GetPictureScreenIfSet(screen); 962d6c0b56eSmrg if (ps) { 963d6c0b56eSmrg info->glamor.SavedComposite = ps->Composite; 964d6c0b56eSmrg ps->Composite = amdgpu_glamor_composite; 965d6c0b56eSmrg 966d6c0b56eSmrg info->glamor.SavedUnrealizeGlyph = ps->UnrealizeGlyph; 967d6c0b56eSmrg 968d6c0b56eSmrg ps->Glyphs = amdgpu_glamor_glyphs; 969d6c0b56eSmrg ps->Triangles = amdgpu_glamor_triangles; 970d6c0b56eSmrg ps->Trapezoids = amdgpu_glamor_trapezoids; 971d6c0b56eSmrg 972d6c0b56eSmrg info->glamor.SavedAddTraps = ps->AddTraps; 973d6c0b56eSmrg ps->AddTraps = amdgpu_glamor_add_traps; 974d6c0b56eSmrg } 975d6c0b56eSmrg } 976d6c0b56eSmrg#endif 977d6c0b56eSmrg} 978d6c0b56eSmrg 979d6c0b56eSmrg#endif /* USE_GLAMOR */ 980