13bfa90b6Smrg/* 23bfa90b6Smrg * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 33bfa90b6Smrg * Copyright 2011 VMWare, Inc. 43bfa90b6Smrg * All Rights Reserved. 53bfa90b6Smrg * 63bfa90b6Smrg * Permission is hereby granted, free of charge, to any person obtaining a 73bfa90b6Smrg * copy of this software and associated documentation files (the 83bfa90b6Smrg * "Software"), to deal in the Software without restriction, including 93bfa90b6Smrg * without limitation the rights to use, copy, modify, merge, publish, 103bfa90b6Smrg * distribute, sub license, and/or sell copies of the Software, and to 113bfa90b6Smrg * permit persons to whom the Software is furnished to do so, subject to 123bfa90b6Smrg * the following conditions: 133bfa90b6Smrg * 143bfa90b6Smrg * The above copyright notice and this permission notice (including the 153bfa90b6Smrg * next paragraph) shall be included in all copies or substantial portions 163bfa90b6Smrg * of the Software. 173bfa90b6Smrg * 183bfa90b6Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 193bfa90b6Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 203bfa90b6Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 213bfa90b6Smrg * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 223bfa90b6Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 233bfa90b6Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 243bfa90b6Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 253bfa90b6Smrg * 263bfa90b6Smrg * 273bfa90b6Smrg * Author: Alan Hourihane <alanh@tungstengraphics.com> 283bfa90b6Smrg * Author: Jakob Bornecrantz <wallbraker@gmail.com> 293bfa90b6Smrg * Author: Thomas Hellstrom <thellstrom@vmware.com> 303bfa90b6Smrg * 313bfa90b6Smrg */ 3234a0776dSmrg#ifdef HAVE_CONFIG_H 3334a0776dSmrg#include "config.h" 3434a0776dSmrg#endif 353bfa90b6Smrg 363bfa90b6Smrg#include "xorg-server.h" 373bfa90b6Smrg#include "xf86.h" 383bfa90b6Smrg#include "xf86_OSproc.h" 393bfa90b6Smrg 403bfa90b6Smrg#include "vmwgfx_driver.h" 413bfa90b6Smrg#include "../saa/saa.h" 423bfa90b6Smrg 433bfa90b6Smrg#include "dri2.h" 443bfa90b6Smrg#include "gcstruct.h" 453bfa90b6Smrg#include "gc.h" 463bfa90b6Smrg#include "vmwgfx_saa.h" 473bfa90b6Smrg#include "wsbm_util.h" 483bfa90b6Smrg#include <unistd.h> 4922f7e8e5Smrg#include "vmwgfx_hosted.h" 503bfa90b6Smrg 513bfa90b6Smrg#define VMWGFX_FD_PATH_LEN 80 523bfa90b6Smrg 533bfa90b6Smrgtypedef struct { 543bfa90b6Smrg int refcount; 553bfa90b6Smrg PixmapPtr pPixmap; 563bfa90b6Smrg struct xa_surface *srf; 573bfa90b6Smrg unsigned int dri2_depth; 583bfa90b6Smrg} *BufferPrivatePtr; 593bfa90b6Smrg 603bfa90b6Smrg 613bfa90b6Smrg/* 623bfa90b6Smrg * Attempt to guess what the dri state tracker is up to. 633bfa90b6Smrg * Currently it sends only bpp as format. 643bfa90b6Smrg */ 653bfa90b6Smrg 663bfa90b6Smrgstatic unsigned int 673bfa90b6Smrgvmwgfx_color_format_to_depth(unsigned int format) 683bfa90b6Smrg{ 693bfa90b6Smrg return format; 703bfa90b6Smrg} 713bfa90b6Smrg 723bfa90b6Smrgstatic unsigned int 733bfa90b6Smrgvmwgfx_zs_format_to_depth(unsigned int format) 743bfa90b6Smrg{ 753bfa90b6Smrg if (format == 24) 763bfa90b6Smrg return 32; 773bfa90b6Smrg return format; 783bfa90b6Smrg} 793bfa90b6Smrg 803bfa90b6Smrgstatic unsigned int 813bfa90b6Smrgvmwgfx_z_format_to_depth(unsigned int format) 823bfa90b6Smrg{ 833bfa90b6Smrg return format; 843bfa90b6Smrg} 853bfa90b6Smrg 863bfa90b6Smrgstatic Bool 873bfa90b6Smrgdri2_do_create_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer, unsigned int format) 883bfa90b6Smrg{ 893bfa90b6Smrg ScreenPtr pScreen = pDraw->pScreen; 903bfa90b6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 913bfa90b6Smrg modesettingPtr ms = modesettingPTR(pScrn); 923bfa90b6Smrg BufferPrivatePtr private = buffer->driverPrivate; 933bfa90b6Smrg PixmapPtr pPixmap; 943bfa90b6Smrg struct vmwgfx_saa_pixmap *vpix; 953bfa90b6Smrg struct xa_surface *srf = NULL; 963bfa90b6Smrg unsigned int depth; 973bfa90b6Smrg 983bfa90b6Smrg 993bfa90b6Smrg if (pDraw->type == DRAWABLE_PIXMAP) 1003bfa90b6Smrg pPixmap = (PixmapPtr) pDraw; 1013bfa90b6Smrg else 1023bfa90b6Smrg pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw); 1033bfa90b6Smrg 1043bfa90b6Smrg vpix = vmwgfx_saa_pixmap(pPixmap); 1053bfa90b6Smrg private->refcount = 0; 1063bfa90b6Smrg 1073bfa90b6Smrg switch (buffer->attachment) { 1083bfa90b6Smrg default: 1093bfa90b6Smrg depth = (format) ? vmwgfx_color_format_to_depth(format) : 1103bfa90b6Smrg pDraw->depth; 1113bfa90b6Smrg 1123bfa90b6Smrg if (buffer->attachment != DRI2BufferFakeFrontLeft || 1133bfa90b6Smrg &pPixmap->drawable != pDraw) { 1143bfa90b6Smrg 1153bfa90b6Smrg pPixmap = (*pScreen->CreatePixmap)(pScreen, 1163bfa90b6Smrg pDraw->width, 1173bfa90b6Smrg pDraw->height, 1183bfa90b6Smrg depth, 1193bfa90b6Smrg 0); 1203bfa90b6Smrg if (pPixmap == NullPixmap) 1213bfa90b6Smrg return FALSE; 1223bfa90b6Smrg 1233bfa90b6Smrg private->pPixmap = pPixmap; 1243bfa90b6Smrg private->dri2_depth = depth; 1253bfa90b6Smrg vpix = vmwgfx_saa_pixmap(pPixmap); 1263bfa90b6Smrg } 1273bfa90b6Smrg break; 1283bfa90b6Smrg case DRI2BufferFrontLeft: 1293bfa90b6Smrg if (&pPixmap->drawable == pDraw) 1303bfa90b6Smrg break; 1313bfa90b6Smrg buffer->name = 0; 1323bfa90b6Smrg buffer->pitch = 0; 1333bfa90b6Smrg buffer->cpp = pDraw->bitsPerPixel / 8; 1343bfa90b6Smrg buffer->driverPrivate = private; 1353bfa90b6Smrg buffer->flags = 0; /* not tiled */ 1363bfa90b6Smrg buffer->format = pDraw->bitsPerPixel; 1373bfa90b6Smrg if (!private->pPixmap) { 1383bfa90b6Smrg private->dri2_depth = 0; 1393bfa90b6Smrg private->pPixmap = pPixmap; 1403bfa90b6Smrg pPixmap->refcnt++; 1413bfa90b6Smrg } 1423bfa90b6Smrg return TRUE; 1433bfa90b6Smrg case DRI2BufferStencil: 1443bfa90b6Smrg case DRI2BufferDepthStencil: 14522f7e8e5Smrg if (!pScrn->vtSema) 14622f7e8e5Smrg return FALSE; 1473bfa90b6Smrg 1483bfa90b6Smrg depth = (format) ? vmwgfx_zs_format_to_depth(format) : 32; 1493bfa90b6Smrg 1503bfa90b6Smrg /* 1513bfa90b6Smrg * The SVGA device uses the zs ordering. 1523bfa90b6Smrg */ 1533bfa90b6Smrg 1543bfa90b6Smrg srf = xa_surface_create(ms->xat, pDraw->width, pDraw->height, 1553bfa90b6Smrg depth, xa_type_zs, xa_format_unknown, 1563bfa90b6Smrg XA_FLAG_SHARED ); 1573bfa90b6Smrg if (!srf) 1583bfa90b6Smrg return FALSE; 1593bfa90b6Smrg 1603bfa90b6Smrg private->dri2_depth = depth; 1613bfa90b6Smrg 1623bfa90b6Smrg break; 1633bfa90b6Smrg case DRI2BufferDepth: 16422f7e8e5Smrg if (!pScrn->vtSema) 16522f7e8e5Smrg return FALSE; 16622f7e8e5Smrg 1673bfa90b6Smrg depth = (format) ? vmwgfx_z_format_to_depth(format) : 1683bfa90b6Smrg pDraw->bitsPerPixel; 1693bfa90b6Smrg 1703bfa90b6Smrg if (depth == 24) 1713bfa90b6Smrg srf = xa_surface_create(ms->xat, pDraw->width, pDraw->height, 1723bfa90b6Smrg depth, xa_type_zs, xa_format_unknown, 1733bfa90b6Smrg XA_FLAG_SHARED ); 1743bfa90b6Smrg else 1753bfa90b6Smrg srf = xa_surface_create(ms->xat, pDraw->width, pDraw->height, 1763bfa90b6Smrg depth, 1773bfa90b6Smrg xa_type_z, xa_format_unknown, 1783bfa90b6Smrg XA_FLAG_SHARED); 1793bfa90b6Smrg if (!srf) 1803bfa90b6Smrg return FALSE; 1813bfa90b6Smrg 1823bfa90b6Smrg private->dri2_depth = depth; 1833bfa90b6Smrg 1843bfa90b6Smrg break; 1853bfa90b6Smrg } 1863bfa90b6Smrg 1873bfa90b6Smrg if (!private->pPixmap) { 1883bfa90b6Smrg private->pPixmap = pPixmap; 1893bfa90b6Smrg pPixmap->refcnt++; 1903bfa90b6Smrg } 1913bfa90b6Smrg 1923bfa90b6Smrg if (!srf) { 1933bfa90b6Smrg depth = (format) ? vmwgfx_color_format_to_depth(format) : 1943bfa90b6Smrg pDraw->depth; 1953bfa90b6Smrg 1963bfa90b6Smrg if (!vmwgfx_hw_dri2_validate(pPixmap, depth)) 1973bfa90b6Smrg return FALSE; 1983bfa90b6Smrg 1993bfa90b6Smrg srf = vpix->hw; 2003bfa90b6Smrg private->refcount++; 2013bfa90b6Smrg private->dri2_depth = depth; 2023bfa90b6Smrg 2033bfa90b6Smrg /* 2043bfa90b6Smrg * Compiz workaround. See vmwgfx_dirty(); 2053bfa90b6Smrg */ 2063bfa90b6Smrg 2073bfa90b6Smrg if (buffer->attachment == DRI2BufferFrontLeft || 2083bfa90b6Smrg buffer->attachment == DRI2BufferFakeFrontLeft) 2093bfa90b6Smrg vpix->hw_is_dri2_fronts++; 2103bfa90b6Smrg } 2113bfa90b6Smrg 2123bfa90b6Smrg private->srf = srf; 21322f7e8e5Smrg if (_xa_surface_handle(srf, &buffer->name, &buffer->pitch) != 0) 2143bfa90b6Smrg return FALSE; 2153bfa90b6Smrg 2163bfa90b6Smrg buffer->cpp = xa_format_depth(xa_surface_format(srf)) / 8; 2173bfa90b6Smrg buffer->driverPrivate = private; 2183bfa90b6Smrg buffer->flags = 0; /* not tiled */ 2193bfa90b6Smrg buffer->format = format; 2203bfa90b6Smrg private->refcount++; 2213bfa90b6Smrg 2223bfa90b6Smrg return TRUE; 2233bfa90b6Smrg} 2243bfa90b6Smrg 2253bfa90b6Smrgstatic void 2263bfa90b6Smrgdri2_do_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer) 2273bfa90b6Smrg{ 2283bfa90b6Smrg BufferPrivatePtr private = buffer->driverPrivate; 2293bfa90b6Smrg struct xa_surface *srf = private->srf; 2303bfa90b6Smrg ScreenPtr pScreen = pDraw->pScreen; 2313bfa90b6Smrg struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(private->pPixmap); 2323bfa90b6Smrg 2333bfa90b6Smrg if (--private->refcount == 0 && srf) { 2343bfa90b6Smrg xa_surface_destroy(srf); 2353bfa90b6Smrg } 2363bfa90b6Smrg 2373bfa90b6Smrg /* 2383bfa90b6Smrg * Compiz workaround. See vmwgfx_dirty(); 2393bfa90b6Smrg */ 2403bfa90b6Smrg 2413bfa90b6Smrg if ((buffer->attachment == DRI2BufferFrontLeft || 2423bfa90b6Smrg buffer->attachment == DRI2BufferFakeFrontLeft) && 2433bfa90b6Smrg private->refcount == 1 && 2443bfa90b6Smrg --vpix->hw_is_dri2_fronts == 0) 2453bfa90b6Smrg WSBMLISTDELINIT(&vpix->sync_x_head); 2463bfa90b6Smrg 2473bfa90b6Smrg private->srf = NULL; 2483bfa90b6Smrg pScreen->DestroyPixmap(private->pPixmap); 2493bfa90b6Smrg} 2503bfa90b6Smrg 2513bfa90b6Smrg 2523bfa90b6Smrgstatic DRI2Buffer2Ptr 2533bfa90b6Smrgdri2_create_buffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) 2543bfa90b6Smrg{ 2553bfa90b6Smrg DRI2Buffer2Ptr buffer; 2563bfa90b6Smrg BufferPrivatePtr private; 2573bfa90b6Smrg 2583bfa90b6Smrg buffer = calloc(1, sizeof *buffer); 2593bfa90b6Smrg if (!buffer) 2603bfa90b6Smrg return NULL; 2613bfa90b6Smrg 2623bfa90b6Smrg private = calloc(1, sizeof *private); 2633bfa90b6Smrg if (!private) { 2643bfa90b6Smrg goto fail; 2653bfa90b6Smrg } 2663bfa90b6Smrg 2673bfa90b6Smrg buffer->attachment = attachment; 2683bfa90b6Smrg buffer->driverPrivate = private; 2693bfa90b6Smrg 2703bfa90b6Smrg if (dri2_do_create_buffer(pDraw, buffer, format)) 2713bfa90b6Smrg return buffer; 2723bfa90b6Smrg 2733bfa90b6Smrg free(private); 2743bfa90b6Smrgfail: 2753bfa90b6Smrg free(buffer); 2763bfa90b6Smrg return NULL; 2773bfa90b6Smrg} 2783bfa90b6Smrg 2793bfa90b6Smrgstatic void 2803bfa90b6Smrgdri2_destroy_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer) 2813bfa90b6Smrg{ 2823bfa90b6Smrg /* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */ 2833bfa90b6Smrg dri2_do_destroy_buffer(pDraw, (DRI2BufferPtr)buffer); 2843bfa90b6Smrg 2853bfa90b6Smrg free(buffer->driverPrivate); 2863bfa90b6Smrg free(buffer); 2873bfa90b6Smrg} 2883bfa90b6Smrg 2893bfa90b6Smrgstatic void 2903bfa90b6Smrgdri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, 2913bfa90b6Smrg DRI2Buffer2Ptr pDestBuffer, DRI2Buffer2Ptr pSrcBuffer) 2923bfa90b6Smrg{ 2933bfa90b6Smrg 2943bfa90b6Smrg 2953bfa90b6Smrg ScreenPtr pScreen = pDraw->pScreen; 2963bfa90b6Smrg BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate; 2973bfa90b6Smrg BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate; 2983bfa90b6Smrg DrawablePtr src_draw; 2993bfa90b6Smrg DrawablePtr dst_draw; 3003bfa90b6Smrg RegionPtr myClip; 3013bfa90b6Smrg GCPtr gc; 30222f7e8e5Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 30322f7e8e5Smrg 30422f7e8e5Smrg /* 30522f7e8e5Smrg * This is a fragile protection against HW operations when not master. 30622f7e8e5Smrg * Needs to be blocked higher up in the dri2 code. 30722f7e8e5Smrg */ 30822f7e8e5Smrg if (!pScrn->vtSema) 30922f7e8e5Smrg return; 3103bfa90b6Smrg 3113bfa90b6Smrg /* 3123bfa90b6Smrg * In driCreateBuffers we dewrap windows into the 3133bfa90b6Smrg * backing pixmaps in order to get to the texture. 3143bfa90b6Smrg * We need to use the real drawable in CopyArea 3153bfa90b6Smrg * so that cliprects and offsets are correct. 3163bfa90b6Smrg */ 3173bfa90b6Smrg src_draw = (pSrcBuffer->attachment == DRI2BufferFrontLeft) ? pDraw : 3183bfa90b6Smrg &src_priv->pPixmap->drawable; 3193bfa90b6Smrg dst_draw = (pDestBuffer->attachment == DRI2BufferFrontLeft) ? pDraw : 3203bfa90b6Smrg &dst_priv->pPixmap->drawable; 3213bfa90b6Smrg 3223bfa90b6Smrg /* 3233bfa90b6Smrg * The clients implements glXWaitX with a copy front to fake and then 3243bfa90b6Smrg * waiting on the server to signal its completion of it. While 3253bfa90b6Smrg * glXWaitGL is a client side flush and a copy from fake to front. 3263bfa90b6Smrg * This is how it is done in the DRI2 protocol, how ever depending 3273bfa90b6Smrg * which type of drawables the server does things a bit differently 3283bfa90b6Smrg * then what the protocol says as the fake and front are the same. 3293bfa90b6Smrg * 3303bfa90b6Smrg * for pixmaps glXWaitX is a server flush. 3313bfa90b6Smrg * for pixmaps glXWaitGL is a client flush. 3323bfa90b6Smrg * for windows glXWaitX is a copy from front to fake then a server flush. 3333bfa90b6Smrg * for windows glXWaitGL is a client flush then a copy from fake to front. 3343bfa90b6Smrg * 3353bfa90b6Smrg * XXX in the windows case this code always flushes but that isn't a 3363bfa90b6Smrg * must in the glXWaitGL case but we don't know if this is a glXWaitGL 3373bfa90b6Smrg * or a glFlush/glFinish call. 3383bfa90b6Smrg */ 3393bfa90b6Smrg if (dst_priv->pPixmap == src_priv->pPixmap) { 3403bfa90b6Smrg /* pixmap glXWaitX */ 3413bfa90b6Smrg if (pSrcBuffer->attachment == DRI2BufferFrontLeft && 3423bfa90b6Smrg pDestBuffer->attachment == DRI2BufferFakeFrontLeft) { 3433bfa90b6Smrg 3443bfa90b6Smrg if (!vmwgfx_hw_dri2_validate(dst_priv->pPixmap, 3453bfa90b6Smrg dst_priv->dri2_depth)) 3463bfa90b6Smrg return; 3473bfa90b6Smrg } 3483bfa90b6Smrg /* pixmap glXWaitGL */ 3493bfa90b6Smrg if (pDestBuffer->attachment == DRI2BufferFrontLeft && 3503bfa90b6Smrg pSrcBuffer->attachment == DRI2BufferFakeFrontLeft) { 3513bfa90b6Smrg return; 3523bfa90b6Smrg } else { 3533bfa90b6Smrg vmwgfx_flush_dri2(pScreen); 3543bfa90b6Smrg return; 3553bfa90b6Smrg } 3563bfa90b6Smrg } 3573bfa90b6Smrg 3583bfa90b6Smrg gc = GetScratchGC(pDraw->depth, pScreen); 3593bfa90b6Smrg myClip = REGION_CREATE(pScreen, REGION_RECTS(pRegion), 3603bfa90b6Smrg REGION_NUM_RECTS(pRegion)); 3613bfa90b6Smrg (*gc->funcs->ChangeClip) (gc, CT_REGION, myClip, 0); 3623bfa90b6Smrg ValidateGC(dst_draw, gc); 3633bfa90b6Smrg 3643bfa90b6Smrg /* 3653bfa90b6Smrg * Damage the src drawable in order for damageCopyArea to pick up 3663bfa90b6Smrg * that something changed. 3673bfa90b6Smrg */ 3683bfa90b6Smrg DamageRegionAppend(src_draw, pRegion); 3693bfa90b6Smrg if (pSrcBuffer->attachment != DRI2BufferFrontLeft) 3703bfa90b6Smrg saa_drawable_dirty(src_draw, TRUE, pRegion); 3713bfa90b6Smrg DamageRegionProcessPending(src_draw); 3723bfa90b6Smrg 3733bfa90b6Smrg /* 3743bfa90b6Smrg * Call CopyArea. This usually means a call to damageCopyArea that 3753bfa90b6Smrg * is wrapping saa_copy_area. The damageCopyArea function will make 3763bfa90b6Smrg * sure the destination drawable is appropriately damaged. 3773bfa90b6Smrg */ 3783bfa90b6Smrg (*gc->ops->CopyArea)(src_draw, dst_draw, gc, 3793bfa90b6Smrg 0, 0, pDraw->width, pDraw->height, 0, 0); 3803bfa90b6Smrg 3813bfa90b6Smrg /* 3823bfa90b6Smrg * FreeScratchGC will free myClip as well. 3833bfa90b6Smrg */ 3843bfa90b6Smrg myClip = NULL; 3853bfa90b6Smrg FreeScratchGC(gc); 3863bfa90b6Smrg} 3873bfa90b6Smrg 38822f7e8e5Smrg#if (DRI2INFOREC_VERSION >= 8 && DRI2INFOREC_VERSION < 10) 38922f7e8e5Smrgstatic int vmw_dri_auth_magic2(ScreenPtr pScreen, uint32_t magic) 39022f7e8e5Smrg{ 39122f7e8e5Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 39222f7e8e5Smrg modesettingPtr ms = modesettingPTR(pScrn); 39322f7e8e5Smrg 39422f7e8e5Smrg return vmwgfx_hosted_dri_auth(ms->hdriver, ms->hosted, NULL, magic); 39522f7e8e5Smrg} 39622f7e8e5Smrg#endif 39722f7e8e5Smrg 39822f7e8e5Smrg#if (DRI2INFOREC_VERSION >= 10) 39922f7e8e5Smrgstatic int vmw_dri_auth_magic3(ClientPtr client, ScreenPtr pScreen, 40022f7e8e5Smrg uint32_t magic) 40122f7e8e5Smrg{ 40222f7e8e5Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 40322f7e8e5Smrg modesettingPtr ms = modesettingPTR(pScrn); 40422f7e8e5Smrg 40522f7e8e5Smrg return vmwgfx_hosted_dri_auth(ms->hdriver, ms->hosted, client, magic); 40622f7e8e5Smrg} 40722f7e8e5Smrg#endif 40822f7e8e5Smrg 4093bfa90b6SmrgBool 4103bfa90b6Smrgxorg_dri2_init(ScreenPtr pScreen) 4113bfa90b6Smrg{ 4123bfa90b6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 4133bfa90b6Smrg modesettingPtr ms = modesettingPTR(pScrn); 4143bfa90b6Smrg DRI2InfoRec dri2info; 4153bfa90b6Smrg int major, minor; 4163bfa90b6Smrg 41722f7e8e5Smrg memset(&dri2info, 0, sizeof(dri2info)); 41822f7e8e5Smrg 4193bfa90b6Smrg if (xf86LoaderCheckSymbol("DRI2Version")) { 4203bfa90b6Smrg DRI2Version(&major, &minor); 4213bfa90b6Smrg } else { 4223bfa90b6Smrg /* Assume version 1.0 */ 4233bfa90b6Smrg major = 1; 4243bfa90b6Smrg minor = 0; 4253bfa90b6Smrg } 4263bfa90b6Smrg 4273bfa90b6Smrg dri2info.version = min(DRI2INFOREC_VERSION, 3); 4283bfa90b6Smrg dri2info.fd = ms->fd; 4293bfa90b6Smrg dri2info.driverName = "vmwgfx"; 4303bfa90b6Smrg 43125dbecb6Smrg#ifdef VMWGFX_LIBDRM_DEVICENAME 43225dbecb6Smrg ms->dri2_device_name = drmGetDeviceNameFromFd2(ms->fd); 43325dbecb6Smrg 43425dbecb6Smrg if (!ms->dri2_device_name) { 4353bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4363bfa90b6Smrg "Could not find the drm device name. Disabling dri2.\n"); 4373bfa90b6Smrg return FALSE; 4383bfa90b6Smrg } 43925dbecb6Smrg#else 44025dbecb6Smrg /* 44125dbecb6Smrg * This way of obtaining the DRM device name is a bit 44225dbecb6Smrg * os-specific. Currently this works only for Linux. 44325dbecb6Smrg */ 44425dbecb6Smrg { 44525dbecb6Smrg char fdPath[VMWGFX_FD_PATH_LEN]; 44625dbecb6Smrg ssize_t numChar; 44725dbecb6Smrg 44825dbecb6Smrg memset(fdPath, 0, VMWGFX_FD_PATH_LEN); 44925dbecb6Smrg snprintf(fdPath, VMWGFX_FD_PATH_LEN - 1, "/proc/self/fd/%d", ms->fd); 45025dbecb6Smrg numChar = readlink(fdPath, ms->dri2_device_name, VMWGFX_DRI_DEVICE_LEN); 45125dbecb6Smrg if (numChar <= 0 || numChar >= VMWGFX_DRI_DEVICE_LEN) { 45225dbecb6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 45325dbecb6Smrg "Could not find the drm device name. Disabling dri2.\n"); 45425dbecb6Smrg return FALSE; 45525dbecb6Smrg } 45625dbecb6Smrg ms->dri2_device_name[numChar] = 0; 45725dbecb6Smrg } 45825dbecb6Smrg#endif 4593bfa90b6Smrg dri2info.deviceName = ms->dri2_device_name; 4603bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4613bfa90b6Smrg "Path of drm device is \"%s\".\n", ms->dri2_device_name); 4623bfa90b6Smrg 4633bfa90b6Smrg dri2info.CreateBuffer = dri2_create_buffer; 4643bfa90b6Smrg dri2info.DestroyBuffer = dri2_destroy_buffer; 4653bfa90b6Smrg 4663bfa90b6Smrg dri2info.CopyRegion = dri2_copy_region; 4673bfa90b6Smrg dri2info.Wait = NULL; 4683bfa90b6Smrg 46922f7e8e5Smrg#if (DRI2INFOREC_VERSION >= 8 && DRI2INFOREC_VERSION < 10) 47022f7e8e5Smrg if (vmwgfx_is_hosted(ms->hdriver)) { 47122f7e8e5Smrg dri2info.version = 8; 47222f7e8e5Smrg dri2info.AuthMagic2 = vmw_dri_auth_magic2; 47322f7e8e5Smrg } 47422f7e8e5Smrg#endif 47522f7e8e5Smrg#if (DRI2INFOREC_VERSION >= 10) 47622f7e8e5Smrg if (vmwgfx_is_hosted(ms->hdriver)) { 47722f7e8e5Smrg dri2info.version = 10; 47822f7e8e5Smrg dri2info.AuthMagic3 = vmw_dri_auth_magic3; 47922f7e8e5Smrg } 48022f7e8e5Smrg#endif 48122f7e8e5Smrg 4823bfa90b6Smrg return DRI2ScreenInit(pScreen, &dri2info); 4833bfa90b6Smrg} 4843bfa90b6Smrg 4853bfa90b6Smrgvoid 4863bfa90b6Smrgxorg_dri2_close(ScreenPtr pScreen) 4873bfa90b6Smrg{ 48825dbecb6Smrg#ifdef VMWGFX_LIBDRM_DEVICENAME 48925dbecb6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 49025dbecb6Smrg modesettingPtr ms = modesettingPTR(pScrn); 49125dbecb6Smrg 49225dbecb6Smrg free(ms->dri2_device_name); 49325dbecb6Smrg#endif 49425dbecb6Smrg 4953bfa90b6Smrg DRI2CloseScreen(pScreen); 4963bfa90b6Smrg} 4973bfa90b6Smrg 4983bfa90b6Smrg/* vim: set sw=4 ts=8 sts=4: */ 499