summaryrefslogtreecommitdiff
path: root/src/driclient/src/driclient.c
diff options
context:
space:
mode:
authorYounes Manton <younes.m@gmail.com>2008-07-22 22:26:26 -0400
committerYounes Manton <younes.m@gmail.com>2008-07-22 22:41:31 -0400
commit0c25ac52425e6d6eb037b99ab90f41b47e3f4491 (patch)
tree67c8739b48a6210e51858189b0583552cee65f2c /src/driclient/src/driclient.c
parent90bd0e338d315c426c2d0255331610055023739e (diff)
g3dvl: Add Nouveau winsys, libdriclient.
Nouveau winsys is based on Mesa's Nouveau winsys and soft-links to most of it. The 'nouveau_context' and 'nouveau_screen' code contains most of the changes, 'nouveau_winsys_pipe', 'nouveau_swapbuffers' and 'nouveau_lock' contain some minor changes. The driclient library contains the DRI userland stuff, most of which was based on Mesa's DRI code.
Diffstat (limited to 'src/driclient/src/driclient.c')
-rw-r--r--src/driclient/src/driclient.c292
1 files changed, 292 insertions, 0 deletions
diff --git a/src/driclient/src/driclient.c b/src/driclient/src/driclient.c
new file mode 100644
index 00000000000..7a7ca95702a
--- /dev/null
+++ b/src/driclient/src/driclient.c
@@ -0,0 +1,292 @@
+#include "driclient.h"
+#include <assert.h>
+#include <stdlib.h>
+
+int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf)
+{
+ int evbase, errbase;
+ char *driver_name;
+ int newly_opened;
+ drm_magic_t magic;
+ drmVersionPtr drm_version;
+ drm_handle_t sarea_handle;
+ char *bus_id;
+ dri_screen_t *dri_scrn;
+
+ assert(display);
+ assert(dri_screen);
+
+ if (!XF86DRIQueryExtension(display, &evbase, &errbase))
+ return 1;
+
+ dri_scrn = calloc(1, sizeof(dri_screen_t));
+
+ if (!dri_scrn)
+ return 1;
+
+ if (!XF86DRIQueryVersion(display, &dri_scrn->dri.major, &dri_scrn->dri.minor, &dri_scrn->dri.patch))
+ goto free_screen;
+
+ dri_scrn->display = display;
+ dri_scrn->num = screen;
+ dri_scrn->draw_lock_id = 1;
+
+ if (!XF86DRIOpenConnection(display, screen, &sarea_handle, &bus_id))
+ goto free_screen;
+
+ dri_scrn->fd = -1;
+ dri_scrn->fd = drmOpenOnce(NULL, bus_id, &newly_opened);
+ XFree(bus_id);
+
+ if (dri_scrn->fd < 0)
+ goto close_connection;
+
+ if (drmGetMagic(dri_scrn->fd, &magic))
+ goto close_drm;
+
+ drm_version = drmGetVersion(dri_scrn->fd);
+
+ if (!drm_version)
+ goto close_drm;
+
+ dri_scrn->drm.major = drm_version->version_major;
+ dri_scrn->drm.minor = drm_version->version_minor;
+ dri_scrn->drm.patch = drm_version->version_patchlevel;
+ drmFreeVersion(drm_version);
+
+ if (!XF86DRIAuthConnection(display, screen, magic))
+ goto close_drm;
+
+ if (!XF86DRIGetClientDriverName
+ (
+ display,
+ screen,
+ &dri_scrn->ddx.major,
+ &dri_scrn->ddx.minor,
+ &dri_scrn->ddx.patch,
+ &driver_name
+ ))
+ goto close_drm;
+
+ if (drmMap(dri_scrn->fd, sarea_handle, SAREA_MAX, (drmAddress)&dri_scrn->sarea))
+ goto close_drm;
+
+ dri_scrn->drawable_hash = drmHashCreate();
+
+ if (!dri_scrn->drawable_hash)
+ goto unmap_sarea;
+
+ if (dri_framebuf)
+ {
+ if (!XF86DRIGetDeviceInfo
+ (
+ display,
+ screen, &dri_framebuf->drm_handle,
+ &dri_framebuf->base,
+ &dri_framebuf->size,
+ &dri_framebuf->stride,
+ &dri_framebuf->private_size,
+ &dri_framebuf->private
+ ))
+ goto destroy_hash;
+ }
+
+ *dri_screen = dri_scrn;
+
+ return 0;
+
+destroy_hash:
+ drmHashDestroy(dri_scrn->drawable_hash);
+unmap_sarea:
+ drmUnmap(dri_scrn->sarea, SAREA_MAX);
+close_drm:
+ drmCloseOnce(dri_scrn->fd);
+close_connection:
+ XF86DRICloseConnection(display, screen);
+free_screen:
+ free(dri_scrn);
+
+ return 1;
+}
+
+int driDestroyScreen(dri_screen_t *dri_screen)
+{
+ assert(dri_screen);
+
+ drmHashDestroy(dri_screen->drawable_hash);
+ drmUnmap(dri_screen->sarea, SAREA_MAX);
+ drmCloseOnce(dri_screen->fd);
+ XF86DRICloseConnection(dri_screen->display, dri_screen->num);
+ free(dri_screen);
+
+ return 0;
+}
+
+int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable)
+{
+ int evbase, errbase;
+ dri_drawable_t *dri_draw;
+
+ assert(dri_screen);
+ assert(dri_drawable);
+
+ if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase))
+ return 1;
+
+ if (!drmHashLookup(dri_screen->drawable_hash, drawable, (void**)dri_drawable))
+ {
+ /* Found */
+ (*dri_drawable)->refcount++;
+ return 0;
+ }
+
+ dri_draw = calloc(1, sizeof(dri_drawable_t));
+
+ if (!dri_draw)
+ return 1;
+
+ if (!XF86DRICreateDrawable(dri_screen->display, 0, drawable, &dri_draw->drm_drawable))
+ {
+ free(dri_draw);
+ return 1;
+ }
+
+ dri_draw->x_drawable = drawable;
+ dri_draw->sarea_index = 0;
+ dri_draw->sarea_stamp = NULL;
+ dri_draw->last_sarea_stamp = 0;
+ dri_draw->dri_screen = dri_screen;
+ dri_draw->refcount = 1;
+
+ if (drmHashInsert(dri_screen->drawable_hash, drawable, dri_draw))
+ {
+ XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable);
+ free(dri_draw);
+ return 1;
+ }
+
+ /*
+ * XXX: Need this to initialize sarea pointer and other stuff in dri_drawable_t
+ * to be able to use the DRI_VALIDATE_DRAWABLE_INFO macro, but is it safe to
+ * call without any sync?
+ */
+ if (driUpdateDrawableInfo(dri_draw))
+ {
+ XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable);
+ free(dri_draw);
+ return 1;
+ }
+
+ *dri_drawable = dri_draw;
+
+ return 0;
+}
+
+int driUpdateDrawableInfo(dri_drawable_t *dri_drawable)
+{
+ assert(dri_drawable);
+
+ if (dri_drawable->cliprects)
+ XFree(dri_drawable->cliprects);
+ if (dri_drawable->back_cliprects)
+ XFree(dri_drawable->back_cliprects);
+
+ DRM_SPINUNLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id);
+
+ if (!XF86DRIGetDrawableInfo
+ (
+ dri_drawable->dri_screen->display,
+ dri_drawable->dri_screen->num,
+ dri_drawable->x_drawable,
+ &dri_drawable->sarea_index,
+ &dri_drawable->last_sarea_stamp,
+ &dri_drawable->x,
+ &dri_drawable->y,
+ &dri_drawable->w,
+ &dri_drawable->h,
+ &dri_drawable->num_cliprects,
+ &dri_drawable->cliprects,
+ &dri_drawable->back_x,
+ &dri_drawable->back_y,
+ &dri_drawable->num_back_cliprects,
+ &dri_drawable->back_cliprects
+ ))
+ {
+ dri_drawable->sarea_stamp = &dri_drawable->last_sarea_stamp;
+ dri_drawable->num_cliprects = 0;
+ dri_drawable->cliprects = NULL;
+ dri_drawable->num_back_cliprects = 0;
+ dri_drawable->back_cliprects = 0;
+
+ return 1;
+ }
+ else
+ dri_drawable->sarea_stamp = &dri_drawable->dri_screen->sarea->drawableTable[dri_drawable->sarea_index].stamp;
+
+ DRM_SPINLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id);
+
+ return 0;
+}
+
+int driDestroyDrawable(dri_drawable_t *dri_drawable)
+{
+ assert(dri_drawable);
+
+ if (--dri_drawable->refcount == 0)
+ {
+ if (dri_drawable->cliprects)
+ XFree(dri_drawable->cliprects);
+ if (dri_drawable->back_cliprects)
+ XFree(dri_drawable->back_cliprects);
+ drmHashDelete(dri_drawable->dri_screen->drawable_hash, dri_drawable->x_drawable);
+ XF86DRIDestroyDrawable(dri_drawable->dri_screen->display, dri_drawable->dri_screen->num, dri_drawable->x_drawable);
+ free(dri_drawable);
+ }
+
+ return 0;
+}
+
+int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context)
+{
+ int evbase, errbase;
+ dri_context_t *dri_ctx;
+
+ assert(dri_screen);
+ assert(visual);
+ assert(dri_context);
+
+ if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase))
+ return 1;
+
+ dri_ctx = calloc(1, sizeof(dri_context_t));
+
+ if (!dri_ctx)
+ return 1;
+
+ if (!XF86DRICreateContext(dri_screen->display, dri_screen->num, visual, &dri_ctx->id, &dri_ctx->drm_context))
+ {
+ free(dri_ctx);
+ return 1;
+ }
+
+ dri_ctx->dri_screen = dri_screen;
+ *dri_context = dri_ctx;
+
+ return 0;
+}
+
+int driDestroyContext(dri_context_t *dri_context)
+{
+ assert(dri_context);
+
+ XF86DRIDestroyContext(dri_context->dri_screen->display, dri_context->dri_screen->num, dri_context->id);
+ free(dri_context);
+
+ return 0;
+}
+
+int driCompareVersions(const dri_version_t *v1, const dri_version_t *v2)
+{
+ return (v1->major == v2->major) && (v1->minor == v2->minor) && (v1->patch == v2->patch);
+}
+