dri2.c revision cdc920a0
1cdc920a0Smrg/* 2cdc920a0Smrg * Copyright © 2008 Red Hat, Inc. 3cdc920a0Smrg * 4cdc920a0Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5cdc920a0Smrg * copy of this software and associated documentation files (the "Soft- 6cdc920a0Smrg * ware"), to deal in the Software without restriction, including without 7cdc920a0Smrg * limitation the rights to use, copy, modify, merge, publish, distribute, 8cdc920a0Smrg * and/or sell copies of the Software, and to permit persons to whom the 9cdc920a0Smrg * Software is furnished to do so, provided that the above copyright 10cdc920a0Smrg * notice(s) and this permission notice appear in all copies of the Soft- 11cdc920a0Smrg * ware and that both the above copyright notice(s) and this permission 12cdc920a0Smrg * notice appear in supporting documentation. 13cdc920a0Smrg * 14cdc920a0Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15cdc920a0Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- 16cdc920a0Smrg * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY 17cdc920a0Smrg * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN 18cdc920a0Smrg * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- 19cdc920a0Smrg * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20cdc920a0Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21cdc920a0Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- 22cdc920a0Smrg * MANCE OF THIS SOFTWARE. 23cdc920a0Smrg * 24cdc920a0Smrg * Except as contained in this notice, the name of a copyright holder shall 25cdc920a0Smrg * not be used in advertising or otherwise to promote the sale, use or 26cdc920a0Smrg * other dealings in this Software without prior written authorization of 27cdc920a0Smrg * the copyright holder. 28cdc920a0Smrg * 29cdc920a0Smrg * Authors: 30cdc920a0Smrg * Kristian Høgsberg (krh@redhat.com) 31cdc920a0Smrg */ 32cdc920a0Smrg 33cdc920a0Smrg 34cdc920a0Smrg#ifdef GLX_DIRECT_RENDERING 35cdc920a0Smrg 36cdc920a0Smrg#define NEED_REPLIES 37cdc920a0Smrg#include <stdio.h> 38cdc920a0Smrg#include <X11/Xlibint.h> 39cdc920a0Smrg#include <X11/extensions/Xext.h> 40cdc920a0Smrg#include <X11/extensions/extutil.h> 41cdc920a0Smrg#include <X11/extensions/dri2proto.h> 42cdc920a0Smrg#include "xf86drm.h" 43cdc920a0Smrg#include "dri2.h" 44cdc920a0Smrg#include "glxclient.h" 45cdc920a0Smrg#include "GL/glxext.h" 46cdc920a0Smrg 47cdc920a0Smrg/* Allow the build to work with an older versions of dri2proto.h and 48cdc920a0Smrg * dri2tokens.h. 49cdc920a0Smrg */ 50cdc920a0Smrg#if DRI2_MINOR < 1 51cdc920a0Smrg#undef DRI2_MINOR 52cdc920a0Smrg#define DRI2_MINOR 1 53cdc920a0Smrg#define X_DRI2GetBuffersWithFormat 7 54cdc920a0Smrg#endif 55cdc920a0Smrg 56cdc920a0Smrg 57cdc920a0Smrgstatic char dri2ExtensionName[] = DRI2_NAME; 58cdc920a0Smrgstatic XExtensionInfo *dri2Info; 59cdc920a0Smrgstatic XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) 60cdc920a0Smrg 61cdc920a0Smrgstatic Bool 62cdc920a0SmrgDRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire); 63cdc920a0Smrgstatic Status 64cdc920a0SmrgDRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire); 65cdc920a0Smrgstatic int 66cdc920a0SmrgDRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code); 67cdc920a0Smrg 68cdc920a0Smrgstatic /* const */ XExtensionHooks dri2ExtensionHooks = { 69cdc920a0Smrg NULL, /* create_gc */ 70cdc920a0Smrg NULL, /* copy_gc */ 71cdc920a0Smrg NULL, /* flush_gc */ 72cdc920a0Smrg NULL, /* free_gc */ 73cdc920a0Smrg NULL, /* create_font */ 74cdc920a0Smrg NULL, /* free_font */ 75cdc920a0Smrg DRI2CloseDisplay, /* close_display */ 76cdc920a0Smrg DRI2WireToEvent, /* wire_to_event */ 77cdc920a0Smrg DRI2EventToWire, /* event_to_wire */ 78cdc920a0Smrg DRI2Error, /* error */ 79cdc920a0Smrg NULL, /* error_string */ 80cdc920a0Smrg}; 81cdc920a0Smrg 82cdc920a0Smrgstatic XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, 83cdc920a0Smrg dri2Info, 84cdc920a0Smrg dri2ExtensionName, 85cdc920a0Smrg &dri2ExtensionHooks, 86cdc920a0Smrg 0, NULL) 87cdc920a0Smrg 88cdc920a0Smrgstatic Bool 89cdc920a0SmrgDRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) 90cdc920a0Smrg{ 91cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 92cdc920a0Smrg XExtDisplayInfo *glx_info = __glXFindDisplay(dpy); 93cdc920a0Smrg 94cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 95cdc920a0Smrg 96cdc920a0Smrg switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { 97cdc920a0Smrg 98cdc920a0Smrg#ifdef X_DRI2SwapBuffers 99cdc920a0Smrg case DRI2_BufferSwapComplete: 100cdc920a0Smrg { 101cdc920a0Smrg GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; 102cdc920a0Smrg xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire; 103cdc920a0Smrg aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); 104cdc920a0Smrg aevent->type = glx_info->codes->first_event + GLX_BufferSwapComplete; 105cdc920a0Smrg aevent->send_event = (awire->type & 0x80) != 0; 106cdc920a0Smrg aevent->display = dpy; 107cdc920a0Smrg aevent->drawable = awire->drawable; 108cdc920a0Smrg switch (awire->event_type) { 109cdc920a0Smrg case DRI2_EXCHANGE_COMPLETE: 110cdc920a0Smrg aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL; 111cdc920a0Smrg break; 112cdc920a0Smrg case DRI2_BLIT_COMPLETE: 113cdc920a0Smrg aevent->event_type = GLX_COPY_COMPLETE_INTEL; 114cdc920a0Smrg break; 115cdc920a0Smrg case DRI2_FLIP_COMPLETE: 116cdc920a0Smrg aevent->event_type = GLX_FLIP_COMPLETE_INTEL; 117cdc920a0Smrg break; 118cdc920a0Smrg default: 119cdc920a0Smrg /* unknown swap completion type */ 120cdc920a0Smrg return False; 121cdc920a0Smrg } 122cdc920a0Smrg aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; 123cdc920a0Smrg aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; 124cdc920a0Smrg aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo; 125cdc920a0Smrg return True; 126cdc920a0Smrg } 127cdc920a0Smrg#endif 128cdc920a0Smrg#ifdef DRI2_InvalidateBuffers 129cdc920a0Smrg case DRI2_InvalidateBuffers: 130cdc920a0Smrg { 131cdc920a0Smrg xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire; 132cdc920a0Smrg 133cdc920a0Smrg dri2InvalidateBuffers(dpy, awire->drawable); 134cdc920a0Smrg return False; 135cdc920a0Smrg } 136cdc920a0Smrg#endif 137cdc920a0Smrg default: 138cdc920a0Smrg /* client doesn't support server event */ 139cdc920a0Smrg break; 140cdc920a0Smrg } 141cdc920a0Smrg 142cdc920a0Smrg return False; 143cdc920a0Smrg} 144cdc920a0Smrg 145cdc920a0Smrg/* We don't actually support this. It doesn't make sense for clients to 146cdc920a0Smrg * send each other DRI2 events. 147cdc920a0Smrg */ 148cdc920a0Smrgstatic Status 149cdc920a0SmrgDRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire) 150cdc920a0Smrg{ 151cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 152cdc920a0Smrg 153cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 154cdc920a0Smrg 155cdc920a0Smrg switch (event->type) { 156cdc920a0Smrg default: 157cdc920a0Smrg /* client doesn't support server event */ 158cdc920a0Smrg break; 159cdc920a0Smrg } 160cdc920a0Smrg 161cdc920a0Smrg return Success; 162cdc920a0Smrg} 163cdc920a0Smrg 164cdc920a0Smrgstatic int 165cdc920a0SmrgDRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code) 166cdc920a0Smrg{ 167cdc920a0Smrg if (err->majorCode == codes->major_opcode && 168cdc920a0Smrg err->errorCode == BadDrawable && 169cdc920a0Smrg err->minorCode == X_DRI2CopyRegion) 170cdc920a0Smrg return True; 171cdc920a0Smrg 172cdc920a0Smrg return False; 173cdc920a0Smrg} 174cdc920a0Smrg 175cdc920a0SmrgBool 176cdc920a0SmrgDRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) 177cdc920a0Smrg{ 178cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 179cdc920a0Smrg 180cdc920a0Smrg if (XextHasExtension(info)) { 181cdc920a0Smrg *eventBase = info->codes->first_event; 182cdc920a0Smrg *errorBase = info->codes->first_error; 183cdc920a0Smrg return True; 184cdc920a0Smrg } 185cdc920a0Smrg 186cdc920a0Smrg return False; 187cdc920a0Smrg} 188cdc920a0Smrg 189cdc920a0SmrgBool 190cdc920a0SmrgDRI2QueryVersion(Display * dpy, int *major, int *minor) 191cdc920a0Smrg{ 192cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 193cdc920a0Smrg xDRI2QueryVersionReply rep; 194cdc920a0Smrg xDRI2QueryVersionReq *req; 195cdc920a0Smrg int i, nevents; 196cdc920a0Smrg 197cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 198cdc920a0Smrg 199cdc920a0Smrg LockDisplay(dpy); 200cdc920a0Smrg GetReq(DRI2QueryVersion, req); 201cdc920a0Smrg req->reqType = info->codes->major_opcode; 202cdc920a0Smrg req->dri2ReqType = X_DRI2QueryVersion; 203cdc920a0Smrg req->majorVersion = DRI2_MAJOR; 204cdc920a0Smrg req->minorVersion = DRI2_MINOR; 205cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 206cdc920a0Smrg UnlockDisplay(dpy); 207cdc920a0Smrg SyncHandle(); 208cdc920a0Smrg return False; 209cdc920a0Smrg } 210cdc920a0Smrg *major = rep.majorVersion; 211cdc920a0Smrg *minor = rep.minorVersion; 212cdc920a0Smrg UnlockDisplay(dpy); 213cdc920a0Smrg SyncHandle(); 214cdc920a0Smrg 215cdc920a0Smrg switch (rep.minorVersion) { 216cdc920a0Smrg case 1: 217cdc920a0Smrg nevents = 0; 218cdc920a0Smrg break; 219cdc920a0Smrg case 2: 220cdc920a0Smrg nevents = 1; 221cdc920a0Smrg break; 222cdc920a0Smrg case 3: 223cdc920a0Smrg default: 224cdc920a0Smrg nevents = 2; 225cdc920a0Smrg break; 226cdc920a0Smrg } 227cdc920a0Smrg 228cdc920a0Smrg for (i = 0; i < nevents; i++) { 229cdc920a0Smrg XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent); 230cdc920a0Smrg XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire); 231cdc920a0Smrg } 232cdc920a0Smrg 233cdc920a0Smrg return True; 234cdc920a0Smrg} 235cdc920a0Smrg 236cdc920a0SmrgBool 237cdc920a0SmrgDRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName) 238cdc920a0Smrg{ 239cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 240cdc920a0Smrg xDRI2ConnectReply rep; 241cdc920a0Smrg xDRI2ConnectReq *req; 242cdc920a0Smrg 243cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 244cdc920a0Smrg 245cdc920a0Smrg LockDisplay(dpy); 246cdc920a0Smrg GetReq(DRI2Connect, req); 247cdc920a0Smrg req->reqType = info->codes->major_opcode; 248cdc920a0Smrg req->dri2ReqType = X_DRI2Connect; 249cdc920a0Smrg req->window = window; 250cdc920a0Smrg req->driverType = DRI2DriverDRI; 251cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 252cdc920a0Smrg UnlockDisplay(dpy); 253cdc920a0Smrg SyncHandle(); 254cdc920a0Smrg return False; 255cdc920a0Smrg } 256cdc920a0Smrg 257cdc920a0Smrg if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) { 258cdc920a0Smrg UnlockDisplay(dpy); 259cdc920a0Smrg SyncHandle(); 260cdc920a0Smrg return False; 261cdc920a0Smrg } 262cdc920a0Smrg 263cdc920a0Smrg *driverName = Xmalloc(rep.driverNameLength + 1); 264cdc920a0Smrg if (*driverName == NULL) { 265cdc920a0Smrg _XEatData(dpy, 266cdc920a0Smrg ((rep.driverNameLength + 3) & ~3) + 267cdc920a0Smrg ((rep.deviceNameLength + 3) & ~3)); 268cdc920a0Smrg UnlockDisplay(dpy); 269cdc920a0Smrg SyncHandle(); 270cdc920a0Smrg return False; 271cdc920a0Smrg } 272cdc920a0Smrg _XReadPad(dpy, *driverName, rep.driverNameLength); 273cdc920a0Smrg (*driverName)[rep.driverNameLength] = '\0'; 274cdc920a0Smrg 275cdc920a0Smrg *deviceName = Xmalloc(rep.deviceNameLength + 1); 276cdc920a0Smrg if (*deviceName == NULL) { 277cdc920a0Smrg Xfree(*driverName); 278cdc920a0Smrg _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3)); 279cdc920a0Smrg UnlockDisplay(dpy); 280cdc920a0Smrg SyncHandle(); 281cdc920a0Smrg return False; 282cdc920a0Smrg } 283cdc920a0Smrg _XReadPad(dpy, *deviceName, rep.deviceNameLength); 284cdc920a0Smrg (*deviceName)[rep.deviceNameLength] = '\0'; 285cdc920a0Smrg 286cdc920a0Smrg UnlockDisplay(dpy); 287cdc920a0Smrg SyncHandle(); 288cdc920a0Smrg 289cdc920a0Smrg return True; 290cdc920a0Smrg} 291cdc920a0Smrg 292cdc920a0SmrgBool 293cdc920a0SmrgDRI2Authenticate(Display * dpy, XID window, drm_magic_t magic) 294cdc920a0Smrg{ 295cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 296cdc920a0Smrg xDRI2AuthenticateReq *req; 297cdc920a0Smrg xDRI2AuthenticateReply rep; 298cdc920a0Smrg 299cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 300cdc920a0Smrg 301cdc920a0Smrg LockDisplay(dpy); 302cdc920a0Smrg GetReq(DRI2Authenticate, req); 303cdc920a0Smrg req->reqType = info->codes->major_opcode; 304cdc920a0Smrg req->dri2ReqType = X_DRI2Authenticate; 305cdc920a0Smrg req->window = window; 306cdc920a0Smrg req->magic = magic; 307cdc920a0Smrg 308cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 309cdc920a0Smrg UnlockDisplay(dpy); 310cdc920a0Smrg SyncHandle(); 311cdc920a0Smrg return False; 312cdc920a0Smrg } 313cdc920a0Smrg 314cdc920a0Smrg UnlockDisplay(dpy); 315cdc920a0Smrg SyncHandle(); 316cdc920a0Smrg 317cdc920a0Smrg return rep.authenticated; 318cdc920a0Smrg} 319cdc920a0Smrg 320cdc920a0Smrgvoid 321cdc920a0SmrgDRI2CreateDrawable(Display * dpy, XID drawable) 322cdc920a0Smrg{ 323cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 324cdc920a0Smrg xDRI2CreateDrawableReq *req; 325cdc920a0Smrg 326cdc920a0Smrg XextSimpleCheckExtension(dpy, info, dri2ExtensionName); 327cdc920a0Smrg 328cdc920a0Smrg LockDisplay(dpy); 329cdc920a0Smrg GetReq(DRI2CreateDrawable, req); 330cdc920a0Smrg req->reqType = info->codes->major_opcode; 331cdc920a0Smrg req->dri2ReqType = X_DRI2CreateDrawable; 332cdc920a0Smrg req->drawable = drawable; 333cdc920a0Smrg UnlockDisplay(dpy); 334cdc920a0Smrg SyncHandle(); 335cdc920a0Smrg} 336cdc920a0Smrg 337cdc920a0Smrgvoid 338cdc920a0SmrgDRI2DestroyDrawable(Display * dpy, XID drawable) 339cdc920a0Smrg{ 340cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 341cdc920a0Smrg xDRI2DestroyDrawableReq *req; 342cdc920a0Smrg 343cdc920a0Smrg XextSimpleCheckExtension(dpy, info, dri2ExtensionName); 344cdc920a0Smrg 345cdc920a0Smrg XSync(dpy, False); 346cdc920a0Smrg 347cdc920a0Smrg LockDisplay(dpy); 348cdc920a0Smrg GetReq(DRI2DestroyDrawable, req); 349cdc920a0Smrg req->reqType = info->codes->major_opcode; 350cdc920a0Smrg req->dri2ReqType = X_DRI2DestroyDrawable; 351cdc920a0Smrg req->drawable = drawable; 352cdc920a0Smrg UnlockDisplay(dpy); 353cdc920a0Smrg SyncHandle(); 354cdc920a0Smrg} 355cdc920a0Smrg 356cdc920a0SmrgDRI2Buffer * 357cdc920a0SmrgDRI2GetBuffers(Display * dpy, XID drawable, 358cdc920a0Smrg int *width, int *height, 359cdc920a0Smrg unsigned int *attachments, int count, int *outCount) 360cdc920a0Smrg{ 361cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 362cdc920a0Smrg xDRI2GetBuffersReply rep; 363cdc920a0Smrg xDRI2GetBuffersReq *req; 364cdc920a0Smrg DRI2Buffer *buffers; 365cdc920a0Smrg xDRI2Buffer repBuffer; 366cdc920a0Smrg CARD32 *p; 367cdc920a0Smrg int i; 368cdc920a0Smrg 369cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 370cdc920a0Smrg 371cdc920a0Smrg LockDisplay(dpy); 372cdc920a0Smrg GetReqExtra(DRI2GetBuffers, count * 4, req); 373cdc920a0Smrg req->reqType = info->codes->major_opcode; 374cdc920a0Smrg req->dri2ReqType = X_DRI2GetBuffers; 375cdc920a0Smrg req->drawable = drawable; 376cdc920a0Smrg req->count = count; 377cdc920a0Smrg p = (CARD32 *) & req[1]; 378cdc920a0Smrg for (i = 0; i < count; i++) 379cdc920a0Smrg p[i] = attachments[i]; 380cdc920a0Smrg 381cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 382cdc920a0Smrg UnlockDisplay(dpy); 383cdc920a0Smrg SyncHandle(); 384cdc920a0Smrg return NULL; 385cdc920a0Smrg } 386cdc920a0Smrg 387cdc920a0Smrg *width = rep.width; 388cdc920a0Smrg *height = rep.height; 389cdc920a0Smrg *outCount = rep.count; 390cdc920a0Smrg 391cdc920a0Smrg buffers = Xmalloc(rep.count * sizeof buffers[0]); 392cdc920a0Smrg if (buffers == NULL) { 393cdc920a0Smrg _XEatData(dpy, rep.count * sizeof repBuffer); 394cdc920a0Smrg UnlockDisplay(dpy); 395cdc920a0Smrg SyncHandle(); 396cdc920a0Smrg return NULL; 397cdc920a0Smrg } 398cdc920a0Smrg 399cdc920a0Smrg for (i = 0; i < rep.count; i++) { 400cdc920a0Smrg _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); 401cdc920a0Smrg buffers[i].attachment = repBuffer.attachment; 402cdc920a0Smrg buffers[i].name = repBuffer.name; 403cdc920a0Smrg buffers[i].pitch = repBuffer.pitch; 404cdc920a0Smrg buffers[i].cpp = repBuffer.cpp; 405cdc920a0Smrg buffers[i].flags = repBuffer.flags; 406cdc920a0Smrg } 407cdc920a0Smrg 408cdc920a0Smrg UnlockDisplay(dpy); 409cdc920a0Smrg SyncHandle(); 410cdc920a0Smrg 411cdc920a0Smrg return buffers; 412cdc920a0Smrg} 413cdc920a0Smrg 414cdc920a0Smrg 415cdc920a0SmrgDRI2Buffer * 416cdc920a0SmrgDRI2GetBuffersWithFormat(Display * dpy, XID drawable, 417cdc920a0Smrg int *width, int *height, 418cdc920a0Smrg unsigned int *attachments, int count, int *outCount) 419cdc920a0Smrg{ 420cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 421cdc920a0Smrg xDRI2GetBuffersReply rep; 422cdc920a0Smrg xDRI2GetBuffersReq *req; 423cdc920a0Smrg DRI2Buffer *buffers; 424cdc920a0Smrg xDRI2Buffer repBuffer; 425cdc920a0Smrg CARD32 *p; 426cdc920a0Smrg int i; 427cdc920a0Smrg 428cdc920a0Smrg XextCheckExtension(dpy, info, dri2ExtensionName, False); 429cdc920a0Smrg 430cdc920a0Smrg LockDisplay(dpy); 431cdc920a0Smrg GetReqExtra(DRI2GetBuffers, count * (4 * 2), req); 432cdc920a0Smrg req->reqType = info->codes->major_opcode; 433cdc920a0Smrg req->dri2ReqType = X_DRI2GetBuffersWithFormat; 434cdc920a0Smrg req->drawable = drawable; 435cdc920a0Smrg req->count = count; 436cdc920a0Smrg p = (CARD32 *) & req[1]; 437cdc920a0Smrg for (i = 0; i < (count * 2); i++) 438cdc920a0Smrg p[i] = attachments[i]; 439cdc920a0Smrg 440cdc920a0Smrg if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { 441cdc920a0Smrg UnlockDisplay(dpy); 442cdc920a0Smrg SyncHandle(); 443cdc920a0Smrg return NULL; 444cdc920a0Smrg } 445cdc920a0Smrg 446cdc920a0Smrg *width = rep.width; 447cdc920a0Smrg *height = rep.height; 448cdc920a0Smrg *outCount = rep.count; 449cdc920a0Smrg 450cdc920a0Smrg buffers = Xmalloc(rep.count * sizeof buffers[0]); 451cdc920a0Smrg if (buffers == NULL) { 452cdc920a0Smrg _XEatData(dpy, rep.count * sizeof repBuffer); 453cdc920a0Smrg UnlockDisplay(dpy); 454cdc920a0Smrg SyncHandle(); 455cdc920a0Smrg return NULL; 456cdc920a0Smrg } 457cdc920a0Smrg 458cdc920a0Smrg for (i = 0; i < rep.count; i++) { 459cdc920a0Smrg _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); 460cdc920a0Smrg buffers[i].attachment = repBuffer.attachment; 461cdc920a0Smrg buffers[i].name = repBuffer.name; 462cdc920a0Smrg buffers[i].pitch = repBuffer.pitch; 463cdc920a0Smrg buffers[i].cpp = repBuffer.cpp; 464cdc920a0Smrg buffers[i].flags = repBuffer.flags; 465cdc920a0Smrg } 466cdc920a0Smrg 467cdc920a0Smrg UnlockDisplay(dpy); 468cdc920a0Smrg SyncHandle(); 469cdc920a0Smrg 470cdc920a0Smrg return buffers; 471cdc920a0Smrg} 472cdc920a0Smrg 473cdc920a0Smrg 474cdc920a0Smrgvoid 475cdc920a0SmrgDRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, 476cdc920a0Smrg CARD32 dest, CARD32 src) 477cdc920a0Smrg{ 478cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 479cdc920a0Smrg xDRI2CopyRegionReq *req; 480cdc920a0Smrg xDRI2CopyRegionReply rep; 481cdc920a0Smrg 482cdc920a0Smrg XextSimpleCheckExtension(dpy, info, dri2ExtensionName); 483cdc920a0Smrg 484cdc920a0Smrg LockDisplay(dpy); 485cdc920a0Smrg GetReq(DRI2CopyRegion, req); 486cdc920a0Smrg req->reqType = info->codes->major_opcode; 487cdc920a0Smrg req->dri2ReqType = X_DRI2CopyRegion; 488cdc920a0Smrg req->drawable = drawable; 489cdc920a0Smrg req->region = region; 490cdc920a0Smrg req->dest = dest; 491cdc920a0Smrg req->src = src; 492cdc920a0Smrg 493cdc920a0Smrg _XReply(dpy, (xReply *) & rep, 0, xFalse); 494cdc920a0Smrg 495cdc920a0Smrg UnlockDisplay(dpy); 496cdc920a0Smrg SyncHandle(); 497cdc920a0Smrg} 498cdc920a0Smrg 499cdc920a0Smrg#ifdef X_DRI2SwapBuffers 500cdc920a0Smrgstatic void 501cdc920a0Smrgload_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor, 502cdc920a0Smrg CARD64 remainder) 503cdc920a0Smrg{ 504cdc920a0Smrg req->target_msc_hi = target >> 32; 505cdc920a0Smrg req->target_msc_lo = target & 0xffffffff; 506cdc920a0Smrg req->divisor_hi = divisor >> 32; 507cdc920a0Smrg req->divisor_lo = divisor & 0xffffffff; 508cdc920a0Smrg req->remainder_hi = remainder >> 32; 509cdc920a0Smrg req->remainder_lo = remainder & 0xffffffff; 510cdc920a0Smrg} 511cdc920a0Smrg 512cdc920a0Smrgstatic CARD64 513cdc920a0Smrgvals_to_card64(CARD32 lo, CARD32 hi) 514cdc920a0Smrg{ 515cdc920a0Smrg return (CARD64)hi << 32 | lo; 516cdc920a0Smrg} 517cdc920a0Smrg 518cdc920a0Smrgvoid DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, 519cdc920a0Smrg CARD64 divisor, CARD64 remainder, CARD64 *count) 520cdc920a0Smrg{ 521cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 522cdc920a0Smrg xDRI2SwapBuffersReq *req; 523cdc920a0Smrg xDRI2SwapBuffersReply rep; 524cdc920a0Smrg 525cdc920a0Smrg XextSimpleCheckExtension (dpy, info, dri2ExtensionName); 526cdc920a0Smrg 527cdc920a0Smrg LockDisplay(dpy); 528cdc920a0Smrg GetReq(DRI2SwapBuffers, req); 529cdc920a0Smrg req->reqType = info->codes->major_opcode; 530cdc920a0Smrg req->dri2ReqType = X_DRI2SwapBuffers; 531cdc920a0Smrg req->drawable = drawable; 532cdc920a0Smrg load_swap_req(req, target_msc, divisor, remainder); 533cdc920a0Smrg 534cdc920a0Smrg _XReply(dpy, (xReply *)&rep, 0, xFalse); 535cdc920a0Smrg 536cdc920a0Smrg *count = vals_to_card64(rep.swap_lo, rep.swap_hi); 537cdc920a0Smrg 538cdc920a0Smrg UnlockDisplay(dpy); 539cdc920a0Smrg SyncHandle(); 540cdc920a0Smrg} 541cdc920a0Smrg#endif 542cdc920a0Smrg 543cdc920a0Smrg#ifdef X_DRI2GetMSC 544cdc920a0SmrgBool DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, 545cdc920a0Smrg CARD64 *sbc) 546cdc920a0Smrg{ 547cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 548cdc920a0Smrg xDRI2GetMSCReq *req; 549cdc920a0Smrg xDRI2MSCReply rep; 550cdc920a0Smrg 551cdc920a0Smrg XextCheckExtension (dpy, info, dri2ExtensionName, False); 552cdc920a0Smrg 553cdc920a0Smrg LockDisplay(dpy); 554cdc920a0Smrg GetReq(DRI2GetMSC, req); 555cdc920a0Smrg req->reqType = info->codes->major_opcode; 556cdc920a0Smrg req->dri2ReqType = X_DRI2GetMSC; 557cdc920a0Smrg req->drawable = drawable; 558cdc920a0Smrg 559cdc920a0Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 560cdc920a0Smrg UnlockDisplay(dpy); 561cdc920a0Smrg SyncHandle(); 562cdc920a0Smrg return False; 563cdc920a0Smrg } 564cdc920a0Smrg 565cdc920a0Smrg *ust = vals_to_card64(rep.ust_lo, rep.ust_hi); 566cdc920a0Smrg *msc = vals_to_card64(rep.msc_lo, rep.msc_hi); 567cdc920a0Smrg *sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi); 568cdc920a0Smrg 569cdc920a0Smrg UnlockDisplay(dpy); 570cdc920a0Smrg SyncHandle(); 571cdc920a0Smrg 572cdc920a0Smrg return True; 573cdc920a0Smrg} 574cdc920a0Smrg#endif 575cdc920a0Smrg 576cdc920a0Smrg#ifdef X_DRI2WaitMSC 577cdc920a0Smrgstatic void 578cdc920a0Smrgload_msc_req(xDRI2WaitMSCReq *req, CARD64 target, CARD64 divisor, 579cdc920a0Smrg CARD64 remainder) 580cdc920a0Smrg{ 581cdc920a0Smrg req->target_msc_hi = target >> 32; 582cdc920a0Smrg req->target_msc_lo = target & 0xffffffff; 583cdc920a0Smrg req->divisor_hi = divisor >> 32; 584cdc920a0Smrg req->divisor_lo = divisor & 0xffffffff; 585cdc920a0Smrg req->remainder_hi = remainder >> 32; 586cdc920a0Smrg req->remainder_lo = remainder & 0xffffffff; 587cdc920a0Smrg} 588cdc920a0Smrg 589cdc920a0SmrgBool DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, 590cdc920a0Smrg CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc) 591cdc920a0Smrg{ 592cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 593cdc920a0Smrg xDRI2WaitMSCReq *req; 594cdc920a0Smrg xDRI2MSCReply rep; 595cdc920a0Smrg 596cdc920a0Smrg XextCheckExtension (dpy, info, dri2ExtensionName, False); 597cdc920a0Smrg 598cdc920a0Smrg LockDisplay(dpy); 599cdc920a0Smrg GetReq(DRI2WaitMSC, req); 600cdc920a0Smrg req->reqType = info->codes->major_opcode; 601cdc920a0Smrg req->dri2ReqType = X_DRI2WaitMSC; 602cdc920a0Smrg req->drawable = drawable; 603cdc920a0Smrg load_msc_req(req, target_msc, divisor, remainder); 604cdc920a0Smrg 605cdc920a0Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 606cdc920a0Smrg UnlockDisplay(dpy); 607cdc920a0Smrg SyncHandle(); 608cdc920a0Smrg return False; 609cdc920a0Smrg } 610cdc920a0Smrg 611cdc920a0Smrg *ust = ((CARD64)rep.ust_hi << 32) | (CARD64)rep.ust_lo; 612cdc920a0Smrg *msc = ((CARD64)rep.msc_hi << 32) | (CARD64)rep.msc_lo; 613cdc920a0Smrg *sbc = ((CARD64)rep.sbc_hi << 32) | (CARD64)rep.sbc_lo; 614cdc920a0Smrg 615cdc920a0Smrg UnlockDisplay(dpy); 616cdc920a0Smrg SyncHandle(); 617cdc920a0Smrg 618cdc920a0Smrg return True; 619cdc920a0Smrg} 620cdc920a0Smrg#endif 621cdc920a0Smrg 622cdc920a0Smrg#ifdef X_DRI2WaitSBC 623cdc920a0Smrgstatic void 624cdc920a0Smrgload_sbc_req(xDRI2WaitSBCReq *req, CARD64 target) 625cdc920a0Smrg{ 626cdc920a0Smrg req->target_sbc_hi = target >> 32; 627cdc920a0Smrg req->target_sbc_lo = target & 0xffffffff; 628cdc920a0Smrg} 629cdc920a0Smrg 630cdc920a0SmrgBool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust, 631cdc920a0Smrg CARD64 *msc, CARD64 *sbc) 632cdc920a0Smrg{ 633cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 634cdc920a0Smrg xDRI2WaitSBCReq *req; 635cdc920a0Smrg xDRI2MSCReply rep; 636cdc920a0Smrg 637cdc920a0Smrg XextCheckExtension (dpy, info, dri2ExtensionName, False); 638cdc920a0Smrg 639cdc920a0Smrg LockDisplay(dpy); 640cdc920a0Smrg GetReq(DRI2WaitSBC, req); 641cdc920a0Smrg req->reqType = info->codes->major_opcode; 642cdc920a0Smrg req->dri2ReqType = X_DRI2WaitSBC; 643cdc920a0Smrg req->drawable = drawable; 644cdc920a0Smrg load_sbc_req(req, target_sbc); 645cdc920a0Smrg 646cdc920a0Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 647cdc920a0Smrg UnlockDisplay(dpy); 648cdc920a0Smrg SyncHandle(); 649cdc920a0Smrg return False; 650cdc920a0Smrg } 651cdc920a0Smrg 652cdc920a0Smrg *ust = ((CARD64)rep.ust_hi << 32) | rep.ust_lo; 653cdc920a0Smrg *msc = ((CARD64)rep.msc_hi << 32) | rep.msc_lo; 654cdc920a0Smrg *sbc = ((CARD64)rep.sbc_hi << 32) | rep.sbc_lo; 655cdc920a0Smrg 656cdc920a0Smrg UnlockDisplay(dpy); 657cdc920a0Smrg SyncHandle(); 658cdc920a0Smrg 659cdc920a0Smrg return True; 660cdc920a0Smrg} 661cdc920a0Smrg#endif 662cdc920a0Smrg 663cdc920a0Smrg#ifdef X_DRI2SwapInterval 664cdc920a0Smrgvoid DRI2SwapInterval(Display *dpy, XID drawable, int interval) 665cdc920a0Smrg{ 666cdc920a0Smrg XExtDisplayInfo *info = DRI2FindDisplay(dpy); 667cdc920a0Smrg xDRI2SwapIntervalReq *req; 668cdc920a0Smrg 669cdc920a0Smrg XextSimpleCheckExtension (dpy, info, dri2ExtensionName); 670cdc920a0Smrg 671cdc920a0Smrg LockDisplay(dpy); 672cdc920a0Smrg GetReq(DRI2SwapInterval, req); 673cdc920a0Smrg req->reqType = info->codes->major_opcode; 674cdc920a0Smrg req->dri2ReqType = X_DRI2SwapInterval; 675cdc920a0Smrg req->drawable = drawable; 676cdc920a0Smrg req->interval = interval; 677cdc920a0Smrg UnlockDisplay(dpy); 678cdc920a0Smrg SyncHandle(); 679cdc920a0Smrg} 680cdc920a0Smrg#endif 681cdc920a0Smrg 682cdc920a0Smrg#endif /* GLX_DIRECT_RENDERING */ 683