summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-04-30 14:29:12 +0100
committerDave Airlie <airlied@redhat.com>2012-04-30 14:29:12 +0100
commitcd0d162a5f51edefa7773a9a3d8eee138f95cd1f (patch)
treed48937baff5556958e0caff5abc3904cac131792
parentd381abf2655bd6752469567570e0afa572f0f0a7 (diff)
dri2: add imped layer 1
this gets the gears turning
-rw-r--r--hw/xfree86/dri2/Makefile.am3
-rw-r--r--hw/xfree86/dri2/dri2.c56
-rw-r--r--hw/xfree86/dri2/dri2.h20
-rw-r--r--hw/xfree86/dri2/dri2_priv.h46
-rw-r--r--hw/xfree86/dri2/imped_dri2.c270
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(&region, &box, 0);
+
+ imped_dri2_copy_region(pDraw, &region, 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;
+}