diff options
author | Christian König <[email protected]> | 2012-02-23 11:13:57 +0100 |
---|---|---|
committer | Christian König <[email protected]> | 2012-03-01 14:37:44 +0100 |
commit | 80b40a4841a4af93a1bc93e4746a418a9cee0a55 (patch) | |
tree | 90d42e27b1380ccb39eeaefeb2c75e177cf69a33 /src/gallium/winsys | |
parent | 6b024464e80d035fe92c9c15761a0ac269a8ad51 (diff) |
vl: rewrite vl DRI backend using XCB
v2: also set array_size of texture
Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r-- | src/gallium/winsys/g3dvl/dri/Makefile | 1 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/dri/dri2.c | 666 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/dri/dri2.h | 106 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/dri/dri_winsys.c | 228 |
4 files changed, 145 insertions, 856 deletions
diff --git a/src/gallium/winsys/g3dvl/dri/Makefile b/src/gallium/winsys/g3dvl/dri/Makefile index 7a9b38fc5c5..43abcd9fb4b 100644 --- a/src/gallium/winsys/g3dvl/dri/Makefile +++ b/src/gallium/winsys/g3dvl/dri/Makefile @@ -7,7 +7,6 @@ LIBRARY_INCLUDES = -I$(TOP)/src/gallium/winsys/g3dvl \ $(shell $(PKG_CONFIG) libdrm --cflags-only-I) C_SOURCES = \ - dri2.c \ dri_winsys.c include ../../../Makefile.template diff --git a/src/gallium/winsys/g3dvl/dri/dri2.c b/src/gallium/winsys/g3dvl/dri/dri2.c deleted file mode 100644 index 12ed6d0ab74..00000000000 --- a/src/gallium/winsys/g3dvl/dri/dri2.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - * Copyright © 2008 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Soft- - * ware"), to deal in the Software without restriction, including without - * limitation the rights to use, copy, modify, merge, publish, distribute, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, provided that the above copyright - * notice(s) and this permission notice appear in all copies of the Soft- - * ware and that both the above copyright notice(s) and this permission - * notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- - * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY - * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN - * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- - * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- - * MANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization of - * the copyright holder. - * - * Authors: - * Kristian Høgsberg ([email protected]) - */ - - -#define NEED_REPLIES -#include <stdio.h> -#include <X11/Xlibint.h> -#include <X11/extensions/Xext.h> -#include <X11/extensions/extutil.h> -#include <X11/extensions/dri2proto.h> -#include "xf86drm.h" -#include "dri2.h" -#if 0 -#include "glxclient.h" -#include "GL/glxext.h" -#endif - -/* Allow the build to work with an older versions of dri2proto.h and - * dri2tokens.h. - */ -#if DRI2_MINOR < 1 -#undef DRI2_MINOR -#define DRI2_MINOR 1 -#define X_DRI2GetBuffersWithFormat 7 -#endif - - -static char dri2ExtensionName[] = DRI2_NAME; -static XExtensionInfo *dri2Info; -static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) - -static Bool -DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire); -static Status -DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire); - -static /* const */ XExtensionHooks dri2ExtensionHooks = { - NULL, /* create_gc */ - NULL, /* copy_gc */ - NULL, /* flush_gc */ - NULL, /* free_gc */ - NULL, /* create_font */ - NULL, /* free_font */ - DRI2CloseDisplay, /* close_display */ - DRI2WireToEvent, /* wire_to_event */ - DRI2EventToWire, /* event_to_wire */ - NULL, /* error */ - NULL, /* error_string */ -}; - -static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, - dri2Info, - dri2ExtensionName, - &dri2ExtensionHooks, - 0, NULL) - -static Bool -DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) -{ -#if 0 - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - XExtDisplayInfo *glx_info = __glXFindDisplay(dpy); - - XextCheckExtension(dpy, info, dri2ExtensionName, False); - - switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { - -#ifdef X_DRI2SwapBuffers - case DRI2_BufferSwapComplete: - { - GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; - xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire; - aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); - aevent->type = - (glx_info->codes->first_event + GLX_BufferSwapComplete) & 0x75; - aevent->send_event = (awire->type & 0x80) != 0; - aevent->display = dpy; - aevent->drawable = awire->drawable; - switch (awire->event_type) { - case DRI2_EXCHANGE_COMPLETE: - aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL; - break; - case DRI2_BLIT_COMPLETE: - aevent->event_type = GLX_BLIT_COMPLETE_INTEL; - break; - case DRI2_FLIP_COMPLETE: - aevent->event_type = GLX_FLIP_COMPLETE_INTEL; - break; - default: - /* unknown swap completion type */ - return False; - } - aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; - aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; - aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo; - return True; - } -#endif -#ifdef DRI2_InvalidateBuffers - case DRI2_InvalidateBuffers: - { - xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire; - - dri2InvalidateBuffers(dpy, awire->drawable); - return False; - } -#endif - default: - /* client doesn't support server event */ - break; - } -#endif - return False; -} - -/* We don't actually support this. It doesn't make sense for clients to - * send each other DRI2 events. - */ -static Status -DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - - XextCheckExtension(dpy, info, dri2ExtensionName, False); - - switch (event->type) { - default: - /* client doesn't support server event */ - break; - } - - return Success; -} - -Bool -DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - - if (XextHasExtension(info)) { - *eventBase = info->codes->first_event; - *errorBase = info->codes->first_error; - return True; - } - - return False; -} - -Bool -DRI2QueryVersion(Display * dpy, int *major, int *minor) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2QueryVersionReply rep; - xDRI2QueryVersionReq *req; - int i, nevents; - - XextCheckExtension(dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2QueryVersion, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2QueryVersion; - req->majorVersion = DRI2_MAJOR; - req->minorVersion = DRI2_MINOR; - if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - *major = rep.majorVersion; - *minor = rep.minorVersion; - UnlockDisplay(dpy); - SyncHandle(); - - switch (rep.minorVersion) { - case 1: - nevents = 0; - break; - case 2: - nevents = 1; - break; - case 3: - default: - nevents = 2; - break; - } - - for (i = 0; i < nevents; i++) { - XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent); - XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire); - } - - return True; -} - -Bool -DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2ConnectReply rep; - xDRI2ConnectReq *req; - - XextCheckExtension(dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2Connect, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2Connect; - req->window = window; - req->driverType = DRI2DriverDRI; - if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - *driverName = Xmalloc(rep.driverNameLength + 1); - if (*driverName == NULL) { - _XEatData(dpy, - ((rep.driverNameLength + 3) & ~3) + - ((rep.deviceNameLength + 3) & ~3)); - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - _XReadPad(dpy, *driverName, rep.driverNameLength); - (*driverName)[rep.driverNameLength] = '\0'; - - *deviceName = Xmalloc(rep.deviceNameLength + 1); - if (*deviceName == NULL) { - Xfree(*driverName); - _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3)); - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - _XReadPad(dpy, *deviceName, rep.deviceNameLength); - (*deviceName)[rep.deviceNameLength] = '\0'; - - UnlockDisplay(dpy); - SyncHandle(); - - return True; -} - -Bool -DRI2Authenticate(Display * dpy, XID window, drm_magic_t magic) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2AuthenticateReq *req; - xDRI2AuthenticateReply rep; - - XextCheckExtension(dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2Authenticate, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2Authenticate; - req->window = window; - req->magic = magic; - - if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - UnlockDisplay(dpy); - SyncHandle(); - - return rep.authenticated; -} - -void -DRI2CreateDrawable(Display * dpy, XID drawable) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2CreateDrawableReq *req; - - XextSimpleCheckExtension(dpy, info, dri2ExtensionName); - - LockDisplay(dpy); - GetReq(DRI2CreateDrawable, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2CreateDrawable; - req->drawable = drawable; - UnlockDisplay(dpy); - SyncHandle(); -} - -void -DRI2DestroyDrawable(Display * dpy, XID drawable) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2DestroyDrawableReq *req; - - XextSimpleCheckExtension(dpy, info, dri2ExtensionName); - - XSync(dpy, False); - - LockDisplay(dpy); - GetReq(DRI2DestroyDrawable, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2DestroyDrawable; - req->drawable = drawable; - UnlockDisplay(dpy); - SyncHandle(); -} - -DRI2Buffer * -DRI2GetBuffers(Display * dpy, XID drawable, - int *width, int *height, - unsigned int *attachments, int count, int *outCount) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2GetBuffersReply rep; - xDRI2GetBuffersReq *req; - DRI2Buffer *buffers; - xDRI2Buffer repBuffer; - CARD32 *p; - int i; - - XextCheckExtension(dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReqExtra(DRI2GetBuffers, count * 4, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2GetBuffers; - req->drawable = drawable; - req->count = count; - p = (CARD32 *) & req[1]; - for (i = 0; i < count; i++) - p[i] = attachments[i]; - - if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return NULL; - } - - *width = rep.width; - *height = rep.height; - *outCount = rep.count; - - buffers = Xmalloc(rep.count * sizeof buffers[0]); - if (buffers == NULL) { - _XEatData(dpy, rep.count * sizeof repBuffer); - UnlockDisplay(dpy); - SyncHandle(); - return NULL; - } - - for (i = 0; i < rep.count; i++) { - _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); - buffers[i].attachment = repBuffer.attachment; - buffers[i].name = repBuffer.name; - buffers[i].pitch = repBuffer.pitch; - buffers[i].cpp = repBuffer.cpp; - buffers[i].flags = repBuffer.flags; - } - - UnlockDisplay(dpy); - SyncHandle(); - - return buffers; -} - - -DRI2Buffer * -DRI2GetBuffersWithFormat(Display * dpy, XID drawable, - int *width, int *height, - unsigned int *attachments, int count, int *outCount) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2GetBuffersReply rep; - xDRI2GetBuffersReq *req; - DRI2Buffer *buffers; - xDRI2Buffer repBuffer; - CARD32 *p; - int i; - - XextCheckExtension(dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReqExtra(DRI2GetBuffers, count * (4 * 2), req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2GetBuffersWithFormat; - req->drawable = drawable; - req->count = count; - p = (CARD32 *) & req[1]; - for (i = 0; i < (count * 2); i++) - p[i] = attachments[i]; - - if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return NULL; - } - - *width = rep.width; - *height = rep.height; - *outCount = rep.count; - - buffers = Xmalloc(rep.count * sizeof buffers[0]); - if (buffers == NULL) { - _XEatData(dpy, rep.count * sizeof repBuffer); - UnlockDisplay(dpy); - SyncHandle(); - return NULL; - } - - for (i = 0; i < rep.count; i++) { - _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); - buffers[i].attachment = repBuffer.attachment; - buffers[i].name = repBuffer.name; - buffers[i].pitch = repBuffer.pitch; - buffers[i].cpp = repBuffer.cpp; - buffers[i].flags = repBuffer.flags; - } - - UnlockDisplay(dpy); - SyncHandle(); - - return buffers; -} - - -void -DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, - CARD32 dest, CARD32 src) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2CopyRegionReq *req; - - XextSimpleCheckExtension(dpy, info, dri2ExtensionName); - - LockDisplay(dpy); - GetReq(DRI2CopyRegion, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2CopyRegion; - req->drawable = drawable; - req->region = region; - req->dest = dest; - req->src = src; - - UnlockDisplay(dpy); - SyncHandle(); -} - -#ifdef X_DRI2SwapBuffers -static void -load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor, - CARD64 remainder) -{ - req->target_msc_hi = target >> 32; - req->target_msc_lo = target & 0xffffffff; - req->divisor_hi = divisor >> 32; - req->divisor_lo = divisor & 0xffffffff; - req->remainder_hi = remainder >> 32; - req->remainder_lo = remainder & 0xffffffff; -} - -static CARD64 -vals_to_card64(CARD32 lo, CARD32 hi) -{ - return (CARD64)hi << 32 | lo; -} - -void DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, - CARD64 divisor, CARD64 remainder, CARD64 *count) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2SwapBuffersReq *req; - xDRI2SwapBuffersReply rep; - - XextSimpleCheckExtension (dpy, info, dri2ExtensionName); - - LockDisplay(dpy); - GetReq(DRI2SwapBuffers, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2SwapBuffers; - req->drawable = drawable; - load_swap_req(req, target_msc, divisor, remainder); - - _XReply(dpy, (xReply *)&rep, 0, xFalse); - - *count = vals_to_card64(rep.swap_lo, rep.swap_hi); - - UnlockDisplay(dpy); - SyncHandle(); -} -#endif - -#ifdef X_DRI2GetMSC -Bool DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, - CARD64 *sbc) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2GetMSCReq *req; - xDRI2MSCReply rep; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2GetMSC, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2GetMSC; - req->drawable = drawable; - - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - *ust = vals_to_card64(rep.ust_lo, rep.ust_hi); - *msc = vals_to_card64(rep.msc_lo, rep.msc_hi); - *sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi); - - UnlockDisplay(dpy); - SyncHandle(); - - return True; -} -#endif - -#ifdef X_DRI2WaitMSC -static void -load_msc_req(xDRI2WaitMSCReq *req, CARD64 target, CARD64 divisor, - CARD64 remainder) -{ - req->target_msc_hi = target >> 32; - req->target_msc_lo = target & 0xffffffff; - req->divisor_hi = divisor >> 32; - req->divisor_lo = divisor & 0xffffffff; - req->remainder_hi = remainder >> 32; - req->remainder_lo = remainder & 0xffffffff; -} - -Bool DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, - CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2WaitMSCReq *req; - xDRI2MSCReply rep; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2WaitMSC, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2WaitMSC; - req->drawable = drawable; - load_msc_req(req, target_msc, divisor, remainder); - - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - *ust = ((CARD64)rep.ust_hi << 32) | (CARD64)rep.ust_lo; - *msc = ((CARD64)rep.msc_hi << 32) | (CARD64)rep.msc_lo; - *sbc = ((CARD64)rep.sbc_hi << 32) | (CARD64)rep.sbc_lo; - - UnlockDisplay(dpy); - SyncHandle(); - - return True; -} -#endif - -#ifdef X_DRI2WaitSBC -static void -load_sbc_req(xDRI2WaitSBCReq *req, CARD64 target) -{ - req->target_sbc_hi = target >> 32; - req->target_sbc_lo = target & 0xffffffff; -} - -Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust, - CARD64 *msc, CARD64 *sbc) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2WaitSBCReq *req; - xDRI2MSCReply rep; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2WaitSBC, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2WaitSBC; - req->drawable = drawable; - load_sbc_req(req, target_sbc); - - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - *ust = ((CARD64)rep.ust_hi << 32) | rep.ust_lo; - *msc = ((CARD64)rep.msc_hi << 32) | rep.msc_lo; - *sbc = ((CARD64)rep.sbc_hi << 32) | rep.sbc_lo; - - UnlockDisplay(dpy); - SyncHandle(); - - return True; -} -#endif - -#ifdef X_DRI2SwapInterval -void DRI2SwapInterval(Display *dpy, XID drawable, int interval) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2SwapIntervalReq *req; - - XextSimpleCheckExtension (dpy, info, dri2ExtensionName); - - LockDisplay(dpy); - GetReq(DRI2SwapInterval, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2SwapInterval; - req->drawable = drawable; - req->interval = interval; - UnlockDisplay(dpy); - SyncHandle(); -} -#endif diff --git a/src/gallium/winsys/g3dvl/dri/dri2.h b/src/gallium/winsys/g3dvl/dri/dri2.h deleted file mode 100644 index 114e9f8f965..00000000000 --- a/src/gallium/winsys/g3dvl/dri/dri2.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright © 2007,2008 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Soft- - * ware"), to deal in the Software without restriction, including without - * limitation the rights to use, copy, modify, merge, publish, distribute, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, provided that the above copyright - * notice(s) and this permission notice appear in all copies of the Soft- - * ware and that both the above copyright notice(s) and this permission - * notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- - * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY - * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN - * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- - * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- - * MANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization of - * the copyright holder. - * - * Authors: - * Kristian Høgsberg ([email protected]) - */ - -#ifndef _DRI2_H_ -#define _DRI2_H_ - -#include <X11/extensions/Xfixes.h> -#include <X11/extensions/dri2tokens.h> - -typedef struct -{ - unsigned int attachment; - unsigned int name; - unsigned int pitch; - unsigned int cpp; - unsigned int flags; -} DRI2Buffer; - -extern Bool -DRI2QueryExtension(Display * display, int *eventBase, int *errorBase); - -extern Bool -DRI2QueryVersion(Display * display, int *major, int *minor); - -extern Bool -DRI2Connect(Display * display, XID window, - char **driverName, char **deviceName); - -extern Bool -DRI2Authenticate(Display * display, XID window, drm_magic_t magic); - -extern void -DRI2CreateDrawable(Display * display, XID drawable); - -extern void -DRI2DestroyDrawable(Display * display, XID handle); - -extern DRI2Buffer* -DRI2GetBuffers(Display * dpy, XID drawable, - int *width, int *height, - unsigned int *attachments, int count, - int *outCount); - -/** - * \note - * This function is only supported with DRI2 version 1.1 or later. - */ -extern DRI2Buffer* -DRI2GetBuffersWithFormat(Display * dpy, XID drawable, - int *width, int *height, - unsigned int *attachments, - int count, int *outCount); - -extern void -DRI2CopyRegion(Display * dpy, XID drawable, - XserverRegion region, - CARD32 dest, CARD32 src); - -extern void -DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, - CARD64 remainder, CARD64 *count); - -extern Bool -DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, CARD64 *sbc); - -extern Bool -DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, - CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc); - -extern Bool -DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust, - CARD64 *msc, CARD64 *sbc); - -extern void -DRI2SwapInterval(Display *dpy, XID drawable, int interval); - -#endif diff --git a/src/gallium/winsys/g3dvl/dri/dri_winsys.c b/src/gallium/winsys/g3dvl/dri/dri_winsys.c index 904a6d796fc..fe8a859beaf 100644 --- a/src/gallium/winsys/g3dvl/dri/dri_winsys.c +++ b/src/gallium/winsys/g3dvl/dri/dri_winsys.c @@ -29,8 +29,9 @@ #include <sys/stat.h> #include <fcntl.h> -#include <X11/Xlibint.h> -#include <X11/extensions/dri2tokens.h> +#include <X11/Xlib-xcb.h> +#include <xcb/xfixes.h> +#include <xcb/dri2.h> #include <xf86drm.h> #include "pipe/p_screen.h" @@ -44,14 +45,16 @@ #include "util/u_inlines.h" #include "vl_winsys.h" -#include "dri2.h" struct vl_dri_screen { struct vl_screen base; - Display *display; - struct util_hash_table *drawable_table; - Drawable last_seen_drawable; + xcb_connection_t *conn; + xcb_drawable_t drawable; + xcb_xfixes_region_t region; + + bool flushed; + xcb_dri2_copy_region_cookie_t flush_cookie; }; static void @@ -60,67 +63,93 @@ vl_dri2_flush_frontbuffer(struct pipe_screen *screen, unsigned level, unsigned layer, void *context_private) { - struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)context_private; - XserverRegion region; + struct vl_dri_screen *scrn = (struct vl_dri_screen*)context_private; assert(screen); assert(resource); assert(context_private); - region = XFixesCreateRegionFromWindow(vl_dri_scrn->display, vl_dri_scrn->last_seen_drawable, WindowRegionBounding); - DRI2CopyRegion(vl_dri_scrn->display, vl_dri_scrn->last_seen_drawable, region, - DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); - XFixesDestroyRegion(vl_dri_scrn->display, region); + if (scrn->flushed) + free(xcb_dri2_copy_region_reply(scrn->conn, scrn->flush_cookie, NULL)); + else + scrn->flushed = true; + + scrn->flush_cookie = xcb_dri2_copy_region_unchecked(scrn->conn, scrn->drawable, scrn->region, + XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT, + XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT); +} + +static void +vl_dri2_destroy_drawable(struct vl_dri_screen *scrn) +{ + xcb_void_cookie_t destroy_cookie; + if (scrn->drawable) { + destroy_cookie = xcb_dri2_destroy_drawable_checked(scrn->conn, scrn->drawable); + /* ignore any error here, since the drawable can be destroyed long ago */ + free(xcb_request_check(scrn->conn, destroy_cookie)); + } } struct pipe_resource* vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable) { - struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen; - unsigned int attachments[1] = {DRI2BufferFrontLeft}; + static const unsigned int attachments[1] = { XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT }; + struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen; + struct winsys_handle dri2_front_handle; struct pipe_resource template, *tex; - DRI2Buffer *dri2_front; - int w, h, count; - - assert(vl_dri_scrn); - - if (vl_dri_scrn->last_seen_drawable != drawable) { - /* Hash table business depends on this equality */ - assert(None == NULL); - Drawable lookup_drawable = (Drawable)util_hash_table_get(vl_dri_scrn->drawable_table, (void*)drawable); - if (lookup_drawable == None) { - DRI2CreateDrawable(vl_dri_scrn->display, drawable); - util_hash_table_set(vl_dri_scrn->drawable_table, (void*)drawable, (void*)drawable); - } - vl_dri_scrn->last_seen_drawable = drawable; + + xcb_dri2_get_buffers_cookie_t cookie; + xcb_dri2_get_buffers_reply_t *reply; + xcb_dri2_dri2_buffer_t *buffers; + + assert(scrn); + + if (scrn->drawable != drawable) { + vl_dri2_destroy_drawable(scrn); + xcb_dri2_create_drawable(scrn->conn, drawable); + scrn->drawable = drawable; } - dri2_front = DRI2GetBuffers(vl_dri_scrn->display, drawable, &w, &h, attachments, 1, &count); + if (scrn->region) + xcb_xfixes_destroy_region(scrn->conn, scrn->region); + else + scrn->region = xcb_generate_id(scrn->conn); + + xcb_xfixes_create_region_from_window(scrn->conn, scrn->region, drawable, XCB_SHAPE_SK_BOUNDING); - assert(count == 1); + cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, drawable, 1, 1, attachments); + reply = xcb_dri2_get_buffers_reply(scrn->conn, cookie, NULL); + if (!reply) + return NULL; - if (!dri2_front) + buffers = xcb_dri2_get_buffers_buffers(reply); + if (!buffers) { + free(reply); return NULL; + } + + assert(reply->count == 1); memset(&dri2_front_handle, 0, sizeof(dri2_front_handle)); dri2_front_handle.type = DRM_API_HANDLE_TYPE_SHARED; - dri2_front_handle.handle = dri2_front->name; - dri2_front_handle.stride = dri2_front->pitch; + dri2_front_handle.handle = buffers[0].name; + dri2_front_handle.stride = buffers[0].pitch; memset(&template, 0, sizeof(template)); template.target = PIPE_TEXTURE_2D; template.format = PIPE_FORMAT_B8G8R8X8_UNORM; template.last_level = 0; - template.width0 = w; - template.height0 = h; + template.width0 = reply->width; + template.height0 = reply->height; template.depth0 = 1; + template.array_size = 1; template.usage = PIPE_USAGE_STATIC; template.bind = PIPE_BIND_RENDER_TARGET; template.flags = 0; - tex = vl_dri_scrn->base.pscreen->resource_from_handle(vl_dri_scrn->base.pscreen, &template, &dri2_front_handle); - Xfree(dri2_front); + tex = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &template, &dri2_front_handle); + free(reply); return tex; } @@ -131,44 +160,67 @@ vl_screen_get_private(struct vl_screen *vscreen) return vscreen; } -static unsigned drawable_hash(void *key) -{ - Drawable drawable = (Drawable)key; - assert(drawable != None); - return util_hash_crc32(&drawable, sizeof(Drawable)); -} - -static int drawable_cmp(void *key1, void *key2) -{ - Drawable d1 = (Drawable)key1; - Drawable d2 = (Drawable)key2; - assert(d1 != None); - assert(d2 != None); - return d1 != d2; -} - struct vl_screen* vl_screen_create(Display *display, int screen) { - struct vl_dri_screen *vl_dri_scrn; - drm_magic_t magic; - char *drvName; - char *devName; + struct vl_dri_screen *scrn; + const xcb_query_extension_reply_t *extension; + xcb_xfixes_query_version_cookie_t xfixes_query_cookie; + xcb_xfixes_query_version_reply_t *xfixes_query = NULL; + xcb_dri2_query_version_cookie_t dri2_query_cookie; + xcb_dri2_query_version_reply_t *dri2_query = NULL; + xcb_dri2_connect_cookie_t connect_cookie; + xcb_dri2_connect_reply_t *connect = NULL; + xcb_dri2_authenticate_cookie_t authenticate_cookie; + xcb_dri2_authenticate_reply_t *authenticate = NULL; + xcb_screen_iterator_t s; + xcb_generic_error_t *error = NULL; + char *device_name; int fd; + drm_magic_t magic; + assert(display); - vl_dri_scrn = CALLOC_STRUCT(vl_dri_screen); - if (!vl_dri_scrn) - goto no_struct; + scrn = CALLOC_STRUCT(vl_dri_screen); + if (!scrn) + return NULL; + + scrn->conn = XGetXCBConnection(display); + if (!scrn->conn) + goto free_screen; + + xcb_prefetch_extension_data(scrn->conn, &xcb_xfixes_id); + xcb_prefetch_extension_data(scrn->conn, &xcb_dri2_id); + + extension = xcb_get_extension_data(scrn->conn, &xcb_xfixes_id); + if (!(extension && extension->present)) + goto free_screen; + + extension = xcb_get_extension_data(scrn->conn, &xcb_dri2_id); + if (!(extension && extension->present)) + goto free_screen; + + xfixes_query_cookie = xcb_xfixes_query_version(scrn->conn, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); + xfixes_query = xcb_xfixes_query_version_reply (scrn->conn, xfixes_query_cookie, &error); + if (xfixes_query == NULL || error != NULL || xfixes_query->major_version < 2) + goto free_screen; + + dri2_query_cookie = xcb_dri2_query_version (scrn->conn, XCB_DRI2_MAJOR_VERSION, XCB_DRI2_MINOR_VERSION); + dri2_query = xcb_dri2_query_version_reply (scrn->conn, dri2_query_cookie, &error); + if (dri2_query == NULL || error != NULL) + goto free_screen; - vl_dri_scrn->display = display; - if (!DRI2Connect(display, XRootWindow(display, screen), &drvName, &devName)) + s = xcb_setup_roots_iterator(xcb_get_setup(scrn->conn)); + connect_cookie = xcb_dri2_connect_unchecked(scrn->conn, s.data->root, XCB_DRI2_DRIVER_TYPE_DRI); + connect = xcb_dri2_connect_reply(scrn->conn, connect_cookie, NULL); + if (connect == NULL || connect->driver_name_length + connect->device_name_length == 0) goto free_screen; - fd = open(devName, O_RDWR); - Xfree(drvName); - Xfree(devName); + device_name = xcb_dri2_connect_device_name(connect); + device_name = strndup(device_name, xcb_dri2_connect_device_name_length(connect)); + fd = open(device_name, O_RDWR); + free(device_name); if (fd < 0) goto free_screen; @@ -176,38 +228,48 @@ vl_screen_create(Display *display, int screen) if (drmGetMagic(fd, &magic)) goto free_screen; - if (!DRI2Authenticate(display, RootWindow(display, screen), magic)) - goto free_screen; + authenticate_cookie = xcb_dri2_authenticate_unchecked(scrn->conn, s.data->root, magic); + authenticate = xcb_dri2_authenticate_reply(scrn->conn, authenticate_cookie, NULL); - vl_dri_scrn->base.pscreen = driver_descriptor.create_screen(fd); + if (authenticate == NULL || !authenticate->authenticated) + goto free_screen; - if (!vl_dri_scrn->base.pscreen) + scrn->base.pscreen = driver_descriptor.create_screen(fd); + if (!scrn->base.pscreen) goto free_screen; - vl_dri_scrn->drawable_table = util_hash_table_create(&drawable_hash, &drawable_cmp); - if (!vl_dri_scrn->drawable_table) - goto no_hash; + scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer; - vl_dri_scrn->last_seen_drawable = None; - vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer; + free(xfixes_query); + free(dri2_query); + free(connect); + free(authenticate); - return &vl_dri_scrn->base; + return &scrn->base; -no_hash: - vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen); free_screen: - FREE(vl_dri_scrn); -no_struct: + FREE(scrn); + + free(xfixes_query); + free(dri2_query); + free(connect); + free(authenticate); + free(error); + return NULL; } void vl_screen_destroy(struct vl_screen *vscreen) { - struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen; + struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen; assert(vscreen); - util_hash_table_destroy(vl_dri_scrn->drawable_table); - vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen); - FREE(vl_dri_scrn); + if (scrn->flushed) + free(xcb_dri2_copy_region_reply(scrn->conn, scrn->flush_cookie, NULL)); + if (scrn->region) + xcb_xfixes_destroy_region(scrn->conn, scrn->region); + vl_dri2_destroy_drawable(scrn); + scrn->base.pscreen->destroy(scrn->base.pscreen); + FREE(scrn); } |