summaryrefslogtreecommitdiff
path: root/src/x11/dri1_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/x11/dri1_util.c')
-rw-r--r--src/x11/dri1_util.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/x11/dri1_util.c b/src/x11/dri1_util.c
new file mode 100644
index 0000000..b3db5b4
--- /dev/null
+++ b/src/x11/dri1_util.c
@@ -0,0 +1,158 @@
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#include <xf86drm.h>
+
+#include "X11/Xlib.h"
+#include "va.h"
+#include "va_backend.h"
+
+#include "va_dri.h"
+#include "va_dricommon.h"
+
+struct dri1_drawable
+{
+ struct dri_drawable base;
+ union dri_buffer buffer;
+ int width;
+ int height;
+};
+
+static struct dri_drawable *
+dri1CreateDrawable(VADriverContextP ctx, XID x_drawable)
+{
+ struct dri1_drawable *dri1_drawable;
+
+ dri1_drawable = calloc(1, sizeof(*dri1_drawable));
+
+ if (!dri1_drawable)
+ return NULL;
+
+ dri1_drawable->base.x_drawable = x_drawable;
+
+ return &dri1_drawable->base;
+}
+
+static void
+dri1DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+ free(dri_drawable);
+}
+
+static void
+dri1SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+
+}
+
+static union dri_buffer *
+dri1GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+ struct dri1_drawable *dri1_drawable = (struct dri1_drawable *)dri_drawable;
+
+ return &dri1_drawable->buffer;
+}
+
+static void
+dri1Close(VADriverContextP ctx)
+{
+ struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+
+ free_drawable_hashtable(ctx);
+ VA_DRIDestroyContext(ctx->x11_dpy, ctx->x11_screen, dri_state->hwContextID);
+ assert(dri_state->pSAREA != MAP_FAILED);
+ drmUnmap(dri_state->pSAREA, SAREA_MAX);
+ assert(dri_state->fd >= 0);
+ drmCloseOnce(dri_state->fd);
+ VA_DRICloseConnection(ctx->x11_dpy, ctx->x11_screen);
+}
+
+Bool
+isDRI1Connected(VADriverContextP ctx, char **driver_name)
+{
+ struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+ int direct_capable;
+ int driver_major;
+ int driver_minor;
+ int driver_patch;
+ int newlyopened;
+ char *BusID;
+ drm_magic_t magic;
+
+ *driver_name = NULL;
+ dri_state->fd = -1;
+ dri_state->pSAREA = MAP_FAILED;
+ dri_state->driConnectedFlag = VA_NONE;
+
+ if (!VA_DRIQueryDirectRenderingCapable(ctx->x11_dpy,
+ ctx->x11_screen,
+ &direct_capable))
+ goto err_out0;
+
+ if (!direct_capable)
+ goto err_out0;
+
+ if (!VA_DRIGetClientDriverName(ctx->x11_dpy, ctx->x11_screen,
+ &driver_major, &driver_minor,
+ &driver_patch, driver_name))
+ goto err_out0;
+
+ if (!VA_DRIOpenConnection(ctx->x11_dpy, ctx->x11_screen,
+ &dri_state->hSAREA, &BusID))
+ goto err_out0;
+
+
+ dri_state->fd = drmOpenOnce(NULL, BusID, &newlyopened);
+ XFree(BusID);
+ assert(dri_state->fd >= 0);
+
+ if (dri_state->fd < 0)
+ goto err_out1;
+
+
+ if (drmGetMagic(dri_state->fd, &magic))
+ goto err_out1;
+
+ if (newlyopened && !VA_DRIAuthConnection(ctx->x11_dpy, ctx->x11_screen, magic))
+ goto err_out1;
+
+ if (drmMap(dri_state->fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA))
+ goto err_out1;
+
+ if (!VA_DRICreateContext(ctx->x11_dpy, ctx->x11_screen,
+ DefaultVisual(ctx->x11_dpy, ctx->x11_screen),
+ &dri_state->hwContextID, &dri_state->hwContext))
+ goto err_out1;
+
+ dri_state->driConnectedFlag = VA_DRI1;
+ dri_state->createDrawable = dri1CreateDrawable;
+ dri_state->destroyDrawable = dri1DestroyDrawable;
+ dri_state->swapBuffer = dri1SwapBuffer;
+ dri_state->getRenderingBuffer = dri1GetRenderingBuffer;
+ dri_state->close = dri1Close;
+
+ return True;
+
+err_out1:
+ if (dri_state->pSAREA != MAP_FAILED)
+ drmUnmap(dri_state->pSAREA, SAREA_MAX);
+
+ if (dri_state->fd >= 0)
+ drmCloseOnce(dri_state->fd);
+
+ VA_DRICloseConnection(ctx->x11_dpy, ctx->x11_screen);
+
+err_out0:
+ if (*driver_name)
+ XFree(*driver_name);
+
+ dri_state->pSAREA = MAP_FAILED;
+ dri_state->fd = -1;
+ *driver_name = NULL;
+
+ return False;
+}
+