1d6c0b56eSmrg/* 2d6c0b56eSmrg * Copyright © 2011 Intel Corporation. 3d6c0b56eSmrg * 2012 Advanced Micro Devices, Inc. 4d6c0b56eSmrg * 5d6c0b56eSmrg * Permission is hereby granted, free of charge, to any person 6d6c0b56eSmrg * obtaining a copy of this software and associated documentation 7d6c0b56eSmrg * files (the "Software"), to deal in the Software without 8d6c0b56eSmrg * restriction, including without limitation the rights to use, copy, 9d6c0b56eSmrg * modify, merge, publish, distribute, sublicense, and/or sell copies 10d6c0b56eSmrg * of the Software, and to permit persons to whom the Software is 11d6c0b56eSmrg * furnished to do so, subject to the following conditions: 12d6c0b56eSmrg * 13d6c0b56eSmrg * The above copyright notice and this permission notice (including 14d6c0b56eSmrg * the next paragraph) shall be included in all copies or substantial 15d6c0b56eSmrg * portions of the Software. 16d6c0b56eSmrg * 17d6c0b56eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18d6c0b56eSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19d6c0b56eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20d6c0b56eSmrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21d6c0b56eSmrg * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22d6c0b56eSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23d6c0b56eSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24d6c0b56eSmrg * DEALINGS IN THE SOFTWARE. 25d6c0b56eSmrg */ 26d6c0b56eSmrg 27d6c0b56eSmrg#ifdef HAVE_CONFIG_H 28d6c0b56eSmrg#include "config.h" 29d6c0b56eSmrg#endif 30d6c0b56eSmrg 3190f2b693Smrg#ifdef USE_GLAMOR 3290f2b693Smrg 33d6c0b56eSmrg#include <xf86.h> 34d6c0b56eSmrg 35d6c0b56eSmrg#include "amdgpu_bo_helper.h" 36d6c0b56eSmrg#include "amdgpu_pixmap.h" 37d6c0b56eSmrg#include "amdgpu_glamor.h" 38d6c0b56eSmrg 39d6c0b56eSmrg#include <gbm.h> 40d6c0b56eSmrg 4111bf0794Smrg#ifndef HAVE_GLAMOR_FINISH 42d6c0b56eSmrg#include <GL/gl.h> 4311bf0794Smrg#endif 44d6c0b56eSmrg 45d6c0b56eSmrgDevPrivateKeyRec amdgpu_pixmap_index; 46d6c0b56eSmrg 47d6c0b56eSmrgvoid amdgpu_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst) 48d6c0b56eSmrg{ 49d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(xf86ScreenToScrn(dst->drawable.pScreen)); 50d6c0b56eSmrg 51d6c0b56eSmrg if (!info->use_glamor) 52d6c0b56eSmrg return; 53d6c0b56eSmrg glamor_egl_exchange_buffers(src, dst); 54d6c0b56eSmrg} 55d6c0b56eSmrg 56d6c0b56eSmrgBool amdgpu_glamor_create_screen_resources(ScreenPtr screen) 57d6c0b56eSmrg{ 5835d5b7c7Smrg PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); 59d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 60d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 61d6c0b56eSmrg 62d6c0b56eSmrg if (!info->use_glamor) 63d6c0b56eSmrg return TRUE; 64d6c0b56eSmrg 65d6c0b56eSmrg#ifdef HAVE_GLAMOR_GLYPHS_INIT 66d6c0b56eSmrg if (!glamor_glyphs_init(screen)) 67d6c0b56eSmrg return FALSE; 68d6c0b56eSmrg#endif 69d6c0b56eSmrg 7035d5b7c7Smrg return amdgpu_glamor_create_textured_pixmap(screen_pixmap, 7135d5b7c7Smrg info->front_buffer); 72d6c0b56eSmrg} 73d6c0b56eSmrg 74d6c0b56eSmrgBool amdgpu_glamor_pre_init(ScrnInfoPtr scrn) 75d6c0b56eSmrg{ 76d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 77d6c0b56eSmrg pointer glamor_module; 78d6c0b56eSmrg CARD32 version; 79d6c0b56eSmrg 8090f2b693Smrg#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,99,0,0) 81d6c0b56eSmrg if (scrn->depth < 24) { 8290f2b693Smrg#else 8390f2b693Smrg if (scrn->depth < 15) { 8490f2b693Smrg#endif 85d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_ERROR, 8690f2b693Smrg "Depth %d not supported with glamor, disabling\n", 8790f2b693Smrg scrn->depth); 88d6c0b56eSmrg return FALSE; 89d6c0b56eSmrg } 9090f2b693Smrg 91d6c0b56eSmrg#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,15,0,0,0) 92d6c0b56eSmrg if (!xf86LoaderCheckSymbol("glamor_egl_init")) { 93d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_ERROR, 94d6c0b56eSmrg "glamor requires Load \"glamoregl\" in " 95d6c0b56eSmrg "Section \"Module\", disabling.\n"); 96d6c0b56eSmrg return FALSE; 97d6c0b56eSmrg } 98d6c0b56eSmrg#endif 99d6c0b56eSmrg 100d6c0b56eSmrg /* Load glamor module */ 101d6c0b56eSmrg if ((glamor_module = xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME))) { 102d6c0b56eSmrg version = xf86GetModuleVersion(glamor_module); 103d6c0b56eSmrg if (version < MODULE_VERSION_NUMERIC(0, 3, 1)) { 104d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_ERROR, 105d6c0b56eSmrg "Incompatible glamor version, required >= 0.3.0.\n"); 106d6c0b56eSmrg return FALSE; 107d6c0b56eSmrg } else { 108d6c0b56eSmrg AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); 109d6c0b56eSmrg 11035d5b7c7Smrg if (scrn->depth == 30 && 11135d5b7c7Smrg version < MODULE_VERSION_NUMERIC(1, 0, 1)) { 11235d5b7c7Smrg xf86DrvMsg(scrn->scrnIndex, X_WARNING, 11335d5b7c7Smrg "Depth 30 requires glamor >= 1.0.1 (xserver 1.20)," 11435d5b7c7Smrg " can't enable glamor\n"); 11535d5b7c7Smrg return FALSE; 11635d5b7c7Smrg } 11735d5b7c7Smrg 118d6c0b56eSmrg if (glamor_egl_init(scrn, pAMDGPUEnt->fd)) { 119d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_INFO, 120d6c0b56eSmrg "glamor detected, initialising EGL layer.\n"); 121d6c0b56eSmrg } else { 122d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_ERROR, 123d6c0b56eSmrg "glamor detected, failed to initialize EGL.\n"); 124d6c0b56eSmrg return FALSE; 125d6c0b56eSmrg } 126d6c0b56eSmrg } 127d6c0b56eSmrg } else { 128d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_ERROR, "glamor not available\n"); 129d6c0b56eSmrg return FALSE; 130d6c0b56eSmrg } 131d6c0b56eSmrg 132d6c0b56eSmrg info->use_glamor = TRUE; 133d6c0b56eSmrg 134d6c0b56eSmrg return TRUE; 135d6c0b56eSmrg} 136d6c0b56eSmrg 137d6c0b56eSmrgBool 138504d986fSmrgamdgpu_glamor_create_textured_pixmap(PixmapPtr pixmap, struct amdgpu_buffer *bo) 139d6c0b56eSmrg{ 140d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); 141d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 142d6c0b56eSmrg 143d6c0b56eSmrg if ((info->use_glamor) == 0) 144d6c0b56eSmrg return TRUE; 145d6c0b56eSmrg 14635d5b7c7Smrg if (bo->flags & AMDGPU_BO_FLAGS_GBM) { 14735d5b7c7Smrg return glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, 14835d5b7c7Smrg bo->bo.gbm 14935d5b7c7Smrg#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,19,99,903,0) 15035d5b7c7Smrg , FALSE 15135d5b7c7Smrg#endif 15235d5b7c7Smrg ); 15335d5b7c7Smrg } else { 15435d5b7c7Smrg uint32_t bo_handle; 155d6c0b56eSmrg 15635d5b7c7Smrg if (!amdgpu_bo_get_handle(bo, &bo_handle)) 15735d5b7c7Smrg return FALSE; 15835d5b7c7Smrg 15935d5b7c7Smrg return glamor_egl_create_textured_pixmap(pixmap, bo_handle, 16035d5b7c7Smrg pixmap->devKind); 16135d5b7c7Smrg } 162d6c0b56eSmrg} 163d6c0b56eSmrg 164d6c0b56eSmrgstatic Bool amdgpu_glamor_destroy_pixmap(PixmapPtr pixmap) 165d6c0b56eSmrg{ 166d6c0b56eSmrg#ifndef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP 167d6c0b56eSmrg ScreenPtr screen = pixmap->drawable.pScreen; 168d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(xf86ScreenToScrn(screen)); 169d6c0b56eSmrg Bool ret; 170d6c0b56eSmrg#endif 171d6c0b56eSmrg 172d6c0b56eSmrg if (pixmap->refcnt == 1) { 173d6c0b56eSmrg if (pixmap->devPrivate.ptr) { 174d6c0b56eSmrg struct amdgpu_buffer *bo = amdgpu_get_pixmap_bo(pixmap); 175d6c0b56eSmrg 176d6c0b56eSmrg if (bo) 177d6c0b56eSmrg amdgpu_bo_unmap(bo); 178d6c0b56eSmrg } 179d6c0b56eSmrg 180d6c0b56eSmrg#ifdef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP 181d6c0b56eSmrg glamor_egl_destroy_textured_pixmap(pixmap); 182d6c0b56eSmrg#endif 183d6c0b56eSmrg amdgpu_set_pixmap_bo(pixmap, NULL); 184d6c0b56eSmrg } 185d6c0b56eSmrg 186d6c0b56eSmrg#ifdef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP 187d6c0b56eSmrg fbDestroyPixmap(pixmap); 188d6c0b56eSmrg return TRUE; 189d6c0b56eSmrg#else 190d6c0b56eSmrg screen->DestroyPixmap = info->glamor.SavedDestroyPixmap; 191d6c0b56eSmrg ret = screen->DestroyPixmap(pixmap); 192d6c0b56eSmrg info->glamor.SavedDestroyPixmap = screen->DestroyPixmap; 193d6c0b56eSmrg screen->DestroyPixmap = amdgpu_glamor_destroy_pixmap; 194d6c0b56eSmrg 195d6c0b56eSmrg return ret; 196d6c0b56eSmrg#endif 197d6c0b56eSmrg} 198d6c0b56eSmrg 199d6c0b56eSmrgstatic PixmapPtr 200d6c0b56eSmrgamdgpu_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, 201d6c0b56eSmrg unsigned usage) 202d6c0b56eSmrg{ 203d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 20446845023Smrg PixmapFormatPtr format = xf86GetPixFormat(scrn, depth); 205d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 206d6c0b56eSmrg struct amdgpu_pixmap *priv; 207d6c0b56eSmrg PixmapPtr pixmap, new_pixmap = NULL; 208d6c0b56eSmrg 20946845023Smrg if (!format) 21035d5b7c7Smrg return NULL; 21135d5b7c7Smrg 212e49c54bcSmrg if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP && 213e49c54bcSmrg usage != CREATE_PIXMAP_USAGE_SHARED && 214e49c54bcSmrg !info->shadow_primary && 215e49c54bcSmrg w >= scrn->virtualX && 216e49c54bcSmrg w <= scrn->displayWidth && 217e49c54bcSmrg h == scrn->virtualY && 218e49c54bcSmrg format->bitsPerPixel == scrn->bitsPerPixel) 219e49c54bcSmrg usage |= AMDGPU_CREATE_PIXMAP_SCANOUT; 220e49c54bcSmrg 22146845023Smrg if (!(usage & AMDGPU_CREATE_PIXMAP_SCANOUT) && 22246845023Smrg !AMDGPU_CREATE_PIXMAP_SHARED(usage)) { 223d6c0b56eSmrg if (info->shadow_primary) { 224d6c0b56eSmrg if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) 225d6c0b56eSmrg return fbCreatePixmap(screen, w, h, depth, usage); 226d6c0b56eSmrg 227d6c0b56eSmrg usage |= AMDGPU_CREATE_PIXMAP_LINEAR | 228d6c0b56eSmrg AMDGPU_CREATE_PIXMAP_GTT; 22990f2b693Smrg } else if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) { 230e49c54bcSmrg pixmap = glamor_create_pixmap(screen, w, h, depth, usage); 231e49c54bcSmrg if (pixmap) 232e49c54bcSmrg return pixmap; 233d6c0b56eSmrg } 234d6c0b56eSmrg } 235d6c0b56eSmrg 236d6c0b56eSmrg if (w > 32767 || h > 32767) 237d6c0b56eSmrg return NullPixmap; 238d6c0b56eSmrg 239d6c0b56eSmrg if (depth == 1) 240d6c0b56eSmrg return fbCreatePixmap(screen, w, h, depth, usage); 241d6c0b56eSmrg 242d6c0b56eSmrg if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32) 243d6c0b56eSmrg return fbCreatePixmap(screen, w, h, depth, usage); 244d6c0b56eSmrg 245d6c0b56eSmrg pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); 246d6c0b56eSmrg if (pixmap == NullPixmap) 247d6c0b56eSmrg return pixmap; 248d6c0b56eSmrg 249d6c0b56eSmrg if (w && h) { 250d6c0b56eSmrg int stride; 251d6c0b56eSmrg 252d6c0b56eSmrg priv = calloc(1, sizeof(struct amdgpu_pixmap)); 25335d5b7c7Smrg if (!priv) 254d6c0b56eSmrg goto fallback_pixmap; 255d6c0b56eSmrg 256d6c0b56eSmrg priv->bo = amdgpu_alloc_pixmap_bo(scrn, w, h, depth, usage, 257d6c0b56eSmrg pixmap->drawable.bitsPerPixel, 258d6c0b56eSmrg &stride); 259d6c0b56eSmrg if (!priv->bo) 260d6c0b56eSmrg goto fallback_priv; 261d6c0b56eSmrg 262d6c0b56eSmrg amdgpu_set_pixmap_private(pixmap, priv); 263d6c0b56eSmrg 264d6c0b56eSmrg screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL); 265d6c0b56eSmrg 266d6c0b56eSmrg pixmap->devPrivate.ptr = NULL; 267d6c0b56eSmrg 268504d986fSmrg if (!amdgpu_glamor_create_textured_pixmap(pixmap, priv->bo)) 269d6c0b56eSmrg goto fallback_glamor; 270d6c0b56eSmrg } 271d6c0b56eSmrg 272d6c0b56eSmrg return pixmap; 273d6c0b56eSmrg 274d6c0b56eSmrgfallback_glamor: 275d6c0b56eSmrg if (AMDGPU_CREATE_PIXMAP_SHARED(usage)) { 276d6c0b56eSmrg /* XXX need further work to handle the DRI2 failure case. 277d6c0b56eSmrg * Glamor don't know how to handle a BO only pixmap. Put 278d6c0b56eSmrg * a warning indicator here. 279d6c0b56eSmrg */ 280d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_WARNING, 281d6c0b56eSmrg "Failed to create textured DRI2/PRIME pixmap."); 282d6c0b56eSmrg 283d6c0b56eSmrg amdgpu_glamor_destroy_pixmap(pixmap); 284d6c0b56eSmrg return NullPixmap; 285d6c0b56eSmrg } 286d6c0b56eSmrg /* Create textured pixmap failed means glamor failed to 287d6c0b56eSmrg * create a texture from current BO for some reasons. We turn 288d6c0b56eSmrg * to create a new glamor pixmap and clean up current one. 289d6c0b56eSmrg * One thing need to be noted, this new pixmap doesn't 290d6c0b56eSmrg * has a priv and bo attached to it. It's glamor's responsbility 291d6c0b56eSmrg * to take care of it. Glamor will mark this new pixmap as a 292d6c0b56eSmrg * texture only pixmap and will never fallback to DDX layer 293d6c0b56eSmrg * afterwards. 294d6c0b56eSmrg */ 295d6c0b56eSmrg new_pixmap = glamor_create_pixmap(screen, w, h, depth, usage); 296d6c0b56eSmrg amdgpu_bo_unref(&priv->bo); 297d6c0b56eSmrgfallback_priv: 298d6c0b56eSmrg free(priv); 299d6c0b56eSmrgfallback_pixmap: 300d6c0b56eSmrg fbDestroyPixmap(pixmap); 301d6c0b56eSmrg if (new_pixmap) 302d6c0b56eSmrg return new_pixmap; 303d6c0b56eSmrg else 304d6c0b56eSmrg return fbCreatePixmap(screen, w, h, depth, usage); 305d6c0b56eSmrg} 306d6c0b56eSmrg 307504d986fSmrgPixmapPtr 308504d986fSmrgamdgpu_glamor_set_pixmap_bo(DrawablePtr drawable, PixmapPtr pixmap) 309504d986fSmrg{ 310504d986fSmrg PixmapPtr old = get_drawable_pixmap(drawable); 311504d986fSmrg ScreenPtr screen = drawable->pScreen; 312504d986fSmrg struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pixmap); 313504d986fSmrg GCPtr gc; 314504d986fSmrg 315504d986fSmrg /* With a glamor pixmap, 2D pixmaps are created in texture 316504d986fSmrg * and without a static BO attached to it. To support DRI, 317504d986fSmrg * we need to create a new textured-drm pixmap and 318504d986fSmrg * need to copy the original content to this new textured-drm 319504d986fSmrg * pixmap, and then convert the old pixmap to a coherent 320504d986fSmrg * textured-drm pixmap which has a valid BO attached to it 321504d986fSmrg * and also has a valid texture, thus both glamor and DRI2 322504d986fSmrg * can access it. 323504d986fSmrg * 324504d986fSmrg */ 325504d986fSmrg 326504d986fSmrg /* Copy the current contents of the pixmap to the bo. */ 327504d986fSmrg gc = GetScratchGC(drawable->depth, screen); 328504d986fSmrg if (gc) { 329504d986fSmrg ValidateGC(&pixmap->drawable, gc); 330504d986fSmrg gc->ops->CopyArea(&old->drawable, &pixmap->drawable, 331504d986fSmrg gc, 332504d986fSmrg 0, 0, 333504d986fSmrg old->drawable.width, 334504d986fSmrg old->drawable.height, 0, 0); 335504d986fSmrg FreeScratchGC(gc); 336504d986fSmrg } 337504d986fSmrg 338504d986fSmrg /* And redirect the pixmap to the new bo (for 3D). */ 339504d986fSmrg glamor_egl_exchange_buffers(old, pixmap); 340504d986fSmrg amdgpu_set_pixmap_private(pixmap, amdgpu_get_pixmap_private(old)); 341504d986fSmrg amdgpu_set_pixmap_private(old, priv); 342504d986fSmrg 343504d986fSmrg screen->ModifyPixmapHeader(old, 344504d986fSmrg old->drawable.width, 345504d986fSmrg old->drawable.height, 346504d986fSmrg 0, 0, pixmap->devKind, NULL); 347504d986fSmrg old->devPrivate.ptr = NULL; 348504d986fSmrg 349504d986fSmrg screen->DestroyPixmap(pixmap); 350504d986fSmrg 351504d986fSmrg return old; 352504d986fSmrg} 353504d986fSmrg 354d6c0b56eSmrg 355d6c0b56eSmrgstatic Bool 35646845023Smrgamdgpu_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr secondary, 357d6c0b56eSmrg void **handle_p) 358d6c0b56eSmrg{ 359504d986fSmrg ScreenPtr screen = pixmap->drawable.pScreen; 36024b90cf4Smrg AMDGPUInfoPtr info = AMDGPUPTR(xf86ScreenToScrn(screen)); 361504d986fSmrg uint64_t tiling_info; 362504d986fSmrg CARD16 stride; 363504d986fSmrg CARD32 size; 36424b90cf4Smrg Bool is_linear; 365504d986fSmrg int fd; 366504d986fSmrg 367504d986fSmrg tiling_info = amdgpu_pixmap_get_tiling_info(pixmap); 36824b90cf4Smrg 36924b90cf4Smrg if (info->family >= AMDGPU_FAMILY_AI) 37024b90cf4Smrg is_linear = AMDGPU_TILING_GET(tiling_info, SWIZZLE_MODE) == 0; 37124b90cf4Smrg else 37224b90cf4Smrg is_linear = AMDGPU_TILING_GET(tiling_info, ARRAY_MODE) == 1; 37324b90cf4Smrg 37424b90cf4Smrg if (!is_linear) { 375504d986fSmrg PixmapPtr linear; 376504d986fSmrg 377504d986fSmrg /* We don't want to re-allocate the screen pixmap as 378504d986fSmrg * linear, to avoid trouble with page flipping 379504d986fSmrg */ 380504d986fSmrg if (screen->GetScreenPixmap(screen) == pixmap) 381504d986fSmrg return FALSE; 382d6c0b56eSmrg 383504d986fSmrg linear = screen->CreatePixmap(screen, pixmap->drawable.width, 384504d986fSmrg pixmap->drawable.height, 385504d986fSmrg pixmap->drawable.depth, 386504d986fSmrg CREATE_PIXMAP_USAGE_SHARED); 387504d986fSmrg if (!linear) 388504d986fSmrg return FALSE; 389504d986fSmrg 390504d986fSmrg amdgpu_glamor_set_pixmap_bo(&pixmap->drawable, linear); 391504d986fSmrg } 392504d986fSmrg 393504d986fSmrg fd = glamor_fd_from_pixmap(screen, pixmap, &stride, &size); 394504d986fSmrg if (fd < 0) 395d6c0b56eSmrg return FALSE; 396d6c0b56eSmrg 397504d986fSmrg *handle_p = (void *)(long)fd; 398504d986fSmrg return TRUE; 399d6c0b56eSmrg} 400d6c0b56eSmrg 401d6c0b56eSmrgstatic Bool 402d6c0b56eSmrgamdgpu_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle) 403d6c0b56eSmrg{ 404d6c0b56eSmrg ScreenPtr screen = pixmap->drawable.pScreen; 405d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 40635d5b7c7Smrg int ihandle = (int)(long)handle; 407d6c0b56eSmrg struct amdgpu_pixmap *priv; 408d6c0b56eSmrg 409d6c0b56eSmrg if (!amdgpu_set_shared_pixmap_backing(pixmap, handle)) 410d6c0b56eSmrg return FALSE; 411d6c0b56eSmrg 412d6c0b56eSmrg priv = amdgpu_get_pixmap_private(pixmap); 413d6c0b56eSmrg 41435d5b7c7Smrg if (ihandle != -1 && 41535d5b7c7Smrg !amdgpu_glamor_create_textured_pixmap(pixmap, priv->bo)) { 416d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_ERROR, 417d6c0b56eSmrg "Failed to get PRIME drawable for glamor pixmap.\n"); 418d6c0b56eSmrg return FALSE; 419d6c0b56eSmrg } 420d6c0b56eSmrg 421d6c0b56eSmrg screen->ModifyPixmapHeader(pixmap, 422d6c0b56eSmrg pixmap->drawable.width, 423d6c0b56eSmrg pixmap->drawable.height, 424d6c0b56eSmrg 0, 0, 0, NULL); 425d6c0b56eSmrg 426d6c0b56eSmrg return TRUE; 427d6c0b56eSmrg} 428d6c0b56eSmrg 429d6c0b56eSmrg 430d6c0b56eSmrgBool amdgpu_glamor_init(ScreenPtr screen) 431d6c0b56eSmrg{ 432d6c0b56eSmrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 433d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(scrn); 434d6c0b56eSmrg#ifdef RENDER 435d6c0b56eSmrg#ifdef HAVE_FBGLYPHS 436d6c0b56eSmrg UnrealizeGlyphProcPtr SavedUnrealizeGlyph = NULL; 437d6c0b56eSmrg#endif 438d6c0b56eSmrg PictureScreenPtr ps = NULL; 439d6c0b56eSmrg 440d6c0b56eSmrg if (info->shadow_primary) { 441d6c0b56eSmrg ps = GetPictureScreenIfSet(screen); 442d6c0b56eSmrg 443d6c0b56eSmrg if (ps) { 444d6c0b56eSmrg#ifdef HAVE_FBGLYPHS 445d6c0b56eSmrg SavedUnrealizeGlyph = ps->UnrealizeGlyph; 446d6c0b56eSmrg#endif 447d6c0b56eSmrg info->glamor.SavedGlyphs = ps->Glyphs; 448d6c0b56eSmrg info->glamor.SavedTriangles = ps->Triangles; 449d6c0b56eSmrg info->glamor.SavedTrapezoids = ps->Trapezoids; 450d6c0b56eSmrg } 451d6c0b56eSmrg } 452d6c0b56eSmrg#endif /* RENDER */ 453d6c0b56eSmrg 454d6c0b56eSmrg if (!glamor_init(screen, GLAMOR_USE_EGL_SCREEN | GLAMOR_USE_SCREEN | 455d6c0b56eSmrg GLAMOR_USE_PICTURE_SCREEN | GLAMOR_INVERTED_Y_AXIS | 456d6c0b56eSmrg GLAMOR_NO_DRI3)) { 457d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_ERROR, 458d6c0b56eSmrg "Failed to initialize glamor.\n"); 459d6c0b56eSmrg return FALSE; 460d6c0b56eSmrg } 461d6c0b56eSmrg 462d6c0b56eSmrg if (!glamor_egl_init_textured_pixmap(screen)) { 463d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_ERROR, 464d6c0b56eSmrg "Failed to initialize textured pixmap of screen for glamor.\n"); 465d6c0b56eSmrg return FALSE; 466d6c0b56eSmrg } 467d6c0b56eSmrg if (!dixRegisterPrivateKey(&amdgpu_pixmap_index, PRIVATE_PIXMAP, 0)) 468d6c0b56eSmrg return FALSE; 469d6c0b56eSmrg 470d6c0b56eSmrg if (info->shadow_primary) 471d6c0b56eSmrg amdgpu_glamor_screen_init(screen); 472d6c0b56eSmrg 473d6c0b56eSmrg#if defined(RENDER) && defined(HAVE_FBGLYPHS) 474d6c0b56eSmrg /* For ShadowPrimary, we need fbUnrealizeGlyph instead of 475d6c0b56eSmrg * glamor_unrealize_glyph 476d6c0b56eSmrg */ 477d6c0b56eSmrg if (ps) 478d6c0b56eSmrg ps->UnrealizeGlyph = SavedUnrealizeGlyph; 479d6c0b56eSmrg#endif 480d6c0b56eSmrg 481d6c0b56eSmrg info->glamor.SavedCreatePixmap = screen->CreatePixmap; 482d6c0b56eSmrg screen->CreatePixmap = amdgpu_glamor_create_pixmap; 483d6c0b56eSmrg info->glamor.SavedDestroyPixmap = screen->DestroyPixmap; 484d6c0b56eSmrg screen->DestroyPixmap = amdgpu_glamor_destroy_pixmap; 485d6c0b56eSmrg info->glamor.SavedSharePixmapBacking = screen->SharePixmapBacking; 486d6c0b56eSmrg screen->SharePixmapBacking = amdgpu_glamor_share_pixmap_backing; 487d6c0b56eSmrg info->glamor.SavedSetSharedPixmapBacking = screen->SetSharedPixmapBacking; 488d6c0b56eSmrg screen->SetSharedPixmapBacking = 489d6c0b56eSmrg amdgpu_glamor_set_shared_pixmap_backing; 490d6c0b56eSmrg 491d6c0b56eSmrg xf86DrvMsg(scrn->scrnIndex, X_INFO, "Use GLAMOR acceleration.\n"); 492d6c0b56eSmrg return TRUE; 493d6c0b56eSmrg} 494d6c0b56eSmrg 495d6c0b56eSmrgvoid amdgpu_glamor_flush(ScrnInfoPtr pScrn) 496d6c0b56eSmrg{ 497d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 498d6c0b56eSmrg 499d6c0b56eSmrg if (info->use_glamor) { 500d6c0b56eSmrg glamor_block_handler(pScrn->pScreen); 501d6c0b56eSmrg } 502504d986fSmrg 503504d986fSmrg info->gpu_flushed++; 504d6c0b56eSmrg} 505d6c0b56eSmrg 506d6c0b56eSmrgvoid amdgpu_glamor_finish(ScrnInfoPtr pScrn) 507d6c0b56eSmrg{ 508d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 509d6c0b56eSmrg 510d6c0b56eSmrg if (info->use_glamor) { 51111bf0794Smrg#if HAVE_GLAMOR_FINISH 51211bf0794Smrg glamor_finish(pScrn->pScreen); 51311bf0794Smrg info->gpu_flushed++; 51411bf0794Smrg#else 515d6c0b56eSmrg amdgpu_glamor_flush(pScrn); 516d6c0b56eSmrg glFinish(); 51711bf0794Smrg#endif 518d6c0b56eSmrg } 519d6c0b56eSmrg} 520d6c0b56eSmrg 521d6c0b56eSmrgvoid 522d6c0b56eSmrgamdgpu_glamor_fini(ScreenPtr screen) 523d6c0b56eSmrg{ 524d6c0b56eSmrg AMDGPUInfoPtr info = AMDGPUPTR(xf86ScreenToScrn(screen)); 525d6c0b56eSmrg 526d6c0b56eSmrg if (!info->use_glamor) 527d6c0b56eSmrg return; 528d6c0b56eSmrg 529d6c0b56eSmrg screen->CreatePixmap = info->glamor.SavedCreatePixmap; 530d6c0b56eSmrg screen->DestroyPixmap = info->glamor.SavedDestroyPixmap; 531d6c0b56eSmrg screen->SharePixmapBacking = info->glamor.SavedSharePixmapBacking; 532d6c0b56eSmrg screen->SetSharedPixmapBacking = info->glamor.SavedSetSharedPixmapBacking; 533d6c0b56eSmrg} 534d6c0b56eSmrg 535d6c0b56eSmrgXF86VideoAdaptorPtr amdgpu_glamor_xv_init(ScreenPtr pScreen, int num_adapt) 536d6c0b56eSmrg{ 537d6c0b56eSmrg return glamor_xv_init(pScreen, num_adapt); 538d6c0b56eSmrg} 53990f2b693Smrg 54090f2b693Smrg#endif /* USE_GLAMOR */ 541