Initial support for user-space buffer objects.
authorBrian <brian.paul@tungstengraphics.com>
Thu, 11 Oct 2007 15:10:19 +0000 (09:10 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Thu, 11 Oct 2007 15:10:19 +0000 (09:10 -0600)
Basically, add userBuffer/Data/Size fields to _DriBufferObject, check those
fields in driBOMap/Unmap().
New driGenUserBuffer() function.

src/mesa/drivers/dri/common/dri_bufmgr.c
src/mesa/drivers/dri/common/dri_bufmgr.h

index eaa4fb09c70a8054cf2327a292ac8a545a7d5e43..5747307f3b62d9a2506ff60e42129a0fab2f7d0d 100644 (file)
@@ -67,6 +67,10 @@ typedef struct _DriBufferObject
    unsigned hint;
    unsigned alignment;
    void *private;
+   /* user-space buffer: */
+   unsigned userBuffer;
+   void *userData;
+   unsigned userSize;
 } DriBufferObject;
 
 
@@ -205,22 +209,29 @@ driBOWaitIdle(struct _DriBufferObject *buf, int lazy)
 void *
 driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint)
 {
-   void *virtual;
+   if (buf->userBuffer) {
+      return buf->userData;
+   }
+   else {
+      void *virtual;
 
-   assert(buf->private != NULL);
+      assert(buf->private != NULL);
 
-   _glthread_LOCK_MUTEX(buf->mutex);
-   BM_CKFATAL(buf->pool->map(buf->pool, buf->private, flags, hint, &virtual));
-   _glthread_UNLOCK_MUTEX(buf->mutex);
-   return virtual;
+      _glthread_LOCK_MUTEX(buf->mutex);
+      BM_CKFATAL(buf->pool->map(buf->pool, buf->private, flags, hint, &virtual));
+      _glthread_UNLOCK_MUTEX(buf->mutex);
+      return virtual;
+   }
 }
 
 void
 driBOUnmap(struct _DriBufferObject *buf)
 {
-   assert(buf->private != NULL);
+   if (!buf->userBuffer) {
+      assert(buf->private != NULL);
 
-   buf->pool->unmap(buf->pool, buf->private);
+      buf->pool->unmap(buf->pool, buf->private);
+   }
 }
 
 unsigned long
@@ -272,7 +283,8 @@ driBOUnReference(struct _DriBufferObject *buf)
    tmp = --buf->refCount;
    _glthread_UNLOCK_MUTEX(bmMutex);
    if (!tmp) {
-      buf->pool->destroy(buf->pool, buf->private);
+      if (buf->private)
+         buf->pool->destroy(buf->pool, buf->private);
       free(buf);
    }
 }
@@ -285,6 +297,8 @@ driBOData(struct _DriBufferObject *buf,
    int newBuffer;
    struct _DriBufferPool *pool;
 
+   assert(!buf->userBuffer); /* XXX just do a memcpy? */
+
    _glthread_LOCK_MUTEX(buf->mutex);
    pool = buf->pool;
    if (!pool->create) {
@@ -323,6 +337,8 @@ driBOSubData(struct _DriBufferObject *buf,
 {
    void *virtual;
 
+   assert(!buf->userBuffer); /* XXX just do a memcpy? */
+
    _glthread_LOCK_MUTEX(buf->mutex);
    if (size && data) {
       BM_CKFATAL(buf->pool->map(buf->pool, buf->private,
@@ -339,6 +355,8 @@ driBOGetSubData(struct _DriBufferObject *buf,
 {
    void *virtual;
 
+   assert(!buf->userBuffer); /* XXX just do a memcpy? */
+
    _glthread_LOCK_MUTEX(buf->mutex);
    if (size && data) {
       BM_CKFATAL(buf->pool->map(buf->pool, buf->private,
@@ -354,6 +372,8 @@ driBOSetStatic(struct _DriBufferObject *buf,
                unsigned long offset,
                unsigned long size, void *virtual, unsigned flags)
 {
+   assert(!buf->userBuffer); /* XXX what to do? */
+
    _glthread_LOCK_MUTEX(buf->mutex);
    if (buf->private != NULL) {
       _mesa_error(NULL, GL_INVALID_OPERATION,
@@ -415,6 +435,22 @@ driGenBuffers(struct _DriBufferPool *pool,
    }
 }
 
+void
+driGenUserBuffer(struct _DriBufferPool *pool,
+                 const char *name,
+                 struct _DriBufferObject **buffers,
+                 void *ptr, unsigned bytes)
+{
+   const unsigned alignment = 1, flags = 0, hint = 0;
+
+   driGenBuffers(pool, name, 1, buffers, alignment, flags, hint);
+
+   (*buffers)->userBuffer = 1;
+   (*buffers)->userData = ptr;
+   (*buffers)->userSize = bytes;
+}
+
+
 void
 driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[])
 {
index 01f149ae4ed6819a7c250abd1075d51203ca9bf7..ee4ce2cbdeff77b7433e9df15f56e9ee56355369 100644 (file)
@@ -78,6 +78,10 @@ extern void driGenBuffers(struct _DriBufferPool *pool,
                           unsigned n,
                           struct _DriBufferObject *buffers[],
                           unsigned alignment, unsigned flags, unsigned hint);
+extern void driGenUserBuffer(struct _DriBufferPool *pool,
+                             const char *name,
+                             struct _DriBufferObject *buffers[],
+                             void *ptr, unsigned bytes);
 extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]);
 extern void driInitBufMgr(int fd);
 extern void driBOCreateList(int target, drmBOList * list);