diff options
author | Dave Airlie <airlied@redhat.com> | 2012-04-30 14:29:12 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-04-30 14:29:12 +0100 |
commit | cd0d162a5f51edefa7773a9a3d8eee138f95cd1f (patch) | |
tree | d48937baff5556958e0caff5abc3904cac131792 | |
parent | d381abf2655bd6752469567570e0afa572f0f0a7 (diff) |
dri2: add imped layer 1
this gets the gears turning
-rw-r--r-- | hw/xfree86/dri2/Makefile.am | 3 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2.c | 56 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2.h | 20 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2_priv.h | 46 | ||||
-rw-r--r-- | hw/xfree86/dri2/imped_dri2.c | 270 |
5 files changed, 350 insertions, 45 deletions
diff --git a/hw/xfree86/dri2/Makefile.am b/hw/xfree86/dri2/Makefile.am index c9fdde2f8..f21626cc6 100644 --- a/hw/xfree86/dri2/Makefile.am +++ b/hw/xfree86/dri2/Makefile.am @@ -11,6 +11,7 @@ libdri2_ladir = $(moduledir)/extensions libdri2_la_SOURCES = \ dri2.c \ dri2.h \ - dri2ext.c + dri2ext.c \ + imped_dri2.c sdk_HEADERS = dri2.h diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index c9a290544..61f668d71 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -47,13 +47,13 @@ #include "xf86VGAarbiter.h" #include "xf86.h" - +#include "dri2_priv.h" +extern Bool impedDRI2ScreenInit(ScreenPtr screen); CARD8 dri2_major; /* version of DRI2 supported by DDX */ CARD8 dri2_minor; -static DevPrivateKeyRec dri2ScreenPrivateKeyRec; +DevPrivateKeyRec dri2ScreenPrivateKeyRec; -#define dri2ScreenPrivateKey (&dri2ScreenPrivateKeyRec) static DevPrivateKeyRec dri2WindowPrivateKeyRec; @@ -76,8 +76,6 @@ typedef struct _DRI2Client { static RESTYPE dri2DrawableRes; -typedef struct _DRI2Screen *DRI2ScreenPtr; - typedef struct _DRI2Drawable { DRI2ScreenPtr dri2_screen; DrawablePtr drawable; @@ -101,40 +99,6 @@ typedef struct _DRI2Drawable { int prime_id; } DRI2DrawableRec, *DRI2DrawablePtr; -typedef struct _DRI2Screen { - ScreenPtr screen; - int refcnt; - unsigned int numDrivers; - const char **driverNames; - const char *deviceName; - int fd; - unsigned int lastSequence; - - DRI2CreateBufferProcPtr CreateBuffer; - DRI2DestroyBufferProcPtr DestroyBuffer; - DRI2CopyRegionProcPtr CopyRegion; - DRI2ScheduleSwapProcPtr ScheduleSwap; - DRI2GetMSCProcPtr GetMSC; - DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC; - DRI2AuthMagicProcPtr AuthMagic; - DRI2ReuseBufferNotifyProcPtr ReuseBufferNotify; - DRI2SwapLimitValidateProcPtr SwapLimitValidate; - - HandleExposuresProcPtr HandleExposures; - - ConfigNotifyProcPtr ConfigNotify; - - DRI2GetDriverInfoProcPtr GetDriverInfo; - DRI2AuthMagic2ProcPtr AuthMagic2; - DRI2CreateBuffer2ProcPtr CreateBuffer2; - -} DRI2ScreenRec; - -static DRI2ScreenPtr -DRI2GetScreen(ScreenPtr pScreen) -{ - return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey); -} static DRI2DrawablePtr DRI2GetDrawable(DrawablePtr pDraw) @@ -406,7 +370,7 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds, || attachment == DRI2BufferFrontLeft || !dimensions_match || (pPriv->buffers[old_buf]->format != format)) { if (*ds->CreateBuffer2) - *buffer = (*ds->CreateBuffer2) (pDraw, attachment, format, pPriv->prime_id); + *buffer = (*ds->CreateBuffer2) (pDraw, attachment, format, pPriv->prime_id, pDraw->width, pDraw->height); else *buffer = (*ds->CreateBuffer) (pDraw, attachment, format); pPriv->serialNumber = DRI2DrawableSerial(pDraw); @@ -1129,7 +1093,7 @@ DRI2Connect(ClientPtr client, ScreenPtr pScreen, if (ds->GetDriverInfo) { ret = ds->GetDriverInfo(pScreen, driverType, &prime_id, - driverName, deviceName); + fd, driverName, deviceName); if (ret == FALSE) return ret; } else { @@ -1139,8 +1103,8 @@ DRI2Connect(ClientPtr client, ScreenPtr pScreen, *driverName = ds->driverNames[driverType]; *deviceName = ds->deviceName; + *fd = ds->fd; } - *fd = ds->fd; if (client) { DRI2ClientPtr dri2_client; @@ -1243,6 +1207,10 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) if (!DRI2InitPrivates()) return FALSE; + if (!drv_dri2_hook) + drv_dri2_hook = impedDRI2ScreenInit; + + ds = calloc(1, sizeof *ds); if (!ds) return FALSE; @@ -1279,6 +1247,10 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) ds->CreateBuffer2 = info->CreateBuffer2; ds->AuthMagic2 = info->AuthMagic2; ds->GetDriverInfo = info->GetDriverInfo; + + ds->CreateBufferPixmap = info->CreateBufferPixmap; + ds->DestroyBufferPixmap = info->DestroyBufferPixmap; + ds->CopyRegionPixmap = info->CopyRegionPixmap; } /* diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index b60ea136f..4946fa806 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -178,18 +178,27 @@ typedef Bool (*DRI2SwapLimitValidateProcPtr) (DrawablePtr pDraw, typedef Bool (*DRI2GetDriverInfoProcPtr)(ScreenPtr pScreen, int driverType, uint32_t *is_prime, + int *fd, const char **drivername, const char **deviceName); typedef DRI2BufferPtr (*DRI2CreateBuffer2ProcPtr)(DrawablePtr pDraw, unsigned int attachment, unsigned int format, - unsigned int prime_id); + unsigned int prime_id, int w, int h); typedef int (*DRI2AuthMagic2ProcPtr)(ScreenPtr pScreen, int prime_id, uint32_t magic); +typedef PixmapPtr (*DRI2CreateBufferPixmapProcPtr)(ScreenPtr pScreen, + PixmapPtr pPixmap, + unsigned int attachment, + unsigned int format, + int w, int h, + uint32_t *name); +typedef void (*DRI2DestroyBufferPixmapProcPtr)(PixmapPtr pPixmap); + typedef void (*DRI2CopyPixmapPtrCB)(PixmapPtr src, PixmapPtr dst, RegionPtr pRegion, RegionPtr front_clip); @@ -233,11 +242,15 @@ typedef struct { DRI2ReuseBufferNotifyProcPtr ReuseBufferNotify; DRI2SwapLimitValidateProcPtr SwapLimitValidate; - /* added in version 7 */ + /* added in version 7 for driver -> impedance layer */ DRI2GetDriverInfoProcPtr GetDriverInfo; DRI2AuthMagic2ProcPtr AuthMagic2; DRI2CreateBuffer2ProcPtr CreateBuffer2; + /* new driver interfaces in version 7 */ + DRI2CreateBufferPixmapProcPtr CreateBufferPixmap; + DRI2DestroyBufferPixmapProcPtr DestroyBufferPixmap; + DRI2CopyRegionPixmapProcPtr CopyRegionPixmap; } DRI2InfoRec, *DRI2InfoPtr; @@ -341,6 +354,7 @@ enum DRI2FrameEventType { DRI2_SWAP, DRI2_FLIP, DRI2_WAITMSC, + DRI2_SWAP_CHAIN, }; typedef struct _DRI2FrameEvent { @@ -367,4 +381,6 @@ extern _X_EXPORT void DRI2FlipEventHandler(DRI2FrameEventPtr flip, unsigned int frame, unsigned int tv_sec, unsigned int tv_usec); + + #endif diff --git a/hw/xfree86/dri2/dri2_priv.h b/hw/xfree86/dri2/dri2_priv.h new file mode 100644 index 000000000..2a03cb945 --- /dev/null +++ b/hw/xfree86/dri2/dri2_priv.h @@ -0,0 +1,46 @@ +#ifndef DRI2_PRIV_H +#define DRI2_PRIV_H +typedef struct _DRI2Screen { + ScreenPtr screen; + int refcnt; + unsigned int numDrivers; + const char **driverNames; + const char *deviceName; + int fd; + unsigned int lastSequence; + + DRI2CreateBufferProcPtr CreateBuffer; + DRI2DestroyBufferProcPtr DestroyBuffer; + DRI2CopyRegionProcPtr CopyRegion; + DRI2ScheduleSwapProcPtr ScheduleSwap; + DRI2GetMSCProcPtr GetMSC; + DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC; + DRI2AuthMagicProcPtr AuthMagic; + DRI2ReuseBufferNotifyProcPtr ReuseBufferNotify; + DRI2SwapLimitValidateProcPtr SwapLimitValidate; + + HandleExposuresProcPtr HandleExposures; + + ConfigNotifyProcPtr ConfigNotify; + + DRI2GetDriverInfoProcPtr GetDriverInfo; + DRI2AuthMagic2ProcPtr AuthMagic2; + DRI2CreateBuffer2ProcPtr CreateBuffer2; + + DRI2CreateBufferPixmapProcPtr CreateBufferPixmap; + DRI2DestroyBufferPixmapProcPtr DestroyBufferPixmap; + DRI2CopyRegionPixmapProcPtr CopyRegionPixmap; + +} DRI2ScreenRec; + +typedef struct _DRI2Screen *DRI2ScreenPtr; + +extern DevPrivateKeyRec dri2ScreenPrivateKeyRec; +#define dri2ScreenPrivateKey (&dri2ScreenPrivateKeyRec) + +static inline DRI2ScreenPtr +DRI2GetScreen(ScreenPtr pScreen) +{ + return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey); +} +#endif diff --git a/hw/xfree86/dri2/imped_dri2.c b/hw/xfree86/dri2/imped_dri2.c new file mode 100644 index 000000000..807a8c725 --- /dev/null +++ b/hw/xfree86/dri2/imped_dri2.c @@ -0,0 +1,270 @@ +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <errno.h> +#ifdef WITH_LIBDRM +#include <xf86drm.h> +#endif +#include "xf86Module.h" +#include "list.h" +#include "windowstr.h" + +#include "dri2.h" +#include "dri2_priv.h" + +typedef struct { + int refcnt; + PixmapPtr pixmap; + unsigned int attachment; + void *driverPrivate; + PixmapPtr prime_pixmap; + int prime_id; +} impedDRI2BufferPrivateRec, *impedDRI2BufferPrivatePtr; + +/* impedance layer for DRI2 */ +/* always appear as a version 7 layer (??) */ + +static ScreenPtr +GetScreenPrime(ScreenPtr master, int prime_id) +{ + ScreenPtr slave; + int i; + + if (prime_id == 0 || xorg_list_is_empty(&master->offload_slave_list)) { + return master->gpu[master->primary_gpu_index]; + } + i = 0; + xorg_list_for_each_entry(slave, &master->offload_slave_list, offload_head) { + if (i == (prime_id - 1)) + break; + i++; + } + if (!slave) + return master->gpu[master->primary_gpu_index]; + /* TODO */ + return master->gpu[master->primary_gpu_index]; +} + + +static DRI2ScreenPtr +DRI2GetScreenPrime(ScreenPtr master, int prime_id) +{ + ScreenPtr slave = GetScreenPrime(master, prime_id); + return DRI2GetScreen(slave); +} + +static Bool imped_dri2_get_driver_info(ScreenPtr pScreen, + int driverType, + uint32_t *is_prime, + int *fd, + const char **drivername, + const char **devicename) +{ + int prime_id = DRI2DriverPrimeId(driverType); + int driver_id = driverType & 0xffff; + DRI2ScreenPtr gpu_ds = DRI2GetScreenPrime(pScreen, prime_id); + + if (driver_id >= gpu_ds->numDrivers || + !gpu_ds->driverNames[driver_id]) + return FALSE; + + *is_prime = prime_id; + *drivername = gpu_ds->driverNames[driver_id]; + *devicename = gpu_ds->deviceName; + *fd = gpu_ds->fd; + return TRUE; +} + +static DRI2BufferPtr imped_dri2_create_buffer2(DrawablePtr pDraw, + unsigned int attachment, + unsigned int format, + unsigned int prime_id, int w, int h) +{ + ScreenPtr gpuScreen = GetScreenPrime(pDraw->pScreen, prime_id); + DRI2ScreenPtr gpu_ds = DRI2GetScreen(gpuScreen); + PixmapPtr pPixmap = GetDrawablePixmap(pDraw); + PixmapPtr gpuPixmap = pPixmap->gpu[pDraw->pScreen->primary_gpu_index]; + DRI2BufferPtr buffer; + PixmapPtr pixmap; + uint32_t name; + impedDRI2BufferPrivatePtr privates; + + buffer = calloc(1, sizeof *buffer); + if (buffer == NULL) + return NULL; + + privates = calloc(1, sizeof *privates); + if (privates == NULL) { + free(buffer); + return NULL; + } + + pixmap = gpu_ds->CreateBufferPixmap(gpuScreen, gpuPixmap, attachment, format, + pDraw->width, pDraw->height, + &name); + + if (pixmap) { + buffer->pitch = pixmap->devKind; + buffer->cpp = pixmap->drawable.bitsPerPixel / 8; + } + buffer->attachment = attachment; + buffer->driverPrivate = privates; + buffer->format = format; + buffer->flags = 0; + buffer->name = name; + privates->refcnt = 1; + privates->pixmap = pixmap; + privates->attachment = attachment; + privates->prime_id = prime_id; + return buffer; +} + +static int imped_dri2_auth_magic2(ScreenPtr pScreen, + int prime_id, + uint32_t magic) +{ + DRI2ScreenPtr gpu_ds = DRI2GetScreenPrime(pScreen, prime_id); + + if ((*gpu_ds->AuthMagic)(gpu_ds->fd, magic)) + return -1; + return 0; +} + +static void imped_dri2_destroy_buffer(DrawablePtr pDraw, + DRI2BufferPtr buffer) +{ + impedDRI2BufferPrivatePtr private; + PixmapPtr pPixmap = GetDrawablePixmap(pDraw); + PixmapPtr gpuPixmap = pPixmap->gpu[pDraw->pScreen->primary_gpu_index]; + + if (!buffer) + return; + + private = buffer->driverPrivate; + if (--private->refcnt == 0) { + if (private->pixmap) { + DRI2ScreenPtr gpu_ds = DRI2GetScreen(private->pixmap->drawable.pScreen); + gpu_ds->DestroyBufferPixmap(private->pixmap); + } + free(private); + free(buffer); + } +} + +static void +imped_dri2_copy_region_callback(PixmapPtr src, PixmapPtr dst, + RegionPtr pRegion, RegionPtr front_clip) +{ + miCopyProc copy; + int nbox; + GCPtr gc; + BoxPtr pbox; + + copy = src->drawable.pScreen->GetCopyAreaFunction(&src->drawable, &dst->drawable); + + gc = GetScratchGC(dst->drawable.depth, src->drawable.pScreen); + if (!gc) + return; + + ValidateGC(&dst->drawable, gc); + nbox = RegionNumRects(pRegion); + pbox = RegionRects(pRegion); + copy(&src->drawable, &dst->drawable, gc, pbox, nbox, 0, 0, 0, 0, 0, NULL); + FreeScratchGC(gc); +} + + +static void +imped_copy_region(PixmapPtr pixmap, RegionPtr pRegion, + DRI2BufferPtr dst_buffer, DRI2BufferPtr src_buffer) +{ + impedDRI2BufferPrivatePtr src_private = src_buffer->driverPrivate; + impedDRI2BufferPrivatePtr dst_private = dst_buffer->driverPrivate; + PixmapPtr src, dst; + + ScreenPtr pScreen = pixmap->drawable.pScreen; + DRI2ScreenPtr gpu_ds = DRI2GetScreen(pScreen); + + src = src_private->pixmap; + dst = dst_private->pixmap; + + gpu_ds->CopyRegionPixmap(src, dst, pRegion, NULL, imped_dri2_copy_region_callback); +} + +static void imped_dri2_copy_region(DrawablePtr pDraw, + RegionPtr pRegion, + DRI2BufferPtr pDestBuffer, + DRI2BufferPtr pSrcBuffer) +{ + ScreenPtr gpuSceren = pDraw->pScreen->gpu[pDraw->pScreen->primary_gpu_index]; + PixmapPtr pPixmap = GetDrawablePixmap(pDraw); + PixmapPtr src; + PixmapPtr dst; + + ErrorF("draw copy region %d %dx%d vs p %dx%d\n", pDraw->type, pDraw->width, pDraw->height, pPixmap->drawable.width, pPixmap->drawable.height); + + imped_copy_region(pPixmap->gpu[pDraw->pScreen->primary_gpu_index], pRegion, pDestBuffer, pSrcBuffer); + + if (pDraw->type == DRAWABLE_WINDOW) { + /* translate */ + } + +} + +static int imped_dri2_schedule_swap(ClientPtr client, + DrawablePtr pDraw, + DRI2BufferPtr pDestBuffer, + DRI2BufferPtr pSrcBuffer, + CARD64 * target_msc, + CARD64 divisor, + CARD64 remainder, + DRI2SwapEventPtr func, void *data) +{ + ScreenPtr pScreen = pDraw->pScreen; + PixmapPtr pPixmap = GetDrawablePixmap(pDraw); + // DRI2ScreenPtr gpu_ds = DRI2GetScreenPrime(pDraw->pScreen, buffer->prime_id); + BoxRec box; + RegionRec region; + + blit_fallback: + box.x1 = 0; + box.y1 = 0; + box.x2 = pDraw->width; + box.y2 = pDraw->height; + + RegionInit(®ion, &box, 0); + + imped_dri2_copy_region(pDraw, ®ion, pDestBuffer, pSrcBuffer); + DRI2SwapComplete(client, pDraw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data); + return TRUE; +} + +static int imped_dri2_get_msc(DrawablePtr pDraw, CARD64 *ust, CARD64 *msc) +{ + return 0; +} + +Bool impedDRI2ScreenInit(ScreenPtr screen) +{ + DRI2InfoRec info; + const char *driverNames[1]; + + memset(&info, 0, sizeof(info)); + info.version = 7; + info.CreateBuffer2 = imped_dri2_create_buffer2; + info.DestroyBuffer = imped_dri2_destroy_buffer; + info.AuthMagic2 = imped_dri2_auth_magic2; + info.GetDriverInfo = imped_dri2_get_driver_info; + info.CopyRegion = imped_dri2_copy_region; + info.ScheduleSwap = imped_dri2_schedule_swap; + info.GetMSC = imped_dri2_get_msc; + info.numDrivers = 1; + driverNames[0] = "hotplug"; + info.driverNames = driverNames; + info.deviceName = NULL; + info.fd = -1; + DRI2ScreenInit(screen, &info); + + return TRUE; +} |