summaryrefslogtreecommitdiff
path: root/src/mesa/pipe/pipebuffer
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/pipe/pipebuffer')
-rw-r--r--src/mesa/pipe/pipebuffer/Makefile3
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer.c49
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer.h127
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_client.c62
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_fenced.c121
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_fenced.h10
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_handle.c182
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_handle.h120
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_malloc.c51
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_null.c98
-rw-r--r--src/mesa/pipe/pipebuffer/pb_bufmgr.h31
-rw-r--r--src/mesa/pipe/pipebuffer/pb_bufmgr_fenced.c48
-rw-r--r--src/mesa/pipe/pipebuffer/pb_bufmgr_mm.c420
-rw-r--r--src/mesa/pipe/pipebuffer/pb_bufmgr_pool.c109
14 files changed, 675 insertions, 756 deletions
diff --git a/src/mesa/pipe/pipebuffer/Makefile b/src/mesa/pipe/pipebuffer/Makefile
index 061d8a060f..ea8c3440c3 100644
--- a/src/mesa/pipe/pipebuffer/Makefile
+++ b/src/mesa/pipe/pipebuffer/Makefile
@@ -4,14 +4,11 @@ include $(TOP)/configs/current
LIBNAME = pipebuffer
-
DRIVER_SOURCES = \
pb_buffer.c \
pb_buffer_client.c \
- pb_buffer_handle.c \
pb_buffer_fenced.c \
pb_buffer_malloc.c \
- pb_buffer_null.c \
pb_bufmgr_fenced.c \
pb_bufmgr_mm.c \
pb_bufmgr_pool.c
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer.c b/src/mesa/pipe/pipebuffer/pb_buffer.c
index 99c960b697..90ab9044ff 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer.c
+++ b/src/mesa/pipe/pipebuffer/pb_buffer.c
@@ -34,19 +34,44 @@
#include "pb_buffer.h"
+#include "pipe/p_winsys.h"
-void
-buffer_reference(struct pipe_buffer **dst,
- struct pipe_buffer *src)
+
+static void *
+pb_winsys_map(struct pipe_winsys *winsys,
+ struct pipe_buffer *ws_buf,
+ unsigned flags)
+{
+ struct pb_buffer *buf = pb_buffer(ws_buf);
+
+ return buf->vtbl->map(buf, flags);
+}
+
+static void
+pb_winsys_unmap(struct pipe_winsys *winsys,
+ struct pipe_buffer *ws_buf)
+{
+ struct pb_buffer *buf = pb_buffer(ws_buf);
+
+ buf->vtbl->unmap(buf);
+}
+
+static void
+pb_winsys_destroy(struct pipe_winsys *winsys,
+ struct pipe_buffer *ws_buf)
+{
+ struct pb_buffer *buf = pb_buffer(ws_buf);
+
+ buf->vtbl->destroy(buf);
+}
+
+
+
+void
+pb_init_winsys(struct pipe_winsys *winsys)
{
- if(*dst != src) {
- if (src)
- src->vtbl->reference(src);
-
- if (*dst)
- (*dst)->vtbl->release(*dst);
-
- *dst = src;
- }
+ winsys->buffer_map = pb_winsys_map;
+ winsys->buffer_unmap = pb_winsys_unmap;
+ winsys->buffer_destroy = pb_winsys_destroy;
}
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer.h b/src/mesa/pipe/pipebuffer/pb_buffer.h
index 0523531395..2f570ef9de 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer.h
+++ b/src/mesa/pipe/pipebuffer/pb_buffer.h
@@ -47,53 +47,57 @@
#include <assert.h>
#include <stdlib.h>
+#include "pipe/p_compiler.h"
-struct pipe_buffer_vtbl;
+#include "pipe/p_state.h"
+struct pb_vtbl;
/**
- * Base class for all pipe buffers.
+ * Buffer description.
+ *
+ * Used when allocating the buffer.
+ */
+struct pb_desc
+{
+ unsigned alignment;
+ unsigned usage;
+};
+
+
+/**
+ * Base class for all pb_* buffers.
*/
-struct pipe_buffer
+struct pb_buffer
{
+ struct pipe_buffer base;
+
/**
* Pointer to the virtual function table.
*
* Avoid accessing this table directly. Use the inline functions below
* instead to avoid mistakes.
*/
- const struct pipe_buffer_vtbl *vtbl;
+ const struct pb_vtbl *vtbl;
};
-
/**
* Virtual function table for the buffer storage operations.
*
* Note that creation is not done through this table.
*/
-struct pipe_buffer_vtbl
+struct pb_vtbl
{
- /**
- * Add a reference to the buffer.
- *
- * This method can be a no-op for buffers that don't need reference
- * counting.
- */
- void (*reference)( struct pipe_buffer *buf );
-
- /**
- * Release a reference to this buffer and destroy it.
- */
- void (*release)( struct pipe_buffer *buf );
+ void (*destroy)( struct pb_buffer *buf );
/**
* Map the entire data store of a buffer object into the client's address.
* flags is bitmask of PIPE_BUFFER_FLAG_READ/WRITE.
*/
- void *(*map)( struct pipe_buffer *buf,
+ void *(*map)( struct pb_buffer *buf,
unsigned flags );
- void (*unmap)( struct pipe_buffer *buf );
+ void (*unmap)( struct pb_buffer *buf );
/**
* Get the base buffer and the offset.
@@ -106,70 +110,87 @@ struct pipe_buffer_vtbl
*
* Note that this will increase the reference count of the base buffer.
*/
- void (*get_base_buffer)( struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+ void (*get_base_buffer)( struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset );
};
-/** *dst = src with reference counting */
-void
-buffer_reference(struct pipe_buffer **dst,
- struct pipe_buffer *src);
-
-
-static inline void
-buffer_release(struct pipe_buffer *buf)
-{
- assert(buf);
- buf->vtbl->release(buf);
-}
-
-
-static inline void *
-buffer_map(struct pipe_buffer *buf,
- unsigned flags)
+/* Accessor functions for pb->vtbl:
+ */
+static INLINE void *
+pb_map(struct pb_buffer *buf,
+ unsigned flags)
{
assert(buf);
return buf->vtbl->map(buf, flags);
}
-static inline void
-buffer_unmap(struct pipe_buffer *buf)
+static INLINE void
+pb_unmap(struct pb_buffer *buf)
{
assert(buf);
buf->vtbl->unmap(buf);
}
-static inline void
-buffer_get_base_buffer( struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
- unsigned *offset )
+static INLINE void
+pb_get_base_buffer( struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
+ unsigned *offset )
{
buf->vtbl->get_base_buffer(buf, base_buf, offset);
}
+static INLINE void
+pb_destroy(struct pb_buffer *buf)
+{
+ assert(buf);
+ buf->vtbl->destroy(buf);
+}
+
-/** Placeholder for empty buffers. */
-extern struct pipe_buffer null_buffer;
/**
- * Client buffers (also designated as user buffers) are just for convenience
- * of the state tracker, so that it can masquerade its own data as a buffer.
+ * User buffers are special buffers that initially reference memory
+ * held by the user but which may if necessary copy that memory into
+ * device memory behind the scenes, for submission to hardware.
+ *
+ * These are particularly useful when the referenced data is never
+ * submitted to hardware at all, in the particular case of software
+ * vertex processing.
*/
-struct pipe_buffer *
-client_buffer_create(void *data);
+struct pb_buffer *
+pb_user_buffer_create(void *data, unsigned bytes);
/**
* Malloc-based buffer to store data that can't be used by the graphics
* hardware.
*/
-struct pipe_buffer *
-malloc_buffer_create(unsigned size);
+struct pb_buffer *
+pb_malloc_buffer_create(size_t size,
+ const struct pb_desc *desc);
+
+
+static INLINE struct pipe_buffer *
+pb_pipe_buffer( struct pb_buffer *pbuf )
+{
+ return &pbuf->base;
+}
+
+static INLINE struct pb_buffer *
+pb_buffer( struct pipe_buffer *buf )
+{
+ /* Could add a magic cookie check on debug builds.
+ */
+ return (struct pb_buffer *)buf;
+}
+
+void
+pb_init_winsys(struct pipe_winsys *winsys);
#endif /*PB_BUFFER_H_*/
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_client.c b/src/mesa/pipe/pipebuffer/pb_buffer_client.c
index bb7f5a9a94..c316aabd32 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer_client.c
+++ b/src/mesa/pipe/pipebuffer/pb_buffer_client.c
@@ -34,61 +34,55 @@
*/
+#include "pipe/p_util.h"
#include "pb_buffer.h"
-struct client_buffer
+struct pb_user_buffer
{
- struct pipe_buffer base;
+ struct pb_buffer base;
void *data;
};
-extern const struct pipe_buffer_vtbl client_buffer_vtbl;
+extern const struct pb_vtbl pb_user_buffer_vtbl;
-static inline struct client_buffer *
-client_buffer(struct pipe_buffer *buf)
+static INLINE struct pb_user_buffer *
+pb_user_buffer(struct pb_buffer *buf)
{
assert(buf);
- assert(buf->vtbl == &client_buffer_vtbl);
- return (struct client_buffer *)buf;
+ assert(buf->vtbl == &pb_user_buffer_vtbl);
+ return (struct pb_user_buffer *)buf;
}
static void
-client_buffer_reference(struct pipe_buffer *buf)
-{
- /* No-op */
-}
-
-
-static void
-client_buffer_release(struct pipe_buffer *buf)
+pb_user_buffer_destroy(struct pb_buffer *buf)
{
assert(buf);
- free(buf);
+ FREE(buf);
}
static void *
-client_buffer_map(struct pipe_buffer *buf,
+pb_user_buffer_map(struct pb_buffer *buf,
unsigned flags)
{
- return client_buffer(buf)->data;
+ return pb_user_buffer(buf)->data;
}
static void
-client_buffer_unmap(struct pipe_buffer *buf)
+pb_user_buffer_unmap(struct pb_buffer *buf)
{
/* No-op */
}
static void
-client_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+pb_user_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset)
{
*base_buf = buf;
@@ -96,27 +90,25 @@ client_buffer_get_base_buffer(struct pipe_buffer *buf,
}
-const struct pipe_buffer_vtbl
-client_buffer_vtbl = {
- client_buffer_reference,
- client_buffer_release,
- client_buffer_map,
- client_buffer_unmap,
- client_buffer_get_base_buffer
+const struct pb_vtbl
+pb_user_buffer_vtbl = {
+ pb_user_buffer_destroy,
+ pb_user_buffer_map,
+ pb_user_buffer_unmap,
+ pb_user_buffer_get_base_buffer
};
-struct pipe_buffer *
-client_buffer_create(void *data)
+struct pb_buffer *
+pb_user_buffer_create(void *data, unsigned bytes)
{
- struct client_buffer *buf;
-
- buf = (struct client_buffer *)malloc(sizeof(struct client_buffer));
+ struct pb_user_buffer *buf = CALLOC_STRUCT(pb_user_buffer);
+
if(!buf)
return NULL;
- buf->base.vtbl = &client_buffer_vtbl;
-
+ buf->base.vtbl = &pb_user_buffer_vtbl;
+ buf->base.base.size = bytes;
buf->data = data;
return &buf->base;
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_fenced.c b/src/mesa/pipe/pipebuffer/pb_buffer_fenced.c
index dfb80b1dcf..b2edc321ef 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer_fenced.c
+++ b/src/mesa/pipe/pipebuffer/pb_buffer_fenced.c
@@ -36,17 +36,21 @@
#include <assert.h>
#include <stdlib.h>
-#include <unistd.h>
-#include "main/imports.h"
-#include "glapi/glthread.h"
#include "linked_list.h"
+#include "p_compiler.h"
#include "p_winsys.h"
+#include "p_thread.h"
+#include "p_util.h"
#include "pb_buffer.h"
#include "pb_buffer_fenced.h"
+#ifndef __MSC__
+#include <unistd.h>
+#endif
+
/**
* Convenience macro (type safe).
@@ -72,9 +76,9 @@ struct fenced_buffer_list
*/
struct fenced_buffer
{
- struct pipe_buffer base;
+ struct pb_buffer base;
- struct pipe_buffer *buffer;
+ struct pb_buffer *buffer;
unsigned refcount;
struct pipe_fence_handle *fence;
@@ -84,8 +88,8 @@ struct fenced_buffer
};
-static inline struct fenced_buffer *
-fenced_buffer(struct pipe_buffer *buf)
+static INLINE struct fenced_buffer *
+fenced_buffer(struct pb_buffer *buf)
{
assert(buf);
assert(buf->vtbl == &fenced_buffer_vtbl);
@@ -93,12 +97,6 @@ fenced_buffer(struct pipe_buffer *buf)
}
-static void
-_fenced_buffer_destroy(struct fenced_buffer *fenced_buf)
-{
- buffer_release(fenced_buf->buffer);
- free(fenced_buf);
-}
static void
@@ -109,11 +107,12 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
struct fenced_buffer *fenced_buf;
struct list_head *list, *prev;
int signaled = -1;
- int i;
list = fenced_list->delayed.next;
if (fenced_list->numDelayed > 3) {
+ unsigned i;
+
for (i = 0; i < fenced_list->numDelayed; i += 3) {
list = list->next;
}
@@ -143,97 +142,81 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
LIST_DEL(list);
fenced_list->numDelayed--;
-
- _fenced_buffer_destroy(fenced_buf);
- }
-}
-
-
-static void
-fenced_buffer_reference(struct pipe_buffer *buf)
-{
- struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- struct fenced_buffer_list *fenced_list = fenced_buf->list;
- _glthread_LOCK_MUTEX(fenced_list->mutex);
- fenced_buf->refcount++;
- _glthread_UNLOCK_MUTEX(fenced_list->mutex);
+ /* Do the delayed destroy:
+ */
+ pb_destroy(fenced_buf->buffer);
+ free(fenced_buf);
+ }
}
static void
-fenced_buffer_release(struct pipe_buffer *buf)
+fenced_buffer_destroy(struct pb_buffer *buf)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
struct fenced_buffer_list *fenced_list = fenced_buf->list;
- _glthread_LOCK_MUTEX(fenced_list->mutex);
-
- fenced_buf->refcount--;
- if(!fenced_buf->refcount) {
- if (fenced_buf->fence) {
- LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed);
- fenced_list->numDelayed++;
- }
- else {
- _fenced_buffer_destroy(fenced_buf);
- }
-
- if ((fenced_list->numDelayed % fenced_list->checkDelayed) == 0)
- _fenced_buffer_list_check_free(fenced_list, 0);
+ if (fenced_buf->fence) {
+ LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed);
+ fenced_list->numDelayed++;
+ }
+ else {
+ pb_destroy(fenced_buf->buffer);
+ free(fenced_buf);
}
- _glthread_UNLOCK_MUTEX(fenced_list->mutex);
+ if ((fenced_list->numDelayed % fenced_list->checkDelayed) == 0)
+ _fenced_buffer_list_check_free(fenced_list, 0);
}
static void *
-fenced_buffer_map(struct pipe_buffer *buf,
+fenced_buffer_map(struct pb_buffer *buf,
unsigned flags)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- return buffer_map(fenced_buf->buffer, flags);
+ return pb_map(fenced_buf->buffer, flags);
}
static void
-fenced_buffer_unmap(struct pipe_buffer *buf)
+fenced_buffer_unmap(struct pb_buffer *buf)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- buffer_unmap(fenced_buf->buffer);
+ pb_unmap(fenced_buf->buffer);
}
static void
-fenced_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+fenced_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- buffer_get_base_buffer(fenced_buf->buffer, base_buf, offset);
+ pb_get_base_buffer(fenced_buf->buffer, base_buf, offset);
}
-const struct pipe_buffer_vtbl
+const struct pb_vtbl
fenced_buffer_vtbl = {
- fenced_buffer_reference,
- fenced_buffer_release,
+ fenced_buffer_destroy,
fenced_buffer_map,
fenced_buffer_unmap,
fenced_buffer_get_base_buffer
};
-struct pipe_buffer *
+struct pb_buffer *
fenced_buffer_create(struct fenced_buffer_list *fenced_list,
- struct pipe_buffer *buffer)
+ struct pb_buffer *buffer)
{
struct fenced_buffer *buf;
if(!buffer)
return NULL;
- buf = (struct fenced_buffer *)calloc(1, sizeof(struct fenced_buffer));
+ buf = CALLOC_STRUCT(fenced_buffer);
if(!buf)
return NULL;
@@ -247,20 +230,16 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list,
void
-buffer_fence(struct pipe_buffer *buf,
+buffer_fence(struct pb_buffer *buf,
struct pipe_fence_handle *fence)
{
- if(buf->vtbl == &fenced_buffer_vtbl) {
- struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- struct fenced_buffer_list *fenced_list = fenced_buf->list;
- struct pipe_winsys *winsys = fenced_list->winsys;
+ struct fenced_buffer *fenced_buf = fenced_buffer(buf);
+ struct fenced_buffer_list *fenced_list = fenced_buf->list;
+ struct pipe_winsys *winsys = fenced_list->winsys;
- _glthread_LOCK_MUTEX(fenced_list->mutex);
- winsys->fence_reference(winsys, &fenced_buf->fence, fence);
- _glthread_UNLOCK_MUTEX(fenced_list->mutex);
- }
- else
- assert(0);
+ _glthread_LOCK_MUTEX(fenced_list->mutex);
+ winsys->fence_reference(winsys, &fenced_buf->fence, fence);
+ _glthread_UNLOCK_MUTEX(fenced_list->mutex);
}
@@ -269,7 +248,7 @@ fenced_buffer_list_create(struct pipe_winsys *winsys)
{
struct fenced_buffer_list *fenced_list;
- fenced_list = (struct fenced_buffer_list *)calloc(1, sizeof(*fenced_list));
+ fenced_list = (struct fenced_buffer_list *)CALLOC(1, sizeof(*fenced_list));
if (!fenced_list)
return NULL;
@@ -307,13 +286,13 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list)
while (fenced_list->numDelayed) {
_glthread_UNLOCK_MUTEX(fenced_list->mutex);
sched_yield();
- _fenced_buffer_list_check_free(fenced_list, GL_TRUE);
+ _fenced_buffer_list_check_free(fenced_list, 1);
_glthread_LOCK_MUTEX(fenced_list->mutex);
}
_glthread_UNLOCK_MUTEX(fenced_list->mutex);
- free(fenced_list);
+ FREE(fenced_list);
}
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_fenced.h b/src/mesa/pipe/pipebuffer/pb_buffer_fenced.h
index 07e42a67f8..09082a5390 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer_fenced.h
+++ b/src/mesa/pipe/pipebuffer/pb_buffer_fenced.h
@@ -70,7 +70,7 @@ struct fenced_buffer_list;
*
* NOTE: Made public for debugging purposes.
*/
-extern const struct pipe_buffer_vtbl fenced_buffer_vtbl;
+extern const struct pb_vtbl fenced_buffer_vtbl;
/**
@@ -98,19 +98,19 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list);
*
* NOTE: this will not increase the buffer reference count.
*/
-struct pipe_buffer *
+struct pb_buffer *
fenced_buffer_create(struct fenced_buffer_list *fenced,
- struct pipe_buffer *buffer);
+ struct pb_buffer *buffer);
/**
* Set a buffer's fence.
*
- * NOTE: Although it takes a generic pipe buffer argument, it will fail
+ * NOTE: Although it takes a generic pb_buffer argument, it will fail
* on everything but buffers returned by fenced_buffer_create.
*/
void
-buffer_fence(struct pipe_buffer *buf,
+buffer_fence(struct pb_buffer *buf,
struct pipe_fence_handle *fence);
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_handle.c b/src/mesa/pipe/pipebuffer/pb_buffer_handle.c
deleted file mode 100644
index 5a5eaee7ac..0000000000
--- a/src/mesa/pipe/pipebuffer/pb_buffer_handle.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * \file
- * Drop-in implementation of the winsys driver functions for buffer handles.
- *
- * \author José Fonseca <jrfonseca@tungstengraphics.com>
- */
-
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "pipe/p_winsys.h"
-#include "pipe/p_defines.h"
-
-#include "pb_buffer.h"
-#include "pb_buffer_handle.h"
-
-
-static struct pipe_buffer_handle *
-buffer_handle_create(struct pipe_winsys *winsys,
- unsigned alignment,
- unsigned flags,
- unsigned hint)
-{
- struct pipe_buffer_handle *handle;
-
- handle = (struct pipe_buffer_handle *)malloc(sizeof(struct pipe_buffer_handle));
- if(!handle)
- return NULL;
-
- handle->refcount = 1;
- handle->alignment = alignment;
- handle->flags = flags;
- handle->hint = hint;
-
- handle->buf = &null_buffer;
-
- return handle;
-}
-
-
-static struct pipe_buffer_handle *
-buffer_handle_create_user(struct pipe_winsys *winsys,
- void *data, unsigned size)
-{
- struct pipe_buffer_handle *handle;
- struct pipe_buffer *buf;
-
- handle = buffer_handle_create(winsys, 1, 0, 0);
- if(!handle)
- return NULL;
-
- buf = client_buffer_create(data);
- if(!buf) {
- free(handle);
- return NULL;
- }
-
- buffer_handle_data(handle, buf);
-
- return handle;
-}
-
-
-static void *
-buffer_handle_map(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *handle,
- unsigned flags)
-{
- return buffer_map(handle->buf, flags);
-}
-
-
-static void
-buffer_handle_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *handle)
-{
- buffer_unmap(handle->buf);
-}
-
-
-static void
-buffer_handle_reference(struct pipe_winsys *winsys,
- struct pipe_buffer_handle **dst,
- struct pipe_buffer_handle *src)
-{
- /* XXX: should this be thread safe? */
-
- if (src) {
- src->refcount++;
- }
-
- if (*dst) {
- (*dst)->refcount--;
- if ((*dst)->refcount == 0) {
- buffer_release((*dst)->buf);
- free(*dst);
- }
- }
-
- *dst = src;
-}
-
-
-static int
-buffer_handle_subdata(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *handle,
- unsigned long offset,
- unsigned long size,
- const void *data)
-{
- void *map;
- assert(handle);
- assert(data);
- map = buffer_handle_map(winsys, handle, PIPE_BUFFER_FLAG_WRITE);
- if(map) {
- memcpy((char *)map + offset, data, size);
- buffer_handle_unmap(winsys, handle);
- return 0;
- }
- return -1;
-}
-
-
-static int
-buffer_handle_get_subdata(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *handle,
- unsigned long offset,
- unsigned long size,
- void *data)
-{
- void *map;
- assert(handle);
- assert(data);
- map = buffer_handle_map(winsys, handle, PIPE_BUFFER_FLAG_READ);
- if(map) {
- memcpy(data, (char *)map + offset, size);
- buffer_handle_unmap(winsys, handle);
- return 0;
- }
- return -1;
-}
-
-
-void
-buffer_handle_init_winsys(struct pipe_winsys *winsys)
-{
- winsys->buffer_create = buffer_handle_create;
- winsys->user_buffer_create = buffer_handle_create_user;
- winsys->buffer_map = buffer_handle_map;
- winsys->buffer_unmap = buffer_handle_unmap;
- winsys->buffer_reference = buffer_handle_reference;
- winsys->buffer_subdata = buffer_handle_subdata;
- winsys->buffer_get_subdata = buffer_handle_get_subdata;
-}
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_handle.h b/src/mesa/pipe/pipebuffer/pb_buffer_handle.h
deleted file mode 100644
index 076eec2fdc..0000000000
--- a/src/mesa/pipe/pipebuffer/pb_buffer_handle.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * \file
- * Buffer handle interface.
- *
- * \author José Fonseca <jrfonseca@tungstengraphics.com>
- */
-
-#ifndef PB_BUFFER_HANDLE_H_
-#define PB_BUFFER_HANDLE_H_
-
-
-#include <assert.h>
-
-#include "pb_buffer.h"
-
-
-/**
- * Buffer handle.
- *
- * The buffer handle and the buffer data storage are separate entities. This
- * is modelled after ARB_vertex_buffer_object, which is the interface that
- * Gallium requires. See p_winsys.h for more information.
- */
-struct pipe_buffer_handle
-{
- /** Reference count */
- unsigned refcount;
-
- /** Allocation characteristics */
- unsigned alignment;
- unsigned flags;
- unsigned hint;
-
- /**
- * The actual buffer.
- *
- * It should never be NULL. Use null_buffer instead.
- */
- struct pipe_buffer *buf;
-};
-
-
-/**
- * Set buffer storage.
- *
- * NOTE: this will not increase the buffer reference count.
- */
-static inline void
-buffer_handle_data(struct pipe_buffer_handle *handle,
- struct pipe_buffer *buf)
-{
- assert(handle);
- assert(handle->buf);
- buffer_release(handle->buf);
- assert(buf);
- handle->buf = buf;
-}
-
-
-static inline void
-buffer_handle_clear(struct pipe_buffer_handle *handle)
-{
- buffer_handle_data(handle, &null_buffer);
-}
-
-
-static inline int
-buffer_handle_has_data(struct pipe_buffer_handle *handle) {
- assert(handle);
- assert(handle->buf);
- return handle->buf != &null_buffer;
-}
-
-
-/**
- * Fill in the pipe_winsys' buffer-related callbacks.
- *
- * Specifically, the fullfilled functions are:
- * - buffer_create
- * - user_buffer_create
- * - buffer_map
- * - buffer_unmap
- * - buffer_reference
- * - buffer_subdata
- * - buffer_get_subdata
- *
- * NOTE: buffer_data is left untouched.
- */
-void
-buffer_handle_init_winsys(struct pipe_winsys *winsys);
-
-
-#endif /*PB_BUFFER_HANDLE_H_*/
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_malloc.c b/src/mesa/pipe/pipebuffer/pb_buffer_malloc.c
index 65ad51e1e7..f0ff1d347e 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer_malloc.c
+++ b/src/mesa/pipe/pipebuffer/pb_buffer_malloc.c
@@ -37,20 +37,21 @@
#include <assert.h>
#include <stdlib.h>
+#include "pipe/p_util.h"
#include "pb_buffer.h"
struct malloc_buffer
{
- struct pipe_buffer base;
+ struct pb_buffer base;
void *data;
};
-extern const struct pipe_buffer_vtbl malloc_buffer_vtbl;
+extern const struct pb_vtbl malloc_buffer_vtbl;
-static inline struct malloc_buffer *
-malloc_buffer(struct pipe_buffer *buf)
+static INLINE struct malloc_buffer *
+malloc_buffer(struct pb_buffer *buf)
{
assert(buf);
assert(buf->vtbl == &malloc_buffer_vtbl);
@@ -59,22 +60,15 @@ malloc_buffer(struct pipe_buffer *buf)
static void
-malloc_buffer_reference(struct pipe_buffer *buf)
+malloc_buffer_destroy(struct pb_buffer *buf)
{
- /* no-op */
-}
-
-
-static void
-malloc_buffer_release(struct pipe_buffer *buf)
-{
- free(malloc_buffer(buf)->data);
- free(buf);
+ align_free(malloc_buffer(buf)->data);
+ FREE(buf);
}
static void *
-malloc_buffer_map(struct pipe_buffer *buf,
+malloc_buffer_map(struct pb_buffer *buf,
unsigned flags)
{
return malloc_buffer(buf)->data;
@@ -82,15 +76,15 @@ malloc_buffer_map(struct pipe_buffer *buf,
static void
-malloc_buffer_unmap(struct pipe_buffer *buf)
+malloc_buffer_unmap(struct pb_buffer *buf)
{
/* No-op */
}
static void
-malloc_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+malloc_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset)
{
*base_buf = buf;
@@ -98,33 +92,36 @@ malloc_buffer_get_base_buffer(struct pipe_buffer *buf,
}
-const struct pipe_buffer_vtbl
+const struct pb_vtbl
malloc_buffer_vtbl = {
- malloc_buffer_reference,
- malloc_buffer_release,
+ malloc_buffer_destroy,
malloc_buffer_map,
malloc_buffer_unmap,
malloc_buffer_get_base_buffer
};
-struct pipe_buffer *
-malloc_buffer_create(unsigned size)
+struct pb_buffer *
+pb_malloc_buffer_create(size_t size,
+ const struct pb_desc *desc)
{
struct malloc_buffer *buf;
/* TODO: accept an alignment parameter */
/* TODO: do a single allocation */
- buf = (struct malloc_buffer *)malloc(sizeof(struct malloc_buffer));
+ buf = (struct malloc_buffer *)MALLOC(sizeof(struct malloc_buffer));
if(!buf)
return NULL;
buf->base.vtbl = &malloc_buffer_vtbl;
-
- buf->data = malloc(size);
+ buf->base.base.alignment = desc->alignment;
+ buf->base.base.usage = desc->usage;
+ buf->base.base.size = size;
+
+ buf->data = align_malloc(size, desc->alignment < sizeof(void*) ? sizeof(void*) : desc->alignment);
if(!buf->data) {
- free(buf);
+ FREE(buf);
return NULL;
}
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_null.c b/src/mesa/pipe/pipebuffer/pb_buffer_null.c
deleted file mode 100644
index a356c6b2d5..0000000000
--- a/src/mesa/pipe/pipebuffer/pb_buffer_null.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * \file
- * Null buffer implementation.
- *
- * We have a special null buffer object so that we can safely call buffer
- * operations without having to check whether the buffer pointer is null or not.
- *
- * \author José Fonseca <jrfonseca@tungstengraphics.com>
- */
-
-
-#include "pipe/p_winsys.h"
-#include "pipe/p_defines.h"
-
-#include "pb_buffer.h"
-
-
-static void
-null_buffer_reference(struct pipe_buffer *buf)
-{
- /* No-op */
-}
-
-
-static void
-null_buffer_release(struct pipe_buffer *buf)
-{
- /* No-op */
-}
-
-
-static void *
-null_buffer_map(struct pipe_buffer *buf,
- unsigned flags)
-{
- assert(0);
- return NULL;
-}
-
-
-static void
-null_buffer_unmap(struct pipe_buffer *buf)
-{
- assert(0);
-}
-
-
-static void
-null_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
- unsigned *offset)
-{
- *base_buf = buf;
- *offset = 0;
-}
-
-
-const struct pipe_buffer_vtbl
-pipe_buffer_vtbl = {
- null_buffer_reference,
- null_buffer_release,
- null_buffer_map,
- null_buffer_unmap,
- null_buffer_get_base_buffer
-};
-
-
-struct pipe_buffer
-null_buffer = {
- &pipe_buffer_vtbl
-};
diff --git a/src/mesa/pipe/pipebuffer/pb_bufmgr.h b/src/mesa/pipe/pipebuffer/pb_bufmgr.h
index 12e36323a8..1ddf784c97 100644
--- a/src/mesa/pipe/pipebuffer/pb_bufmgr.h
+++ b/src/mesa/pipe/pipebuffer/pb_bufmgr.h
@@ -53,6 +53,7 @@
#include <stddef.h>
+struct pb_desc;
struct pipe_buffer;
struct pipe_winsys;
@@ -60,15 +61,16 @@ struct pipe_winsys;
/**
* Abstract base class for all buffer managers.
*/
-struct buffer_manager
+struct pb_manager
{
/* XXX: we will likely need more allocation flags */
- struct pipe_buffer *
- (*create_buffer)( struct buffer_manager *mgr,
- size_t size );
+ struct pb_buffer *
+ (*create_buffer)( struct pb_manager *mgr,
+ size_t size,
+ const struct pb_desc *desc);
void
- (*destroy)( struct buffer_manager *mgr );
+ (*destroy)( struct pb_manager *mgr );
};
@@ -80,9 +82,10 @@ struct buffer_manager
*
* It is meant to manage the allocation of batch buffer pools.
*/
-struct buffer_manager *
-pool_bufmgr_create(struct buffer_manager *provider,
- size_t n, size_t size);
+struct pb_manager *
+pool_bufmgr_create(struct pb_manager *provider,
+ size_t n, size_t size,
+ const struct pb_desc *desc);
/**
@@ -92,8 +95,8 @@ pool_bufmgr_create(struct buffer_manager *provider,
* with the size of the heap, and then using the old mm memory manager to manage
* that heap.
*/
-struct buffer_manager *
-mm_bufmgr_create(struct buffer_manager *provider,
+struct pb_manager *
+mm_bufmgr_create(struct pb_manager *provider,
size_t size, size_t align2);
/**
@@ -101,8 +104,8 @@ mm_bufmgr_create(struct buffer_manager *provider,
*
* Buffer will be release when the manager is destroyed.
*/
-struct buffer_manager *
-mm_bufmgr_create_from_buffer(struct pipe_buffer *buffer,
+struct pb_manager *
+mm_bufmgr_create_from_buffer(struct pb_buffer *buffer,
size_t size, size_t align2);
@@ -115,8 +118,8 @@ mm_bufmgr_create_from_buffer(struct pipe_buffer *buffer,
* NOTE: the buffer manager that provides the buffers will be destroyed
* at the same time.
*/
-struct buffer_manager *
-fenced_bufmgr_create(struct buffer_manager *provider,
+struct pb_manager *
+fenced_bufmgr_create(struct pb_manager *provider,
struct pipe_winsys *winsys);
diff --git a/src/mesa/pipe/pipebuffer/pb_bufmgr_fenced.c b/src/mesa/pipe/pipebuffer/pb_bufmgr_fenced.c
index defd8e4df7..6a81cbdae0 100644
--- a/src/mesa/pipe/pipebuffer/pb_bufmgr_fenced.c
+++ b/src/mesa/pipe/pipebuffer/pb_bufmgr_fenced.c
@@ -37,45 +37,49 @@
#include <assert.h>
#include <stdlib.h>
+#include "p_util.h"
+
#include "pb_buffer.h"
#include "pb_buffer_fenced.h"
#include "pb_bufmgr.h"
-struct fenced_buffer_manager
+struct fenced_pb_manager
{
- struct buffer_manager base;
+ struct pb_manager base;
- struct buffer_manager *provider;
+ struct pb_manager *provider;
struct fenced_buffer_list *fenced_list;
};
-static inline struct fenced_buffer_manager *
-fenced_buffer_manager(struct buffer_manager *mgr)
+static INLINE struct fenced_pb_manager *
+fenced_pb_manager(struct pb_manager *mgr)
{
assert(mgr);
- return (struct fenced_buffer_manager *)mgr;
+ return (struct fenced_pb_manager *)mgr;
}
-static struct pipe_buffer *
-fenced_bufmgr_create_buffer(struct buffer_manager *mgr, size_t size)
+static struct pb_buffer *
+fenced_bufmgr_create_buffer(struct pb_manager *mgr,
+ size_t size,
+ const struct pb_desc *desc)
{
- struct fenced_buffer_manager *fenced_mgr = fenced_buffer_manager(mgr);
- struct pipe_buffer *buf;
- struct pipe_buffer *fenced_buf;
+ struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr);
+ struct pb_buffer *buf;
+ struct pb_buffer *fenced_buf;
/* check for free buffers before allocating new ones */
fenced_buffer_list_check_free(fenced_mgr->fenced_list, 0);
- buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size);
+ buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc);
if(!buf) {
/* try harder to get a buffer */
fenced_buffer_list_check_free(fenced_mgr->fenced_list, 1);
- buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size);
+ buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc);
if(!buf) {
/* give up */
return NULL;
@@ -84,7 +88,7 @@ fenced_bufmgr_create_buffer(struct buffer_manager *mgr, size_t size)
fenced_buf = fenced_buffer_create(fenced_mgr->fenced_list, buf);
if(!fenced_buf) {
- buffer_release(buf);
+ pb_destroy(buf);
}
return fenced_buf;
@@ -92,25 +96,25 @@ fenced_bufmgr_create_buffer(struct buffer_manager *mgr, size_t size)
static void
-fenced_bufmgr_destroy(struct buffer_manager *mgr)
+fenced_bufmgr_destroy(struct pb_manager *mgr)
{
- struct fenced_buffer_manager *fenced_mgr = fenced_buffer_manager(mgr);
+ struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr);
fenced_buffer_list_destroy(fenced_mgr->fenced_list);
fenced_mgr->provider->destroy(fenced_mgr->provider);
- free(fenced_mgr);
+ FREE(fenced_mgr);
}
-struct buffer_manager *
-fenced_bufmgr_create(struct buffer_manager *provider,
+struct pb_manager *
+fenced_bufmgr_create(struct pb_manager *provider,
struct pipe_winsys *winsys)
{
- struct fenced_buffer_manager *fenced_mgr;
+ struct fenced_pb_manager *fenced_mgr;
- fenced_mgr = (struct fenced_buffer_manager *)calloc(1, sizeof(*fenced_mgr));
+ fenced_mgr = (struct fenced_pb_manager *)CALLOC(1, sizeof(*fenced_mgr));
if (!fenced_mgr)
return NULL;
@@ -120,7 +124,7 @@ fenced_bufmgr_create(struct buffer_manager *provider,
fenced_mgr->provider = provider;
fenced_mgr->fenced_list = fenced_buffer_list_create(winsys);
if(!fenced_mgr->fenced_list) {
- free(fenced_mgr);
+ FREE(fenced_mgr);
return NULL;
}
diff --git a/src/mesa/pipe/pipebuffer/pb_bufmgr_mm.c b/src/mesa/pipe/pipebuffer/pb_bufmgr_mm.c
index e9bc34b4a4..2a62702c36 100644
--- a/src/mesa/pipe/pipebuffer/pb_bufmgr_mm.c
+++ b/src/mesa/pipe/pipebuffer/pb_bufmgr_mm.c
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 1999 Wittawat Yamwong
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -34,15 +35,12 @@
#include <assert.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "main/imports.h"
-#include "glapi/glthread.h"
-#include "main/mm.h"
#include "linked_list.h"
#include "p_defines.h"
+#include "p_thread.h"
+#include "p_util.h"
#include "pb_buffer.h"
#include "pb_bufmgr.h"
@@ -53,9 +51,309 @@
#define SUPER(__derived) (&(__derived)->base)
-struct mm_buffer_manager
+struct mem_block
{
- struct buffer_manager base;
+ struct mem_block *next, *prev;
+ struct mem_block *next_free, *prev_free;
+ struct mem_block *heap;
+ int ofs, size;
+ unsigned int free:1;
+ unsigned int reserved:1;
+};
+
+
+#ifdef DEBUG
+/**
+ * For debugging purposes.
+ */
+static void
+mmDumpMemInfo(const struct mem_block *heap)
+{
+ fprintf(stderr, "Memory heap %p:\n", (void *)heap);
+ if (heap == 0) {
+ fprintf(stderr, " heap == 0\n");
+ } else {
+ const struct mem_block *p;
+
+ for(p = heap->next; p != heap; p = p->next) {
+ fprintf(stderr, " Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
+ p->free ? 'F':'.',
+ p->reserved ? 'R':'.');
+ }
+
+ fprintf(stderr, "\nFree list:\n");
+
+ for(p = heap->next_free; p != heap; p = p->next_free) {
+ fprintf(stderr, " FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
+ p->free ? 'F':'.',
+ p->reserved ? 'R':'.');
+ }
+
+ }
+ fprintf(stderr, "End of memory blocks\n");
+}
+#endif
+
+
+/**
+ * input: total size in bytes
+ * return: a heap pointer if OK, NULL if error
+ */
+static struct mem_block *
+mmInit(int ofs, int size)
+{
+ struct mem_block *heap, *block;
+
+ if (size <= 0)
+ return NULL;
+
+ heap = CALLOC_STRUCT(mem_block);
+ if (!heap)
+ return NULL;
+
+ block = CALLOC_STRUCT(mem_block);
+ if (!block) {
+ FREE(heap);
+ return NULL;
+ }
+
+ heap->next = block;
+ heap->prev = block;
+ heap->next_free = block;
+ heap->prev_free = block;
+
+ block->heap = heap;
+ block->next = heap;
+ block->prev = heap;
+ block->next_free = heap;
+ block->prev_free = heap;
+
+ block->ofs = ofs;
+ block->size = size;
+ block->free = 1;
+
+ return heap;
+}
+
+
+static struct mem_block *
+SliceBlock(struct mem_block *p,
+ int startofs, int size,
+ int reserved, int alignment)
+{
+ struct mem_block *newblock;
+
+ /* break left [p, newblock, p->next], then p = newblock */
+ if (startofs > p->ofs) {
+ newblock = CALLOC_STRUCT(mem_block);
+ if (!newblock)
+ return NULL;
+ newblock->ofs = startofs;
+ newblock->size = p->size - (startofs - p->ofs);
+ newblock->free = 1;
+ newblock->heap = p->heap;
+
+ newblock->next = p->next;
+ newblock->prev = p;
+ p->next->prev = newblock;
+ p->next = newblock;
+
+ newblock->next_free = p->next_free;
+ newblock->prev_free = p;
+ p->next_free->prev_free = newblock;
+ p->next_free = newblock;
+
+ p->size -= newblock->size;
+ p = newblock;
+ }
+
+ /* break right, also [p, newblock, p->next] */
+ if (size < p->size) {
+ newblock = CALLOC_STRUCT(mem_block);
+ if (!newblock)
+ return NULL;
+ newblock->ofs = startofs + size;
+ newblock->size = p->size - size;
+ newblock->free = 1;
+ newblock->heap = p->heap;
+
+ newblock->next = p->next;
+ newblock->prev = p;
+ p->next->prev = newblock;
+ p->next = newblock;
+
+ newblock->next_free = p->next_free;
+ newblock->prev_free = p;
+ p->next_free->prev_free = newblock;
+ p->next_free = newblock;
+
+ p->size = size;
+ }
+
+ /* p = middle block */
+ p->free = 0;
+
+ /* Remove p from the free list:
+ */
+ p->next_free->prev_free = p->prev_free;
+ p->prev_free->next_free = p->next_free;
+
+ p->next_free = 0;
+ p->prev_free = 0;
+
+ p->reserved = reserved;
+ return p;
+}
+
+
+/**
+ * Allocate 'size' bytes with 2^align2 bytes alignment,
+ * restrict the search to free memory after 'startSearch'
+ * depth and back buffers should be in different 4mb banks
+ * to get better page hits if possible
+ * input: size = size of block
+ * align2 = 2^align2 bytes alignment
+ * startSearch = linear offset from start of heap to begin search
+ * return: pointer to the allocated block, 0 if error
+ */
+static struct mem_block *
+mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch)
+{
+ struct mem_block *p;
+ const int mask = (1 << align2)-1;
+ int startofs = 0;
+ int endofs;
+
+ if (!heap || align2 < 0 || size <= 0)
+ return NULL;
+
+ for (p = heap->next_free; p != heap; p = p->next_free) {
+ assert(p->free);
+
+ startofs = (p->ofs + mask) & ~mask;
+ if ( startofs < startSearch ) {
+ startofs = startSearch;
+ }
+ endofs = startofs+size;
+ if (endofs <= (p->ofs+p->size))
+ break;
+ }
+
+ if (p == heap)
+ return NULL;
+
+ assert(p->free);
+ p = SliceBlock(p,startofs,size,0,mask+1);
+
+ return p;
+}
+
+
+#if 0
+/**
+ * Free block starts at offset
+ * input: pointer to a heap, start offset
+ * return: pointer to a block
+ */
+static struct mem_block *
+mmFindBlock(struct mem_block *heap, int start)
+{
+ struct mem_block *p;
+
+ for (p = heap->next; p != heap; p = p->next) {
+ if (p->ofs == start)
+ return p;
+ }
+
+ return NULL;
+}
+#endif
+
+
+static INLINE int
+Join2Blocks(struct mem_block *p)
+{
+ /* XXX there should be some assertions here */
+
+ /* NOTE: heap->free == 0 */
+
+ if (p->free && p->next->free) {
+ struct mem_block *q = p->next;
+
+ assert(p->ofs + p->size == q->ofs);
+ p->size += q->size;
+
+ p->next = q->next;
+ q->next->prev = p;
+
+ q->next_free->prev_free = q->prev_free;
+ q->prev_free->next_free = q->next_free;
+
+ FREE(q);
+ return 1;
+ }
+ return 0;
+}
+
+
+/**
+ * Free block starts at offset
+ * input: pointer to a block
+ * return: 0 if OK, -1 if error
+ */
+static int
+mmFreeMem(struct mem_block *b)
+{
+ if (!b)
+ return 0;
+
+ if (b->free) {
+ fprintf(stderr, "block already free\n");
+ return -1;
+ }
+ if (b->reserved) {
+ fprintf(stderr, "block is reserved\n");
+ return -1;
+ }
+
+ b->free = 1;
+ b->next_free = b->heap->next_free;
+ b->prev_free = b->heap;
+ b->next_free->prev_free = b;
+ b->prev_free->next_free = b;
+
+ Join2Blocks(b);
+ if (b->prev != b->heap)
+ Join2Blocks(b->prev);
+
+ return 0;
+}
+
+
+/**
+ * destroy MM
+ */
+static void
+mmDestroy(struct mem_block *heap)
+{
+ struct mem_block *p;
+
+ if (!heap)
+ return;
+
+ for (p = heap->next; p != heap; ) {
+ struct mem_block *next = p->next;
+ FREE(p);
+ p = next;
+ }
+
+ FREE(heap);
+}
+
+
+struct mm_pb_manager
+{
+ struct pb_manager base;
_glthread_Mutex mutex;
@@ -64,31 +362,31 @@ struct mm_buffer_manager
size_t align2;
- struct pipe_buffer *buffer;
+ struct pb_buffer *buffer;
void *map;
};
-static inline struct mm_buffer_manager *
-mm_buffer_manager(struct buffer_manager *mgr)
+static inline struct mm_pb_manager *
+mm_pb_manager(struct pb_manager *mgr)
{
assert(mgr);
- return (struct mm_buffer_manager *)mgr;
+ return (struct mm_pb_manager *)mgr;
}
struct mm_buffer
{
- struct pipe_buffer base;
+ struct pb_buffer base;
- struct mm_buffer_manager *mgr;
+ struct mm_pb_manager *mgr;
struct mem_block *block;
};
static inline struct mm_buffer *
-mm_buffer(struct pipe_buffer *buf)
+mm_buffer(struct pb_buffer *buf)
{
assert(buf);
return (struct mm_buffer *)buf;
@@ -96,75 +394,73 @@ mm_buffer(struct pipe_buffer *buf)
static void
-mm_buffer_reference(struct pipe_buffer *buf)
-{
- /* No-op */
-}
-
-
-static void
-mm_buffer_release(struct pipe_buffer *buf)
+mm_buffer_destroy(struct pb_buffer *buf)
{
struct mm_buffer *mm_buf = mm_buffer(buf);
- struct mm_buffer_manager *mm = mm_buf->mgr;
+ struct mm_pb_manager *mm = mm_buf->mgr;
_glthread_LOCK_MUTEX(mm->mutex);
mmFreeMem(mm_buf->block);
- free(buf);
+ FREE(buf);
_glthread_UNLOCK_MUTEX(mm->mutex);
}
static void *
-mm_buffer_map(struct pipe_buffer *buf,
+mm_buffer_map(struct pb_buffer *buf,
unsigned flags)
{
struct mm_buffer *mm_buf = mm_buffer(buf);
- struct mm_buffer_manager *mm = mm_buf->mgr;
+ struct mm_pb_manager *mm = mm_buf->mgr;
return (unsigned char *) mm->map + mm_buf->block->ofs;
}
static void
-mm_buffer_unmap(struct pipe_buffer *buf)
+mm_buffer_unmap(struct pb_buffer *buf)
{
/* No-op */
}
static void
-mm_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+mm_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset)
{
struct mm_buffer *mm_buf = mm_buffer(buf);
- struct mm_buffer_manager *mm = mm_buf->mgr;
- buffer_get_base_buffer(mm->buffer, base_buf, offset);
+ struct mm_pb_manager *mm = mm_buf->mgr;
+ pb_get_base_buffer(mm->buffer, base_buf, offset);
*offset += mm_buf->block->ofs;
}
-static const struct pipe_buffer_vtbl
+static const struct pb_vtbl
mm_buffer_vtbl = {
- mm_buffer_reference,
- mm_buffer_release,
+ mm_buffer_destroy,
mm_buffer_map,
mm_buffer_unmap,
mm_buffer_get_base_buffer
};
-static struct pipe_buffer *
-mm_bufmgr_create_buffer(struct buffer_manager *mgr,
- size_t size)
+static struct pb_buffer *
+mm_bufmgr_create_buffer(struct pb_manager *mgr,
+ size_t size,
+ const struct pb_desc *desc)
{
- struct mm_buffer_manager *mm = mm_buffer_manager(mgr);
+ struct mm_pb_manager *mm = mm_pb_manager(mgr);
struct mm_buffer *mm_buf;
+ /* We don't handle alignments larger then the one initially setup */
+ assert(desc->alignment % (1 << mm->align2) == 0);
+ if(desc->alignment % (1 << mm->align2))
+ return NULL;
+
_glthread_LOCK_MUTEX(mm->mutex);
- mm_buf = (struct mm_buffer *)malloc(sizeof(*mm_buf));
+ mm_buf = CALLOC_STRUCT(mm_buffer);
if (!mm_buf) {
_glthread_UNLOCK_MUTEX(mm->mutex);
return NULL;
@@ -184,7 +480,7 @@ mm_bufmgr_create_buffer(struct buffer_manager *mgr,
mm_buf->block = mmAllocMem(mm->heap, size, mm->align2, 0);
if(!mm_buf->block) {
assert(0);
- free(mm_buf);
+ FREE(mm_buf);
_glthread_UNLOCK_MUTEX(mm->mutex);
return NULL;
}
@@ -200,33 +496,33 @@ mm_bufmgr_create_buffer(struct buffer_manager *mgr,
static void
-mm_bufmgr_destroy(struct buffer_manager *mgr)
+mm_bufmgr_destroy(struct pb_manager *mgr)
{
- struct mm_buffer_manager *mm = mm_buffer_manager(mgr);
+ struct mm_pb_manager *mm = mm_pb_manager(mgr);
_glthread_LOCK_MUTEX(mm->mutex);
mmDestroy(mm->heap);
- buffer_unmap(mm->buffer);
- buffer_release(mm->buffer);
+ pb_unmap(mm->buffer);
+ pb_destroy(mm->buffer);
_glthread_UNLOCK_MUTEX(mm->mutex);
- free(mgr);
+ FREE(mgr);
}
-struct buffer_manager *
-mm_bufmgr_create_from_buffer(struct pipe_buffer *buffer,
+struct pb_manager *
+mm_bufmgr_create_from_buffer(struct pb_buffer *buffer,
size_t size, size_t align2)
{
- struct mm_buffer_manager *mm;
+ struct mm_pb_manager *mm;
if(!buffer)
return NULL;
- mm = (struct mm_buffer_manager *)calloc(1, sizeof(*mm));
+ mm = CALLOC_STRUCT(mm_pb_manager);
if (!mm)
return NULL;
@@ -240,8 +536,9 @@ mm_bufmgr_create_from_buffer(struct pipe_buffer *buffer,
mm->buffer = buffer;
- mm->map = buffer_map(mm->buffer,
- PIPE_BUFFER_FLAG_READ | PIPE_BUFFER_FLAG_WRITE );
+ mm->map = pb_map(mm->buffer,
+ PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE);
if(!mm->map)
goto failure;
@@ -255,29 +552,34 @@ failure:
if(mm->heap)
mmDestroy(mm->heap);
if(mm->map)
- buffer_unmap(mm->buffer);
+ pb_unmap(mm->buffer);
if(mm)
- free(mm);
+ FREE(mm);
return NULL;
}
-struct buffer_manager *
-mm_bufmgr_create(struct buffer_manager *provider,
+struct pb_manager *
+mm_bufmgr_create(struct pb_manager *provider,
size_t size, size_t align2)
{
- struct pipe_buffer *buffer;
- struct buffer_manager *mgr;
+ struct pb_buffer *buffer;
+ struct pb_manager *mgr;
+ struct pb_desc desc;
assert(provider);
assert(provider->create_buffer);
- buffer = provider->create_buffer(provider, size);
+
+ memset(&desc, 0, sizeof(desc));
+ desc.alignment = 1 << align2;
+
+ buffer = provider->create_buffer(provider, size, &desc);
if (!buffer)
return NULL;
mgr = mm_bufmgr_create_from_buffer(buffer, size, align2);
if (!mgr) {
- buffer_release(buffer);
+ pb_destroy(buffer);
return NULL;
}
diff --git a/src/mesa/pipe/pipebuffer/pb_bufmgr_pool.c b/src/mesa/pipe/pipebuffer/pb_bufmgr_pool.c
index ee6fa62500..61c06ec824 100644
--- a/src/mesa/pipe/pipebuffer/pb_bufmgr_pool.c
+++ b/src/mesa/pipe/pipebuffer/pb_bufmgr_pool.c
@@ -37,13 +37,13 @@
#include <assert.h>
#include <stdlib.h>
-#include <unistd.h>
-#include "main/imports.h"
-#include "glapi/glthread.h"
#include "linked_list.h"
+#include "p_compiler.h"
+#include "p_thread.h"
#include "p_defines.h"
+#include "p_util.h"
#include "pb_buffer.h"
#include "pb_bufmgr.h"
@@ -55,39 +55,40 @@
#define SUPER(__derived) (&(__derived)->base)
-struct pool_buffer_manager
+struct pool_pb_manager
{
- struct buffer_manager base;
+ struct pb_manager base;
_glthread_Mutex mutex;
size_t bufSize;
+ size_t bufAlign;
size_t numFree;
size_t numTot;
struct list_head free;
- struct pipe_buffer *buffer;
+ struct pb_buffer *buffer;
void *map;
struct pool_buffer *bufs;
};
-static inline struct pool_buffer_manager *
-pool_buffer_manager(struct buffer_manager *mgr)
+static INLINE struct pool_pb_manager *
+pool_pb_manager(struct pb_manager *mgr)
{
assert(mgr);
- return (struct pool_buffer_manager *)mgr;
+ return (struct pool_pb_manager *)mgr;
}
struct pool_buffer
{
- struct pipe_buffer base;
+ struct pb_buffer base;
- struct pool_buffer_manager *mgr;
+ struct pool_pb_manager *mgr;
struct list_head head;
@@ -95,26 +96,20 @@ struct pool_buffer
};
-static inline struct pool_buffer *
-pool_buffer(struct pipe_buffer *buf)
+static INLINE struct pool_buffer *
+pool_buffer(struct pb_buffer *buf)
{
assert(buf);
return (struct pool_buffer *)buf;
}
-static void
-pool_buffer_reference(struct pipe_buffer *buf)
-{
- /* No-op */
-}
-
static void
-pool_buffer_release(struct pipe_buffer *buf)
+pool_buffer_destroy(struct pb_buffer *buf)
{
struct pool_buffer *pool_buf = pool_buffer(buf);
- struct pool_buffer_manager *pool = pool_buf->mgr;
+ struct pool_pb_manager *pool = pool_buf->mgr;
_glthread_LOCK_MUTEX(pool->mutex);
LIST_ADD(&pool_buf->head, &pool->free);
@@ -124,10 +119,10 @@ pool_buffer_release(struct pipe_buffer *buf)
static void *
-pool_buffer_map(struct pipe_buffer *buf, unsigned flags)
+pool_buffer_map(struct pb_buffer *buf, unsigned flags)
{
struct pool_buffer *pool_buf = pool_buffer(buf);
- struct pool_buffer_manager *pool = pool_buf->mgr;
+ struct pool_pb_manager *pool = pool_buf->mgr;
void *map;
_glthread_LOCK_MUTEX(pool->mutex);
@@ -138,42 +133,44 @@ pool_buffer_map(struct pipe_buffer *buf, unsigned flags)
static void
-pool_buffer_unmap(struct pipe_buffer *buf)
+pool_buffer_unmap(struct pb_buffer *buf)
{
/* No-op */
}
static void
-pool_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+pool_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset)
{
struct pool_buffer *pool_buf = pool_buffer(buf);
- struct pool_buffer_manager *pool = pool_buf->mgr;
- buffer_get_base_buffer(pool->buffer, base_buf, offset);
+ struct pool_pb_manager *pool = pool_buf->mgr;
+ pb_get_base_buffer(pool->buffer, base_buf, offset);
*offset += pool_buf->start;
}
-static const struct pipe_buffer_vtbl
+static const struct pb_vtbl
pool_buffer_vtbl = {
- pool_buffer_reference,
- pool_buffer_release,
+ pool_buffer_destroy,
pool_buffer_map,
pool_buffer_unmap,
pool_buffer_get_base_buffer
};
-static struct pipe_buffer *
-pool_bufmgr_create_buffer(struct buffer_manager *mgr, size_t size)
+static struct pb_buffer *
+pool_bufmgr_create_buffer(struct pb_manager *mgr,
+ size_t size,
+ const struct pb_desc *desc)
{
- struct pool_buffer_manager *pool = pool_buffer_manager(mgr);
+ struct pool_pb_manager *pool = pool_pb_manager(mgr);
struct pool_buffer *pool_buf;
struct list_head *item;
assert(size == pool->bufSize);
+ assert(desc->alignment % pool->bufAlign == 0);
_glthread_LOCK_MUTEX(pool->mutex);
@@ -201,32 +198,33 @@ pool_bufmgr_create_buffer(struct buffer_manager *mgr, size_t size)
static void
-pool_bufmgr_destroy(struct buffer_manager *mgr)
+pool_bufmgr_destroy(struct pb_manager *mgr)
{
- struct pool_buffer_manager *pool = pool_buffer_manager(mgr);
+ struct pool_pb_manager *pool = pool_pb_manager(mgr);
_glthread_LOCK_MUTEX(pool->mutex);
- free(pool->bufs);
+ FREE(pool->bufs);
- buffer_unmap(pool->buffer);
- buffer_release(pool->buffer);
+ pb_unmap(pool->buffer);
+ pb_destroy(pool->buffer);
_glthread_UNLOCK_MUTEX(pool->mutex);
- free(mgr);
+ FREE(mgr);
}
-struct buffer_manager *
-pool_bufmgr_create(struct buffer_manager *provider,
+struct pb_manager *
+pool_bufmgr_create(struct pb_manager *provider,
size_t numBufs,
- size_t bufSize)
+ size_t bufSize,
+ const struct pb_desc *desc)
{
- struct pool_buffer_manager *pool;
+ struct pool_pb_manager *pool;
struct pool_buffer *pool_buf;
- int i;
+ size_t i;
- pool = (struct pool_buffer_manager *)calloc(1, sizeof(*pool));
+ pool = (struct pool_pb_manager *)CALLOC(1, sizeof(*pool));
if (!pool)
return NULL;
@@ -238,20 +236,21 @@ pool_bufmgr_create(struct buffer_manager *provider,
pool->numTot = numBufs;
pool->numFree = numBufs;
pool->bufSize = bufSize;
+ pool->bufAlign = desc->alignment;
_glthread_INIT_MUTEX(pool->mutex);
- pool->buffer = provider->create_buffer(provider, numBufs*bufSize);
+ pool->buffer = provider->create_buffer(provider, numBufs*bufSize, desc);
if (!pool->buffer)
goto failure;
- pool->map = buffer_map(pool->buffer,
- PIPE_BUFFER_FLAG_READ |
- PIPE_BUFFER_FLAG_WRITE );
+ pool->map = pb_map(pool->buffer,
+ PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE);
if(!pool->map)
goto failure;
- pool->bufs = (struct pool_buffer *) malloc(numBufs * sizeof(*pool->bufs));
+ pool->bufs = (struct pool_buffer *) MALLOC(numBufs * sizeof(*pool->bufs));
if (!pool->bufs)
goto failure;
@@ -268,12 +267,12 @@ pool_bufmgr_create(struct buffer_manager *provider,
failure:
if(pool->bufs)
- free(pool->bufs);
+ FREE(pool->bufs);
if(pool->map)
- buffer_unmap(pool->buffer);
+ pb_unmap(pool->buffer);
if(pool->buffer)
- buffer_release(pool->buffer);
+ pb_destroy(pool->buffer);
if(pool)
- free(pool);
+ FREE(pool);
return NULL;
}