#include "p_context.h"
#include "p_defines.h"
#include "p_screen.h"
-#include "p_winsys.h"
#ifdef __cplusplus
#endif
-/* XXX: these are a kludge. will fix when all surfaces are views into
- * textures, and free-floating winsys surfaces go away.
+/**
+ * Convenience wrappers for screen buffer functions.
*/
-static INLINE void *
-pipe_surface_map( struct pipe_surface *surf, unsigned flags )
+
+static INLINE struct pipe_buffer *
+pipe_buffer_create( struct pipe_screen *screen,
+ unsigned alignment, unsigned usage, unsigned size )
{
- if (surf->texture) {
- struct pipe_screen *screen = surf->texture->screen;
- return surf->texture->screen->surface_map( screen, surf, flags );
- }
- else {
- struct pipe_winsys *winsys = surf->winsys;
- char *map = (char *)winsys->buffer_map( winsys, surf->buffer, flags );
- if (map == NULL)
- return NULL;
- return (void *)(map + surf->offset);
- }
+ return screen->buffer_create(screen, alignment, usage, size);
}
-static INLINE void
-pipe_surface_unmap( struct pipe_surface *surf )
+static INLINE struct pipe_buffer *
+pipe_user_buffer_create( struct pipe_screen *screen, void *ptr, unsigned size )
{
- if (surf->texture) {
- struct pipe_screen *screen = surf->texture->screen;
- surf->texture->screen->surface_unmap( screen, surf );
- }
- else {
- struct pipe_winsys *winsys = surf->winsys;
- winsys->buffer_unmap( winsys, surf->buffer );
- }
+ return screen->user_buffer_create(screen, ptr, size);
}
-
-
-/**
- * Set 'ptr' to point to 'surf' and update reference counting.
- * The old thing pointed to, if any, will be unreferenced first.
- * 'surf' may be NULL.
- */
-static INLINE void
-pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
+static INLINE void *
+pipe_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned usage)
{
- /* bump the refcount first */
- if (surf) {
- assert(surf->refcount);
- surf->refcount++;
- }
+ if(screen->buffer_map_range) {
+ unsigned offset = 0;
+ unsigned length = buf->size;
- if (*ptr) {
- assert((*ptr)->refcount);
-
- /* There are currently two sorts of surfaces... This needs to be
- * fixed so that all surfaces are views into a texture.
- */
- if ((*ptr)->texture) {
- struct pipe_screen *screen = (*ptr)->texture->screen;
- screen->tex_surface_release( screen, ptr );
- }
- else {
- struct pipe_winsys *winsys = (*ptr)->winsys;
- winsys->surface_release(winsys, ptr);
- }
-
- assert(!*ptr);
- }
+ /* XXX: Actually we should be using/detecting DISCARD
+ * instead of assuming that WRITE implies discard */
+ if((usage & PIPE_BUFFER_USAGE_CPU_WRITE) &&
+ !(usage & PIPE_BUFFER_USAGE_DISCARD))
+ usage |= PIPE_BUFFER_USAGE_CPU_READ;
- *ptr = surf;
+ return screen->buffer_map_range(screen, buf, offset, length, usage);
+ }
+ else
+ return screen->buffer_map(screen, buf, usage);
}
-
-/* XXX: thread safety issues!
- */
static INLINE void
-winsys_buffer_reference(struct pipe_winsys *winsys,
- struct pipe_buffer **ptr,
- struct pipe_buffer *buf)
+pipe_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buf)
{
- if (buf) {
- assert(buf->refcount);
- buf->refcount++;
- }
-
- if (*ptr) {
- assert((*ptr)->refcount);
- if(--(*ptr)->refcount == 0)
- winsys->buffer_destroy( winsys, *ptr );
- }
-
- *ptr = buf;
+ screen->buffer_unmap(screen, buf);
}
-
-
-/**
- * \sa pipe_surface_reference
- */
-static INLINE void
-pipe_texture_reference(struct pipe_texture **ptr,
- struct pipe_texture *pt)
+static INLINE void *
+pipe_buffer_map_range(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned offset,
+ unsigned length,
+ unsigned usage)
{
- assert(ptr);
-
- if (pt) {
- assert(pt->refcount);
- pt->refcount++;
- }
-
- if (*ptr) {
- struct pipe_screen *screen = (*ptr)->screen;
- assert(screen);
- assert((*ptr)->refcount);
- screen->texture_release(screen, ptr);
-
- assert(!*ptr);
- }
-
- *ptr = pt;
+ assert(offset < buf->size);
+ assert(offset + length <= buf->size);
+ assert(length);
+ if(screen->buffer_map_range)
+ return screen->buffer_map_range(screen, buf, offset, length, usage);
+ else
+ return screen->buffer_map(screen, buf, usage);
}
-
static INLINE void
-pipe_texture_release(struct pipe_texture **ptr)
+pipe_buffer_flush_mapped_range(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned offset,
+ unsigned length)
{
- struct pipe_screen *screen;
- assert(ptr);
- screen = (*ptr)->screen;
- assert((*ptr)->refcount);
- screen->texture_release(screen, ptr);
- *ptr = NULL;
+ assert(offset < buf->size);
+ assert(offset + length <= buf->size);
+ assert(length);
+ if(screen->buffer_flush_mapped_range)
+ screen->buffer_flush_mapped_range(screen, buf, offset, length);
}
-
-/**
- * Convenience wrappers for winsys buffer functions.
- */
-
-static INLINE struct pipe_buffer *
-pipe_buffer_create( struct pipe_screen *screen,
- unsigned alignment, unsigned usage, unsigned size )
+static INLINE void
+pipe_buffer_write(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned offset, unsigned size,
+ const void *data)
{
- return screen->winsys->buffer_create(screen->winsys, alignment, usage, size);
+ void *map;
+
+ assert(offset < buf->size);
+ assert(offset + size <= buf->size);
+ assert(size);
+
+ map = pipe_buffer_map_range(screen, buf, offset, size,
+ PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_FLUSH_EXPLICIT);
+ assert(map);
+ if(map) {
+ memcpy((uint8_t *)map + offset, data, size);
+ pipe_buffer_flush_mapped_range(screen, buf, offset, size);
+ pipe_buffer_unmap(screen, buf);
+ }
}
-static INLINE struct pipe_buffer *
-pipe_user_buffer_create( struct pipe_screen *screen, void *ptr, unsigned size )
+static INLINE void
+pipe_buffer_read(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned offset, unsigned size,
+ void *data)
{
- return screen->winsys->user_buffer_create(screen->winsys, ptr, size);
+ void *map;
+
+ assert(offset < buf->size);
+ assert(offset + size <= buf->size);
+ assert(size);
+
+ map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_READ);
+ assert(map);
+ if(map) {
+ memcpy(data, (const uint8_t *)map + offset, size);
+ pipe_buffer_unmap(screen, buf);
+ }
}
static INLINE void *
-pipe_buffer_map(struct pipe_screen *screen,
- struct pipe_buffer *buf,
- unsigned usage)
+pipe_transfer_map( struct pipe_transfer *transf )
{
- return screen->winsys->buffer_map(screen->winsys, buf, usage);
+ struct pipe_screen *screen = transf->texture->screen;
+ return screen->transfer_map(screen, transf);
}
static INLINE void
-pipe_buffer_unmap(struct pipe_screen *screen,
- struct pipe_buffer *buf)
+pipe_transfer_unmap( struct pipe_transfer *transf )
{
- screen->winsys->buffer_unmap(screen->winsys, buf);
+ struct pipe_screen *screen = transf->texture->screen;
+ screen->transfer_unmap(screen, transf);
}
-/* XXX when we're using this everywhere, get rid of
- * winsys_buffer_reference() above.
- */
static INLINE void
-pipe_buffer_reference(struct pipe_screen *screen,
- struct pipe_buffer **ptr,
- struct pipe_buffer *buf)
+pipe_transfer_destroy( struct pipe_transfer *transf )
{
- winsys_buffer_reference(screen->winsys, ptr, buf);
+ struct pipe_screen *screen = transf->texture->screen;
+ screen->tex_transfer_destroy(transf);
}
+static INLINE unsigned
+pipe_transfer_buffer_flags( struct pipe_transfer *transf )
+{
+ switch (transf->usage & PIPE_TRANSFER_READ_WRITE) {
+ case PIPE_TRANSFER_READ_WRITE:
+ return PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE;
+ case PIPE_TRANSFER_READ:
+ return PIPE_BUFFER_USAGE_CPU_READ;
+ case PIPE_TRANSFER_WRITE:
+ return PIPE_BUFFER_USAGE_CPU_WRITE;
+ default:
+ debug_assert(0);
+ return 0;
+ }
+}
#ifdef __cplusplus
}