1fa225cbcSrjs/************************************************************************** 2fa225cbcSrjs 3fa225cbcSrjsCopyright 2001 VA Linux Systems Inc., Fremont, California. 4fa225cbcSrjsCopyright © 2002 by David Dawes 5fa225cbcSrjs 6fa225cbcSrjsAll Rights Reserved. 7fa225cbcSrjs 8fa225cbcSrjsPermission is hereby granted, free of charge, to any person obtaining a 9fa225cbcSrjscopy of this software and associated documentation files (the "Software"), 10fa225cbcSrjsto deal in the Software without restriction, including without limitation 11fa225cbcSrjson the rights to use, copy, modify, merge, publish, distribute, sub 12fa225cbcSrjslicense, and/or sell copies of the Software, and to permit persons to whom 13fa225cbcSrjsthe Software is furnished to do so, subject to the following conditions: 14fa225cbcSrjs 15fa225cbcSrjsThe above copyright notice and this permission notice (including the next 16fa225cbcSrjsparagraph) shall be included in all copies or substantial portions of the 17fa225cbcSrjsSoftware. 18fa225cbcSrjs 19fa225cbcSrjsTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20fa225cbcSrjsIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21fa225cbcSrjsFITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22fa225cbcSrjsATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 23fa225cbcSrjsDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24fa225cbcSrjsOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 25fa225cbcSrjsUSE OR OTHER DEALINGS IN THE SOFTWARE. 26fa225cbcSrjs 27fa225cbcSrjs**************************************************************************/ 28fa225cbcSrjs 29fa225cbcSrjs/* 30fa225cbcSrjs * Authors: Jeff Hartmann <jhartmann@valinux.com> 31fa225cbcSrjs * David Dawes <dawes@xfree86.org> 32fa225cbcSrjs * Keith Whitwell <keith@tungstengraphics.com> 33fa225cbcSrjs */ 34fa225cbcSrjs 35fa225cbcSrjs#ifdef HAVE_CONFIG_H 36fa225cbcSrjs#include "config.h" 37fa225cbcSrjs#endif 38fa225cbcSrjs 39fa225cbcSrjs#include <stdio.h> 40fa225cbcSrjs#include <string.h> 41fa225cbcSrjs#include <assert.h> 42fa225cbcSrjs#include <sys/types.h> 43fa225cbcSrjs#include <sys/stat.h> 44fa225cbcSrjs#include <sys/ioctl.h> 45fa225cbcSrjs#include <errno.h> 46fa225cbcSrjs#include <unistd.h> 47fa225cbcSrjs#include <fcntl.h> 48fa225cbcSrjs 49fa225cbcSrjs#include "xf86.h" 50fa225cbcSrjs#include "xf86_OSproc.h" 51fa225cbcSrjs#include "xf86Priv.h" 52fa225cbcSrjs 53fa225cbcSrjs#include "xf86PciInfo.h" 54fa225cbcSrjs#include "xf86Pci.h" 55fa225cbcSrjs 56fa225cbcSrjs#include "windowstr.h" 57fa225cbcSrjs#include "shadow.h" 58fa225cbcSrjs 59fa225cbcSrjs#include "GL/glxtokens.h" 60fa225cbcSrjs 61fa225cbcSrjs#include "i830.h" 62fa225cbcSrjs#include "i830_dri.h" 63fa225cbcSrjs 64fa225cbcSrjs#include "i915_drm.h" 65fa225cbcSrjs 66fa225cbcSrjs#include "dri2.h" 67fa225cbcSrjs 68fa225cbcSrjs#ifdef DRI2 69fa225cbcSrjs#if DRI2INFOREC_VERSION >= 1 70fa225cbcSrjs#define USE_DRI2_1_1_0 71fa225cbcSrjs#endif 72fa225cbcSrjs 73fa225cbcSrjsextern XF86ModuleData dri2ModuleData; 74fa225cbcSrjs#endif 75fa225cbcSrjs 76fa225cbcSrjstypedef struct { 77fa225cbcSrjs PixmapPtr pPixmap; 78fa225cbcSrjs unsigned int attachment; 79fa225cbcSrjs} I830DRI2BufferPrivateRec, *I830DRI2BufferPrivatePtr; 80fa225cbcSrjs 81fa225cbcSrjs#ifndef USE_DRI2_1_1_0 82fa225cbcSrjsstatic DRI2BufferPtr 83fa225cbcSrjsI830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) 84fa225cbcSrjs{ 85fa225cbcSrjs ScreenPtr pScreen = pDraw->pScreen; 86fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 87fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 88fa225cbcSrjs DRI2BufferPtr buffers; 89fa225cbcSrjs dri_bo *bo; 90fa225cbcSrjs int i; 91fa225cbcSrjs I830DRI2BufferPrivatePtr privates; 92fa225cbcSrjs PixmapPtr pPixmap, pDepthPixmap; 93fa225cbcSrjs 94fa225cbcSrjs buffers = xcalloc(count, sizeof *buffers); 95fa225cbcSrjs if (buffers == NULL) 96fa225cbcSrjs return NULL; 97fa225cbcSrjs privates = xcalloc(count, sizeof *privates); 98fa225cbcSrjs if (privates == NULL) { 99fa225cbcSrjs xfree(buffers); 100fa225cbcSrjs return NULL; 101fa225cbcSrjs } 102fa225cbcSrjs 103fa225cbcSrjs pDepthPixmap = NULL; 104fa225cbcSrjs for (i = 0; i < count; i++) { 105fa225cbcSrjs if (attachments[i] == DRI2BufferFrontLeft) { 106fa225cbcSrjs pPixmap = get_drawable_pixmap(pDraw); 107fa225cbcSrjs pPixmap->refcnt++; 108fa225cbcSrjs } else if (attachments[i] == DRI2BufferStencil && pDepthPixmap) { 109fa225cbcSrjs pPixmap = pDepthPixmap; 110fa225cbcSrjs pPixmap->refcnt++; 111fa225cbcSrjs } else { 112fa225cbcSrjs unsigned int hint = 0; 113fa225cbcSrjs 114fa225cbcSrjs switch (attachments[i]) { 115fa225cbcSrjs case DRI2BufferDepth: 116fa225cbcSrjs if (SUPPORTS_YTILING(pI830)) 117fa225cbcSrjs hint = INTEL_CREATE_PIXMAP_TILING_Y; 118fa225cbcSrjs else 119fa225cbcSrjs hint = INTEL_CREATE_PIXMAP_TILING_X; 120fa225cbcSrjs break; 121fa225cbcSrjs case DRI2BufferFakeFrontLeft: 122fa225cbcSrjs case DRI2BufferFakeFrontRight: 123fa225cbcSrjs case DRI2BufferBackLeft: 124fa225cbcSrjs case DRI2BufferBackRight: 125fa225cbcSrjs hint = INTEL_CREATE_PIXMAP_TILING_X; 126fa225cbcSrjs break; 127fa225cbcSrjs } 128fa225cbcSrjs 129fa225cbcSrjs if (!pI830->tiling || 130fa225cbcSrjs (!IS_I965G(pI830) && !pI830->kernel_exec_fencing)) 131fa225cbcSrjs hint = 0; 132fa225cbcSrjs 133fa225cbcSrjs pPixmap = (*pScreen->CreatePixmap)(pScreen, 134fa225cbcSrjs pDraw->width, 135fa225cbcSrjs pDraw->height, 136fa225cbcSrjs pDraw->depth, 137fa225cbcSrjs hint); 138fa225cbcSrjs 139fa225cbcSrjs } 140fa225cbcSrjs 141fa225cbcSrjs if (attachments[i] == DRI2BufferDepth) 142fa225cbcSrjs pDepthPixmap = pPixmap; 143fa225cbcSrjs 144fa225cbcSrjs buffers[i].attachment = attachments[i]; 145fa225cbcSrjs buffers[i].pitch = pPixmap->devKind; 146fa225cbcSrjs buffers[i].cpp = pPixmap->drawable.bitsPerPixel / 8; 147fa225cbcSrjs buffers[i].driverPrivate = &privates[i]; 148fa225cbcSrjs buffers[i].flags = 0; /* not tiled */ 149fa225cbcSrjs privates[i].pPixmap = pPixmap; 150fa225cbcSrjs privates[i].attachment = attachments[i]; 151fa225cbcSrjs 152fa225cbcSrjs bo = i830_get_pixmap_bo (pPixmap); 153fa225cbcSrjs if (dri_bo_flink(bo, &buffers[i].name) != 0) { 154fa225cbcSrjs /* failed to name buffer */ 155fa225cbcSrjs } 156fa225cbcSrjs 157fa225cbcSrjs } 158fa225cbcSrjs 159fa225cbcSrjs return buffers; 160fa225cbcSrjs} 161fa225cbcSrjs 162fa225cbcSrjs#else 163fa225cbcSrjs 164fa225cbcSrjsstatic DRI2Buffer2Ptr 165fa225cbcSrjsI830DRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment, 166fa225cbcSrjs unsigned int format) 167fa225cbcSrjs{ 168fa225cbcSrjs ScreenPtr pScreen = pDraw->pScreen; 169fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 170fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 171fa225cbcSrjs DRI2Buffer2Ptr buffer; 172fa225cbcSrjs dri_bo *bo; 173fa225cbcSrjs I830DRI2BufferPrivatePtr privates; 174fa225cbcSrjs PixmapPtr pPixmap; 175fa225cbcSrjs 176fa225cbcSrjs buffer = xcalloc(1, sizeof *buffer); 177fa225cbcSrjs if (buffer == NULL) 178fa225cbcSrjs return NULL; 179fa225cbcSrjs privates = xcalloc(1, sizeof *privates); 180fa225cbcSrjs if (privates == NULL) { 181fa225cbcSrjs xfree(buffer); 182fa225cbcSrjs return NULL; 183fa225cbcSrjs } 184fa225cbcSrjs 185fa225cbcSrjs if (attachment == DRI2BufferFrontLeft) { 186fa225cbcSrjs pPixmap = get_drawable_pixmap(pDraw); 187fa225cbcSrjs pPixmap->refcnt++; 188fa225cbcSrjs } else { 189fa225cbcSrjs unsigned int hint = 0; 190fa225cbcSrjs 191fa225cbcSrjs switch (attachment) { 192fa225cbcSrjs case DRI2BufferDepth: 193fa225cbcSrjs case DRI2BufferDepthStencil: 194fa225cbcSrjs if (SUPPORTS_YTILING(pI830)) 195fa225cbcSrjs hint = INTEL_CREATE_PIXMAP_TILING_Y; 196fa225cbcSrjs else 197fa225cbcSrjs hint = INTEL_CREATE_PIXMAP_TILING_X; 198fa225cbcSrjs break; 199fa225cbcSrjs case DRI2BufferFakeFrontLeft: 200fa225cbcSrjs case DRI2BufferFakeFrontRight: 201fa225cbcSrjs case DRI2BufferBackLeft: 202fa225cbcSrjs case DRI2BufferBackRight: 203fa225cbcSrjs hint = INTEL_CREATE_PIXMAP_TILING_X; 204fa225cbcSrjs break; 205fa225cbcSrjs } 206fa225cbcSrjs 207fa225cbcSrjs if (!pI830->tiling || 208fa225cbcSrjs (!IS_I965G(pI830) && !pI830->kernel_exec_fencing)) 209fa225cbcSrjs hint = 0; 210fa225cbcSrjs 211fa225cbcSrjs pPixmap = (*pScreen->CreatePixmap)(pScreen, 212fa225cbcSrjs pDraw->width, 213fa225cbcSrjs pDraw->height, 214fa225cbcSrjs (format != 0)?format:pDraw->depth, 215fa225cbcSrjs hint); 216fa225cbcSrjs 217fa225cbcSrjs } 218fa225cbcSrjs 219fa225cbcSrjs 220fa225cbcSrjs buffer->attachment = attachment; 221fa225cbcSrjs buffer->pitch = pPixmap->devKind; 222fa225cbcSrjs buffer->cpp = pPixmap->drawable.bitsPerPixel / 8; 223fa225cbcSrjs buffer->driverPrivate = privates; 224fa225cbcSrjs buffer->format = format; 225fa225cbcSrjs buffer->flags = 0; /* not tiled */ 226fa225cbcSrjs privates->pPixmap = pPixmap; 227fa225cbcSrjs privates->attachment = attachment; 228fa225cbcSrjs 229fa225cbcSrjs bo = i830_get_pixmap_bo (pPixmap); 230fa225cbcSrjs if (dri_bo_flink(bo, &buffer->name) != 0) { 231fa225cbcSrjs /* failed to name buffer */ 232fa225cbcSrjs } 233fa225cbcSrjs 234fa225cbcSrjs return buffer; 235fa225cbcSrjs} 236fa225cbcSrjs 237fa225cbcSrjs#endif 238fa225cbcSrjs 239fa225cbcSrjs#ifndef USE_DRI2_1_1_0 240fa225cbcSrjs 241fa225cbcSrjsstatic void 242fa225cbcSrjsI830DRI2DestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) 243fa225cbcSrjs{ 244fa225cbcSrjs ScreenPtr pScreen = pDraw->pScreen; 245fa225cbcSrjs I830DRI2BufferPrivatePtr private; 246fa225cbcSrjs int i; 247fa225cbcSrjs 248fa225cbcSrjs for (i = 0; i < count; i++) 249fa225cbcSrjs { 250fa225cbcSrjs private = buffers[i].driverPrivate; 251fa225cbcSrjs (*pScreen->DestroyPixmap)(private->pPixmap); 252fa225cbcSrjs } 253fa225cbcSrjs 254fa225cbcSrjs if (buffers) 255fa225cbcSrjs { 256fa225cbcSrjs xfree(buffers[0].driverPrivate); 257fa225cbcSrjs xfree(buffers); 258fa225cbcSrjs } 259fa225cbcSrjs} 260fa225cbcSrjs 261fa225cbcSrjs#else 262fa225cbcSrjs 263fa225cbcSrjsstatic void 264fa225cbcSrjsI830DRI2DestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer) 265fa225cbcSrjs{ 266fa225cbcSrjs if (buffer) { 267fa225cbcSrjs I830DRI2BufferPrivatePtr private = buffer->driverPrivate; 268fa225cbcSrjs ScreenPtr pScreen = pDraw->pScreen; 269fa225cbcSrjs 270fa225cbcSrjs (*pScreen->DestroyPixmap)(private->pPixmap); 271fa225cbcSrjs 272fa225cbcSrjs xfree(private); 273fa225cbcSrjs xfree(buffer); 274fa225cbcSrjs } 275fa225cbcSrjs} 276fa225cbcSrjs 277fa225cbcSrjs#endif 278fa225cbcSrjs 279fa225cbcSrjsstatic void 280fa225cbcSrjsI830DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, 281fa225cbcSrjs DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer) 282fa225cbcSrjs{ 283fa225cbcSrjs I830DRI2BufferPrivatePtr srcPrivate = pSrcBuffer->driverPrivate; 284fa225cbcSrjs I830DRI2BufferPrivatePtr dstPrivate = pDstBuffer->driverPrivate; 285fa225cbcSrjs ScreenPtr pScreen = pDraw->pScreen; 286fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 287fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 288fa225cbcSrjs DrawablePtr src = (srcPrivate->attachment == DRI2BufferFrontLeft) 289fa225cbcSrjs ? pDraw : &srcPrivate->pPixmap->drawable; 290fa225cbcSrjs DrawablePtr dst = (dstPrivate->attachment == DRI2BufferFrontLeft) 291fa225cbcSrjs ? pDraw : &dstPrivate->pPixmap->drawable; 292fa225cbcSrjs RegionPtr pCopyClip; 293fa225cbcSrjs GCPtr pGC; 294fa225cbcSrjs 295fa225cbcSrjs pGC = GetScratchGC(pDraw->depth, pScreen); 296fa225cbcSrjs pCopyClip = REGION_CREATE(pScreen, NULL, 0); 297fa225cbcSrjs REGION_COPY(pScreen, pCopyClip, pRegion); 298fa225cbcSrjs (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pCopyClip, 0); 299fa225cbcSrjs ValidateGC(dst, pGC); 300fa225cbcSrjs 301fa225cbcSrjs /* Wait for the scanline to be outside the region to be copied */ 302fa225cbcSrjs if (pixmap_is_scanout(get_drawable_pixmap(dst)) && pI830->swapbuffers_wait) { 303fa225cbcSrjs BoxPtr box; 304fa225cbcSrjs BoxRec crtcbox; 305fa225cbcSrjs int y1, y2; 306fa225cbcSrjs int pipe = -1, event, load_scan_lines_pipe; 307fa225cbcSrjs xf86CrtcPtr crtc; 308fa225cbcSrjs 309fa225cbcSrjs box = REGION_EXTENTS(unused, pGC->pCompositeClip); 310fa225cbcSrjs crtc = i830_covering_crtc(pScrn, box, NULL, &crtcbox); 311fa225cbcSrjs 312fa225cbcSrjs /* Make sure the CRTC is valid and this is the real front buffer */ 313fa225cbcSrjs if (crtc != NULL && !crtc->rotatedData) { 314fa225cbcSrjs pipe = i830_crtc_to_pipe(crtc); 315fa225cbcSrjs 316fa225cbcSrjs if (pipe == 0) { 317fa225cbcSrjs event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW; 318fa225cbcSrjs load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA; 319fa225cbcSrjs } else { 320fa225cbcSrjs event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW; 321fa225cbcSrjs load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB; 322fa225cbcSrjs } 323fa225cbcSrjs 324fa225cbcSrjs /* Make sure we don't wait for a scanline that will never occur */ 325fa225cbcSrjs y1 = (crtcbox.y1 <= box->y1) ? box->y1 - crtcbox.y1 : 0; 326fa225cbcSrjs y2 = (box->y2 <= crtcbox.y2) ? 327fa225cbcSrjs box->y2 - crtcbox.y1 : crtcbox.y2 - crtcbox.y1; 328fa225cbcSrjs 329fa225cbcSrjs BEGIN_BATCH(5); 330fa225cbcSrjs /* The documentation says that the LOAD_SCAN_LINES command 331fa225cbcSrjs * always comes in pairs. Don't ask me why. */ 332fa225cbcSrjs OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe); 333fa225cbcSrjs OUT_BATCH((y1 << 16) | y2); 334fa225cbcSrjs OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe); 335fa225cbcSrjs OUT_BATCH((y1 << 16) | y2); 336fa225cbcSrjs OUT_BATCH(MI_WAIT_FOR_EVENT | event); 337fa225cbcSrjs ADVANCE_BATCH(); 338fa225cbcSrjs } 339fa225cbcSrjs } 340fa225cbcSrjs 341fa225cbcSrjs (*pGC->ops->CopyArea)(src, dst, 342fa225cbcSrjs pGC, 0, 0, pDraw->width, pDraw->height, 0, 0); 343fa225cbcSrjs FreeScratchGC(pGC); 344fa225cbcSrjs 345fa225cbcSrjs /* Emit a flush of the rendering cache, or on the 965 and beyond 346fa225cbcSrjs * rendering results may not hit the framebuffer until significantly 347fa225cbcSrjs * later. 348fa225cbcSrjs */ 349fa225cbcSrjs I830EmitFlush(pScrn); 350fa225cbcSrjs pI830->need_mi_flush = FALSE; 351fa225cbcSrjs 352fa225cbcSrjs /* We can't rely on getting into the block handler before the DRI 353fa225cbcSrjs * client gets to run again so flush now. */ 354fa225cbcSrjs intel_batch_flush(pScrn, TRUE); 355fa225cbcSrjs#if ALWAYS_SYNC 356fa225cbcSrjs I830Sync(pScrn); 357fa225cbcSrjs#endif 358fa225cbcSrjs drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_THROTTLE); 359fa225cbcSrjs 360fa225cbcSrjs} 361fa225cbcSrjs 362fa225cbcSrjsBool I830DRI2ScreenInit(ScreenPtr pScreen) 363fa225cbcSrjs{ 364fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 365fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 366fa225cbcSrjs DRI2InfoRec info; 367fa225cbcSrjs char *p; 368fa225cbcSrjs int i; 369fa225cbcSrjs struct stat sbuf; 370fa225cbcSrjs dev_t d; 371fa225cbcSrjs#ifdef USE_DRI2_1_1_0 372fa225cbcSrjs int dri2_major = 1; 373fa225cbcSrjs int dri2_minor = 0; 374fa225cbcSrjs#endif 375fa225cbcSrjs 376fa225cbcSrjs#ifdef USE_DRI2_1_1_0 377fa225cbcSrjs if (xf86LoaderCheckSymbol("DRI2Version")) { 378fa225cbcSrjs DRI2Version(& dri2_major, & dri2_minor); 379fa225cbcSrjs } 380fa225cbcSrjs 381fa225cbcSrjs if (dri2_minor < 1) { 382fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 383fa225cbcSrjs "DRI2 requires DRI2 module version 1.1.0 or later\n"); 384fa225cbcSrjs return FALSE; 385fa225cbcSrjs } 386fa225cbcSrjs#endif 387fa225cbcSrjs 388fa225cbcSrjs info.fd = pI830->drmSubFD; 389fa225cbcSrjs 390fa225cbcSrjs /* The whole drmOpen thing is a fiasco and we need to find a way 391fa225cbcSrjs * back to just using open(2). For now, however, lets just make 392fa225cbcSrjs * things worse with even more ad hoc directory walking code to 393fa225cbcSrjs * discover the device file name. */ 394fa225cbcSrjs 395fa225cbcSrjs fstat(info.fd, &sbuf); 396fa225cbcSrjs d = sbuf.st_rdev; 397fa225cbcSrjs 398fa225cbcSrjs p = pI830->deviceName; 399fa225cbcSrjs for (i = 0; i < DRM_MAX_MINOR; i++) { 400fa225cbcSrjs sprintf(p, DRM_DEV_NAME, DRM_DIR_NAME, i); 401fa225cbcSrjs if (stat(p, &sbuf) == 0 && sbuf.st_rdev == d) 402fa225cbcSrjs break; 403fa225cbcSrjs } 404fa225cbcSrjs if (i == DRM_MAX_MINOR) { 405fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 406fa225cbcSrjs "DRI2: failed to open drm device\n"); 407fa225cbcSrjs return FALSE; 408fa225cbcSrjs } 409fa225cbcSrjs 410fa225cbcSrjs info.driverName = IS_I965G(pI830) ? "i965" : "i915"; 411fa225cbcSrjs info.deviceName = p; 412fa225cbcSrjs 413fa225cbcSrjs#if DRI2INFOREC_VERSION >= 3 414fa225cbcSrjs info.version = 3; 415fa225cbcSrjs info.CreateBuffer = I830DRI2CreateBuffer; 416fa225cbcSrjs info.DestroyBuffer = I830DRI2DestroyBuffer; 417fa225cbcSrjs#else 418fa225cbcSrjs# ifdef USE_DRI2_1_1_0 419fa225cbcSrjs info.version = 2; 420fa225cbcSrjs info.CreateBuffers = NULL; 421fa225cbcSrjs info.DestroyBuffers = NULL; 422fa225cbcSrjs info.CreateBuffer = I830DRI2CreateBuffer; 423fa225cbcSrjs info.DestroyBuffer = I830DRI2DestroyBuffer; 424fa225cbcSrjs# else 425fa225cbcSrjs info.version = 1; 426fa225cbcSrjs info.CreateBuffers = I830DRI2CreateBuffers; 427fa225cbcSrjs info.DestroyBuffers = I830DRI2DestroyBuffers; 428fa225cbcSrjs# endif 429fa225cbcSrjs#endif 430fa225cbcSrjs 431fa225cbcSrjs info.CopyRegion = I830DRI2CopyRegion; 432fa225cbcSrjs 433fa225cbcSrjs return DRI2ScreenInit(pScreen, &info); 434fa225cbcSrjs} 435fa225cbcSrjs 436fa225cbcSrjsvoid I830DRI2CloseScreen(ScreenPtr pScreen) 437fa225cbcSrjs{ 438fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 439fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 440fa225cbcSrjs 441fa225cbcSrjs DRI2CloseScreen(pScreen); 442fa225cbcSrjs pI830->directRenderingType = DRI_NONE; 443fa225cbcSrjs} 444