summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-06-26 10:20:52 +0100
committerDave Airlie <airlied@redhat.com>2012-07-07 10:39:10 +0100
commit30298012162de7f76e8a4c7b0362e98703f80011 (patch)
tree22d31a9c13102a29ec55bbf4232f8f5a27953a9f
parent234022cfb3ad2a1b16ab7981ce69f9cd5ba0fbeb (diff)
dri2: add initial prime support. (v1.2)
This adds the initial prime support for dri2 offload. The main thing is when we get a connection from a prime client, we stored the information and mark all drawables from that client as prime. We then create all buffers for that drawable on the prime device dri2screen. Then DRI2UpdatePrime is provided which drivers can call to get a shared pixmap which they can use as the front buffer. The driver is then responsible for doing the back->front copy to the shared buffer. prime requires a compositing manager be run, but it handles the case where a window get un-redirected by allocating a new pixmap and pointing the crtc at it while the client is in that state. Currently prime can't handle pageflipping, so always does straight copy swap, v1.1: renumber on top of master. v1.2: fix auth on top of master. Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--glx/glxdri2.c2
-rw-r--r--hw/xfree86/dri2/dri2.c265
-rw-r--r--hw/xfree86/dri2/dri2.h25
-rw-r--r--hw/xfree86/dri2/dri2ext.c4
4 files changed, 267 insertions, 29 deletions
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 1e99179d4..e0f4cf79e 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -929,7 +929,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
929 return NULL; 929 return NULL;
930 930
931 if (!xf86LoaderCheckSymbol("DRI2Connect") || 931 if (!xf86LoaderCheckSymbol("DRI2Connect") ||
932 !DRI2Connect(pScreen, DRI2DriverDRI, 932 !DRI2Connect(serverClient, pScreen, DRI2DriverDRI,
933 &screen->fd, &driverName, &deviceName)) { 933 &screen->fd, &driverName, &deviceName)) {
934 LogMessage(X_INFO, 934 LogMessage(X_INFO,
935 "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum); 935 "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum);
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index d3b3c73f8..87158ff5c 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -45,7 +45,7 @@
45#include "dixstruct.h" 45#include "dixstruct.h"
46#include "dri2.h" 46#include "dri2.h"
47#include "xf86VGAarbiter.h" 47#include "xf86VGAarbiter.h"
48 48#include "damage.h"
49#include "xf86.h" 49#include "xf86.h"
50 50
51CARD8 dri2_major; /* version of DRI2 supported by DDX */ 51CARD8 dri2_major; /* version of DRI2 supported by DDX */
@@ -63,6 +63,17 @@ static DevPrivateKeyRec dri2PixmapPrivateKeyRec;
63 63
64#define dri2PixmapPrivateKey (&dri2PixmapPrivateKeyRec) 64#define dri2PixmapPrivateKey (&dri2PixmapPrivateKeyRec)
65 65
66static DevPrivateKeyRec dri2ClientPrivateKeyRec;
67
68#define dri2ClientPrivateKey (&dri2ClientPrivateKeyRec)
69
70#define dri2ClientPrivate(_pClient) (dixLookupPrivate(&(_pClient)->devPrivates, \
71 dri2ClientPrivateKey))
72
73typedef struct _DRI2Client {
74 int prime_id;
75} DRI2ClientRec, *DRI2ClientPtr;
76
66static RESTYPE dri2DrawableRes; 77static RESTYPE dri2DrawableRes;
67 78
68typedef struct _DRI2Screen *DRI2ScreenPtr; 79typedef struct _DRI2Screen *DRI2ScreenPtr;
@@ -87,6 +98,9 @@ typedef struct _DRI2Drawable {
87 int swap_limit; /* for N-buffering */ 98 int swap_limit; /* for N-buffering */
88 unsigned long serialNumber; 99 unsigned long serialNumber;
89 Bool needInvalidate; 100 Bool needInvalidate;
101 int prime_id;
102 PixmapPtr prime_slave_pixmap;
103 PixmapPtr redirectpixmap;
90} DRI2DrawableRec, *DRI2DrawablePtr; 104} DRI2DrawableRec, *DRI2DrawablePtr;
91 105
92typedef struct _DRI2Screen { 106typedef struct _DRI2Screen {
@@ -113,14 +127,47 @@ typedef struct _DRI2Screen {
113 HandleExposuresProcPtr HandleExposures; 127 HandleExposuresProcPtr HandleExposures;
114 128
115 ConfigNotifyProcPtr ConfigNotify; 129 ConfigNotifyProcPtr ConfigNotify;
130 DRI2CreateBuffer2ProcPtr CreateBuffer2;
131 DRI2DestroyBuffer2ProcPtr DestroyBuffer2;
132 DRI2CopyRegion2ProcPtr CopyRegion2;
116} DRI2ScreenRec; 133} DRI2ScreenRec;
117 134
135static void
136destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, int prime_id);
137
118static DRI2ScreenPtr 138static DRI2ScreenPtr
119DRI2GetScreen(ScreenPtr pScreen) 139DRI2GetScreen(ScreenPtr pScreen)
120{ 140{
121 return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey); 141 return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey);
122} 142}
123 143
144static ScreenPtr
145GetScreenPrime(ScreenPtr master, int prime_id)
146{
147 ScreenPtr slave;
148 int i;
149
150 if (prime_id == 0 || xorg_list_is_empty(&master->offload_slave_list)) {
151 return master;
152 }
153 i = 0;
154 xorg_list_for_each_entry(slave, &master->offload_slave_list, offload_head) {
155 if (i == (prime_id - 1))
156 break;
157 i++;
158 }
159 if (!slave)
160 return master;
161 return slave;
162}
163
164static DRI2ScreenPtr
165DRI2GetScreenPrime(ScreenPtr master, int prime_id)
166{
167 ScreenPtr slave = GetScreenPrime(master, prime_id);
168 return DRI2GetScreen(slave);
169}
170
124static DRI2DrawablePtr 171static DRI2DrawablePtr
125DRI2GetDrawable(DrawablePtr pDraw) 172DRI2GetDrawable(DrawablePtr pDraw)
126{ 173{
@@ -187,7 +234,8 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
187 xorg_list_init(&pPriv->reference_list); 234 xorg_list_init(&pPriv->reference_list);
188 pPriv->serialNumber = DRI2DrawableSerial(pDraw); 235 pPriv->serialNumber = DRI2DrawableSerial(pDraw);
189 pPriv->needInvalidate = FALSE; 236 pPriv->needInvalidate = FALSE;
190 237 pPriv->redirectpixmap = NULL;
238 pPriv->prime_slave_pixmap = NULL;
191 if (pDraw->type == DRAWABLE_WINDOW) { 239 if (pDraw->type == DRAWABLE_WINDOW) {
192 pWin = (WindowPtr) pDraw; 240 pWin = (WindowPtr) pDraw;
193 dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv); 241 dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
@@ -286,6 +334,7 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
286 DRI2InvalidateProcPtr invalidate, void *priv) 334 DRI2InvalidateProcPtr invalidate, void *priv)
287{ 335{
288 DRI2DrawablePtr pPriv; 336 DRI2DrawablePtr pPriv;
337 DRI2ClientPtr dri2_client = dri2ClientPrivate(client);
289 XID dri2_id; 338 XID dri2_id;
290 int rc; 339 int rc;
291 340
@@ -295,6 +344,8 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
295 if (pPriv == NULL) 344 if (pPriv == NULL)
296 return BadAlloc; 345 return BadAlloc;
297 346
347 pPriv->prime_id = dri2_client->prime_id;
348
298 dri2_id = FakeClientID(client->index); 349 dri2_id = FakeClientID(client->index);
299 rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv); 350 rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv);
300 if (rc != Success) 351 if (rc != Success)
@@ -307,7 +358,6 @@ static int
307DRI2DrawableGone(pointer p, XID id) 358DRI2DrawableGone(pointer p, XID id)
308{ 359{
309 DRI2DrawablePtr pPriv = p; 360 DRI2DrawablePtr pPriv = p;
310 DRI2ScreenPtr ds = pPriv->dri2_screen;
311 DRI2DrawableRefPtr ref, next; 361 DRI2DrawableRefPtr ref, next;
312 WindowPtr pWin; 362 WindowPtr pWin;
313 PixmapPtr pPixmap; 363 PixmapPtr pPixmap;
@@ -347,16 +397,52 @@ DRI2DrawableGone(pointer p, XID id)
347 397
348 if (pPriv->buffers != NULL) { 398 if (pPriv->buffers != NULL) {
349 for (i = 0; i < pPriv->bufferCount; i++) 399 for (i = 0; i < pPriv->bufferCount; i++)
350 (*ds->DestroyBuffer) (pDraw, pPriv->buffers[i]); 400 destroy_buffer(pDraw, pPriv->buffers[i], pPriv->prime_id);
351 401
352 free(pPriv->buffers); 402 free(pPriv->buffers);
353 } 403 }
354 404
405 if (pPriv->redirectpixmap) {
406 (*pDraw->pScreen->ReplaceScanoutPixmap)(pDraw, pPriv->redirectpixmap, FALSE);
407 (*pDraw->pScreen->DestroyPixmap)(pPriv->redirectpixmap);
408 }
409
355 free(pPriv); 410 free(pPriv);
356 411
357 return Success; 412 return Success;
358} 413}
359 414
415static DRI2BufferPtr
416create_buffer(DrawablePtr pDraw,
417 unsigned int attachment, unsigned int format)
418{
419 ScreenPtr primeScreen;
420 DRI2DrawablePtr pPriv;
421 DRI2ScreenPtr ds;
422 DRI2BufferPtr buffer;
423 pPriv = DRI2GetDrawable(pDraw);
424 primeScreen = GetScreenPrime(pDraw->pScreen, pPriv->prime_id);
425 ds = DRI2GetScreenPrime(pDraw->pScreen, pPriv->prime_id);
426 if (ds->CreateBuffer2)
427 buffer = (*ds->CreateBuffer2)(primeScreen, pDraw, attachment, format);
428 else
429 buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
430 return buffer;
431}
432
433static void
434destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, int prime_id)
435{
436 ScreenPtr primeScreen;
437 DRI2ScreenPtr ds;
438 primeScreen = GetScreenPrime(pDraw->pScreen, prime_id);
439 ds = DRI2GetScreen(primeScreen);
440 if (ds->DestroyBuffer2)
441 (*ds->DestroyBuffer2)(primeScreen, pDraw, buffer);
442 else
443 (*ds->DestroyBuffer)(pDraw, buffer);
444}
445
360static int 446static int
361find_attachment(DRI2DrawablePtr pPriv, unsigned attachment) 447find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
362{ 448{
@@ -387,7 +473,7 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
387 if ((old_buf < 0) 473 if ((old_buf < 0)
388 || attachment == DRI2BufferFrontLeft 474 || attachment == DRI2BufferFrontLeft
389 || !dimensions_match || (pPriv->buffers[old_buf]->format != format)) { 475 || !dimensions_match || (pPriv->buffers[old_buf]->format != format)) {
390 *buffer = (*ds->CreateBuffer) (pDraw, attachment, format); 476 *buffer = create_buffer (pDraw, attachment, format);
391 pPriv->serialNumber = DRI2DrawableSerial(pDraw); 477 pPriv->serialNumber = DRI2DrawableSerial(pDraw);
392 return TRUE; 478 return TRUE;
393 479
@@ -408,13 +494,12 @@ update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
408 DRI2BufferPtr * buffers, int out_count, int *width, 494 DRI2BufferPtr * buffers, int out_count, int *width,
409 int *height) 495 int *height)
410{ 496{
411 DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
412 int i; 497 int i;
413 498
414 if (pPriv->buffers != NULL) { 499 if (pPriv->buffers != NULL) {
415 for (i = 0; i < pPriv->bufferCount; i++) { 500 for (i = 0; i < pPriv->bufferCount; i++) {
416 if (pPriv->buffers[i] != NULL) { 501 if (pPriv->buffers[i] != NULL) {
417 (*ds->DestroyBuffer) (pDraw, pPriv->buffers[i]); 502 destroy_buffer(pDraw, pPriv->buffers[i], pPriv->prime_id);
418 } 503 }
419 } 504 }
420 505
@@ -434,8 +519,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
434 unsigned int *attachments, int count, int *out_count, 519 unsigned int *attachments, int count, int *out_count,
435 int has_format) 520 int has_format)
436{ 521{
437 DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
438 DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw); 522 DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
523 DRI2ScreenPtr ds;
439 DRI2BufferPtr *buffers; 524 DRI2BufferPtr *buffers;
440 int need_real_front = 0; 525 int need_real_front = 0;
441 int need_fake_front = 0; 526 int need_fake_front = 0;
@@ -452,6 +537,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
452 return NULL; 537 return NULL;
453 } 538 }
454 539
540 ds = DRI2GetScreen(pDraw->pScreen);
541
455 dimensions_match = (pDraw->width == pPriv->width) 542 dimensions_match = (pDraw->width == pPriv->width)
456 && (pDraw->height == pPriv->height) 543 && (pDraw->height == pPriv->height)
457 && (pPriv->serialNumber == DRI2DrawableSerial(pDraw)); 544 && (pPriv->serialNumber == DRI2DrawableSerial(pDraw));
@@ -556,7 +643,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
556 if (buffers) { 643 if (buffers) {
557 for (i = 0; i < count; i++) { 644 for (i = 0; i < count; i++) {
558 if (buffers[i] != NULL) 645 if (buffers[i] != NULL)
559 (*ds->DestroyBuffer) (pDraw, buffers[i]); 646 destroy_buffer(pDraw, buffers[i], 0);
560 } 647 }
561 648
562 free(buffers); 649 free(buffers);
@@ -650,11 +737,118 @@ DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
650 pPriv->blockedOnMsc = TRUE; 737 pPriv->blockedOnMsc = TRUE;
651} 738}
652 739
740static inline PixmapPtr GetDrawablePixmap(DrawablePtr drawable)
741{
742 if (drawable->type == DRAWABLE_PIXMAP)
743 return (PixmapPtr)drawable;
744 else {
745 struct _Window *pWin = (struct _Window *)drawable;
746 return drawable->pScreen->GetWindowPixmap(pWin);
747 }
748}
749
750DrawablePtr DRI2UpdatePrime(DrawablePtr pDraw, DRI2BufferPtr pDest)
751{
752 DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
753 PixmapPtr spix;
754 PixmapPtr mpix = GetDrawablePixmap(pDraw);
755 ScreenPtr master, slave;
756 Bool ret;
757
758 master = mpix->drawable.pScreen;
759
760 if (pDraw->type == DRAWABLE_WINDOW) {
761 WindowPtr pWin = (WindowPtr)pDraw;
762 PixmapPtr pPixmap = pDraw->pScreen->GetWindowPixmap(pWin);
763
764 if (pDraw->pScreen->GetScreenPixmap(pDraw->pScreen) == pPixmap) {
765 if (pPriv->redirectpixmap &&
766 pPriv->redirectpixmap->drawable.width == pDraw->width &&
767 pPriv->redirectpixmap->drawable.height == pDraw->height &&
768 pPriv->redirectpixmap->drawable.depth == pDraw->depth) {
769 mpix = pPriv->redirectpixmap;
770 } else {
771 if (master->ReplaceScanoutPixmap) {
772 mpix = (*master->CreatePixmap)(master, pDraw->width, pDraw->height,
773 pDraw->depth, CREATE_PIXMAP_USAGE_SHARED);
774 if (!mpix)
775 return NULL;
776
777 ret = (*master->ReplaceScanoutPixmap)(pDraw, mpix, TRUE);
778 if (ret == FALSE) {
779 (*master->DestroyPixmap)(mpix);
780 return NULL;
781 }
782 pPriv->redirectpixmap = mpix;
783 } else
784 return NULL;
785 }
786 } else if (pPriv->redirectpixmap) {
787 (*master->ReplaceScanoutPixmap)(pDraw, pPriv->redirectpixmap, FALSE);
788 (*master->DestroyPixmap)(pPriv->redirectpixmap);
789 pPriv->redirectpixmap = NULL;
790 }
791 }
792
793 slave = GetScreenPrime(pDraw->pScreen, pPriv->prime_id);
794
795 /* check if the pixmap is still fine */
796 if (pPriv->prime_slave_pixmap) {
797 if (pPriv->prime_slave_pixmap->master_pixmap == mpix)
798 return &pPriv->prime_slave_pixmap->drawable;
799 else {
800 (*master->DestroyPixmap)(pPriv->prime_slave_pixmap->master_pixmap);
801 (*slave->DestroyPixmap)(pPriv->prime_slave_pixmap);
802 }
803 }
804
805 spix = PixmapShareToSlave(mpix, slave);
806 if (!spix)
807 return NULL;
808
809 pPriv->prime_slave_pixmap = spix;
810#ifdef COMPOSITE
811 spix->screen_x = mpix->screen_x;
812 spix->screen_y = mpix->screen_y;
813#endif
814 return &spix->drawable;
815}
816
817static void dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
818 DRI2BufferPtr pDest, DRI2BufferPtr pSrc)
819{
820 DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
821 DRI2ScreenPtr ds;
822 ScreenPtr primeScreen;
823
824 primeScreen = GetScreenPrime(pDraw->pScreen, pPriv->prime_id);
825 ds = DRI2GetScreen(primeScreen);
826
827 if (ds->CopyRegion2)
828 (*ds->CopyRegion2)(primeScreen, pDraw, pRegion, pDest, pSrc);
829 else
830 (*ds->CopyRegion) (pDraw, pRegion, pDest, pSrc);
831
832 /* cause damage to the box */
833 if (pPriv->prime_id) {
834 BoxRec box;
835 RegionRec region;
836 box.x1 = 0;
837 box.x2 = box.x1 + pDraw->width;
838 box.y1 = 0;
839 box.y2 = box.y1 + pDraw->height;
840 RegionInit(&region, &box, 1);
841 RegionTranslate(&region, pDraw->x, pDraw->y);
842 DamageRegionAppend(pDraw, &region);
843 DamageRegionProcessPending(pDraw);
844 RegionUninit(&region);
845 }
846}
847
653int 848int
654DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, 849DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
655 unsigned int dest, unsigned int src) 850 unsigned int dest, unsigned int src)
656{ 851{
657 DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
658 DRI2DrawablePtr pPriv; 852 DRI2DrawablePtr pPriv;
659 DRI2BufferPtr pDestBuffer, pSrcBuffer; 853 DRI2BufferPtr pDestBuffer, pSrcBuffer;
660 int i; 854 int i;
@@ -674,7 +868,7 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
674 if (pSrcBuffer == NULL || pDestBuffer == NULL) 868 if (pSrcBuffer == NULL || pDestBuffer == NULL)
675 return BadValue; 869 return BadValue;
676 870
677 (*ds->CopyRegion) (pDraw, pRegion, pDestBuffer, pSrcBuffer); 871 dri2_copy_region(pDraw, pRegion, pDestBuffer, pSrcBuffer);
678 872
679 return Success; 873 return Success;
680} 874}
@@ -879,7 +1073,7 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
879 } 1073 }
880 1074
881 /* Old DDX or no swap interval, just blit */ 1075 /* Old DDX or no swap interval, just blit */
882 if (!ds->ScheduleSwap || !pPriv->swap_interval) { 1076 if (!ds->ScheduleSwap || !pPriv->swap_interval || pPriv->prime_id) {
883 BoxRec box; 1077 BoxRec box;
884 RegionRec region; 1078 RegionRec region;
885 1079
@@ -891,7 +1085,7 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
891 1085
892 pPriv->swapsPending++; 1086 pPriv->swapsPending++;
893 1087
894 (*ds->CopyRegion) (pDraw, &region, pDestBuffer, pSrcBuffer); 1088 dri2_copy_region(pDraw, &region, pDestBuffer, pSrcBuffer);
895 DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE, 1089 DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE,
896 func, data); 1090 func, data);
897 return Success; 1091 return Success;
@@ -1091,22 +1285,34 @@ DRI2HasSwapControl(ScreenPtr pScreen)
1091} 1285}
1092 1286
1093Bool 1287Bool
1094DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd, 1288DRI2Connect(ClientPtr client, ScreenPtr pScreen,
1289 unsigned int driverType, int *fd,
1095 const char **driverName, const char **deviceName) 1290 const char **driverName, const char **deviceName)
1096{ 1291{
1097 DRI2ScreenPtr ds; 1292 DRI2ScreenPtr ds;
1293 uint32_t prime_id = DRI2DriverPrimeId(driverType);
1294 uint32_t driver_id = driverType & 0xffff;
1098 1295
1099 if (!dixPrivateKeyRegistered(dri2ScreenPrivateKey)) 1296 if (!dixPrivateKeyRegistered(dri2ScreenPrivateKey))
1100 return FALSE; 1297 return FALSE;
1101 1298
1102 ds = DRI2GetScreen(pScreen); 1299 ds = DRI2GetScreenPrime(pScreen, prime_id);
1103 if (ds == NULL || driverType >= ds->numDrivers || 1300 if (ds == NULL)
1104 !ds->driverNames[driverType])
1105 return FALSE; 1301 return FALSE;
1106 1302
1107 *fd = ds->fd; 1303 if (driver_id >= ds->numDrivers ||
1108 *driverName = ds->driverNames[driverType]; 1304 !ds->driverNames[driver_id])
1305 return FALSE;
1306
1307 *driverName = ds->driverNames[driver_id];
1109 *deviceName = ds->deviceName; 1308 *deviceName = ds->deviceName;
1309 *fd = ds->fd;
1310
1311 if (client) {
1312 DRI2ClientPtr dri2_client;
1313 dri2_client = dri2ClientPrivate(client);
1314 dri2_client->prime_id = prime_id;
1315 }
1110 1316
1111 return TRUE; 1317 return TRUE;
1112} 1318}
@@ -1122,13 +1328,19 @@ DRI2AuthMagic (ScreenPtr pScreen, uint32_t magic)
1122} 1328}
1123 1329
1124Bool 1330Bool
1125DRI2Authenticate(ScreenPtr pScreen, uint32_t magic) 1331DRI2Authenticate(ClientPtr client, ScreenPtr pScreen, uint32_t magic)
1126{ 1332{
1127 DRI2ScreenPtr ds = DRI2GetScreen(pScreen); 1333 DRI2ScreenPtr ds;
1334 DRI2ClientPtr dri2_client = dri2ClientPrivate(client);
1335 ScreenPtr primescreen;
1128 1336
1129 if (ds == NULL || (*ds->AuthMagic) (pScreen, magic)) 1337 ds = DRI2GetScreenPrime(pScreen, dri2_client->prime_id);
1338 if (ds == NULL)
1130 return FALSE; 1339 return FALSE;
1131 1340
1341 primescreen = GetScreenPrime(pScreen, dri2_client->prime_id);
1342 if ((*ds->AuthMagic)(primescreen, magic))
1343 return FALSE;
1132 return TRUE; 1344 return TRUE;
1133} 1345}
1134 1346
@@ -1190,6 +1402,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
1190 if (!dixRegisterPrivateKey(&dri2PixmapPrivateKeyRec, PRIVATE_PIXMAP, 0)) 1402 if (!dixRegisterPrivateKey(&dri2PixmapPrivateKeyRec, PRIVATE_PIXMAP, 0))
1191 return FALSE; 1403 return FALSE;
1192 1404
1405 if (!dixRegisterPrivateKey(&dri2ClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(DRI2ClientRec)))
1406 return FALSE;
1407
1193 ds = calloc(1, sizeof *ds); 1408 ds = calloc(1, sizeof *ds);
1194 if (!ds) 1409 if (!ds)
1195 return FALSE; 1410 return FALSE;
@@ -1230,6 +1445,12 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
1230 cur_minor = 4; 1445 cur_minor = 4;
1231 } 1446 }
1232 1447
1448 if (info->version >= 9) {
1449 ds->CreateBuffer2 = info->CreateBuffer2;
1450 ds->DestroyBuffer2 = info->DestroyBuffer2;
1451 ds->CopyRegion2 = info->CopyRegion2;
1452 }
1453
1233 /* 1454 /*
1234 * if the driver doesn't provide an AuthMagic function or the info struct 1455 * if the driver doesn't provide an AuthMagic function or the info struct
1235 * version is too low, call through LegacyAuthMagic 1456 * version is too low, call through LegacyAuthMagic
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 4fd0fbc52..a59e680be 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -176,6 +176,18 @@ typedef void (*DRI2InvalidateProcPtr) (DrawablePtr pDraw, void *data, XID id);
176typedef Bool (*DRI2SwapLimitValidateProcPtr) (DrawablePtr pDraw, 176typedef Bool (*DRI2SwapLimitValidateProcPtr) (DrawablePtr pDraw,
177 int swap_limit); 177 int swap_limit);
178 178
179typedef DRI2BufferPtr(*DRI2CreateBuffer2ProcPtr) (ScreenPtr pScreen,
180 DrawablePtr pDraw,
181 unsigned int attachment,
182 unsigned int format);
183typedef void (*DRI2DestroyBuffer2ProcPtr) (ScreenPtr pScreen, DrawablePtr pDraw,
184 DRI2BufferPtr buffer);
185
186typedef void (*DRI2CopyRegion2ProcPtr) (ScreenPtr pScreen, DrawablePtr pDraw,
187 RegionPtr pRegion,
188 DRI2BufferPtr pDestBuffer,
189 DRI2BufferPtr pSrcBuffer);
190
179/** 191/**
180 * \brief Get the value of a parameter. 192 * \brief Get the value of a parameter.
181 * 193 *
@@ -193,7 +205,7 @@ typedef int (*DRI2GetParamProcPtr) (ClientPtr client,
193/** 205/**
194 * Version of the DRI2InfoRec structure defined in this header 206 * Version of the DRI2InfoRec structure defined in this header
195 */ 207 */
196#define DRI2INFOREC_VERSION 8 208#define DRI2INFOREC_VERSION 9
197 209
198typedef struct { 210typedef struct {
199 unsigned int version; /**< Version of this struct */ 211 unsigned int version; /**< Version of this struct */
@@ -228,7 +240,6 @@ typedef struct {
228 DRI2SwapLimitValidateProcPtr SwapLimitValidate; 240 DRI2SwapLimitValidateProcPtr SwapLimitValidate;
229 241
230 /* added in version 7 */ 242 /* added in version 7 */
231
232 DRI2GetParamProcPtr GetParam; 243 DRI2GetParamProcPtr GetParam;
233 244
234 /* added in version 8 */ 245 /* added in version 8 */
@@ -236,6 +247,11 @@ typedef struct {
236 /* If this is NULL the AuthMagic callback is used */ 247 /* If this is NULL the AuthMagic callback is used */
237 /* If this is non-NULL the AuthMagic callback is ignored */ 248 /* If this is non-NULL the AuthMagic callback is ignored */
238 DRI2AuthMagic2ProcPtr AuthMagic2; 249 DRI2AuthMagic2ProcPtr AuthMagic2;
250
251 /* added in version 9 */
252 DRI2CreateBuffer2ProcPtr CreateBuffer2;
253 DRI2DestroyBuffer2ProcPtr DestroyBuffer2;
254 DRI2CopyRegion2ProcPtr CopyRegion2;
239} DRI2InfoRec, *DRI2InfoPtr; 255} DRI2InfoRec, *DRI2InfoPtr;
240 256
241extern _X_EXPORT int DRI2EventBase; 257extern _X_EXPORT int DRI2EventBase;
@@ -246,13 +262,13 @@ extern _X_EXPORT void DRI2CloseScreen(ScreenPtr pScreen);
246 262
247extern _X_EXPORT Bool DRI2HasSwapControl(ScreenPtr pScreen); 263extern _X_EXPORT Bool DRI2HasSwapControl(ScreenPtr pScreen);
248 264
249extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen, 265extern _X_EXPORT Bool DRI2Connect(ClientPtr client, ScreenPtr pScreen,
250 unsigned int driverType, 266 unsigned int driverType,
251 int *fd, 267 int *fd,
252 const char **driverName, 268 const char **driverName,
253 const char **deviceName); 269 const char **deviceName);
254 270
255extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, uint32_t magic); 271extern _X_EXPORT Bool DRI2Authenticate(ClientPtr client, ScreenPtr pScreen, uint32_t magic);
256 272
257extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client, 273extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
258 DrawablePtr pDraw, 274 DrawablePtr pDraw,
@@ -339,4 +355,5 @@ extern _X_EXPORT int DRI2GetParam(ClientPtr client,
339 BOOL *is_param_recognized, 355 BOOL *is_param_recognized,
340 CARD64 *value); 356 CARD64 *value);
341 357
358extern _X_EXPORT DrawablePtr DRI2UpdatePrime(DrawablePtr pDraw, DRI2BufferPtr pDest);
342#endif 359#endif
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index c6f5b4e11..3bc3ea74e 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -116,7 +116,7 @@ ProcDRI2Connect(ClientPtr client)
116 rep.driverNameLength = 0; 116 rep.driverNameLength = 0;
117 rep.deviceNameLength = 0; 117 rep.deviceNameLength = 0;
118 118
119 if (!DRI2Connect(pDraw->pScreen, 119 if (!DRI2Connect(client, pDraw->pScreen,
120 stuff->driverType, &fd, &driverName, &deviceName)) 120 stuff->driverType, &fd, &driverName, &deviceName))
121 goto fail; 121 goto fail;
122 122
@@ -149,7 +149,7 @@ ProcDRI2Authenticate(ClientPtr client)
149 rep.type = X_Reply; 149 rep.type = X_Reply;
150 rep.sequenceNumber = client->sequence; 150 rep.sequenceNumber = client->sequence;
151 rep.length = 0; 151 rep.length = 0;
152 rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic); 152 rep.authenticated = DRI2Authenticate(client, pDraw->pScreen, stuff->magic);
153 WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep); 153 WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
154 154
155 return Success; 155 return Success;