#endif
-/**
- * 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)
-{
- /* bump the refcount first */
- if (surf) {
- assert(surf->refcount);
- surf->refcount++;
- }
-
- if (*ptr) {
- struct pipe_screen *screen;
- assert((*ptr)->refcount);
- assert((*ptr)->texture);
- screen = (*ptr)->texture->screen;
- screen->tex_surface_release( screen, ptr );
- assert(!*ptr);
- }
-
- *ptr = surf;
-}
-
-
-/**
- * \sa pipe_surface_reference
- */
-static INLINE void
-pipe_transfer_reference(struct pipe_transfer **ptr, struct pipe_transfer *trans)
-{
- /* bump the refcount first */
- if (trans) {
- assert(trans->refcount);
- trans->refcount++;
- }
-
- if (*ptr) {
- struct pipe_screen *screen;
- assert((*ptr)->refcount);
- assert((*ptr)->texture);
- screen = (*ptr)->texture->screen;
- screen->tex_transfer_release( screen, ptr );
- assert(!*ptr);
- }
-
- *ptr = trans;
-}
-
-
-/**
- * \sa pipe_surface_reference
- */
-static INLINE void
-pipe_texture_reference(struct pipe_texture **ptr,
- struct pipe_texture *pt)
-{
- 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;
-}
-
-
-static INLINE void
-pipe_texture_release(struct pipe_texture **ptr)
-{
- struct pipe_screen *screen;
- assert(ptr);
- screen = (*ptr)->screen;
- assert((*ptr)->refcount);
- screen->texture_release(screen, ptr);
- *ptr = NULL;
-}
-
-
/**
* Convenience wrappers for screen buffer functions.
*/
unsigned usage)
{
if(screen->buffer_map_range) {
- struct pipe_buffer_range read;
- struct pipe_buffer_range write;
- read.offset = 0;
- read.size = usage & PIPE_BUFFER_USAGE_CPU_READ ? buf->size : 0;
- write.offset = 0;
- write.size = usage & PIPE_BUFFER_USAGE_CPU_WRITE ? buf->size : 0;
- return screen->buffer_map_range(screen, buf, read, write, usage);
+ unsigned offset = 0;
+ unsigned length = buf->size;
+ return screen->buffer_map_range(screen, buf, offset, length, usage);
}
else
return screen->buffer_map(screen, buf, usage);
pipe_buffer_unmap(struct pipe_screen *screen,
struct pipe_buffer *buf)
{
- if(screen->buffer_unmap_range) {
- struct pipe_buffer_range written;
- written.offset = 0;
- written.size = buf->size;
- screen->buffer_unmap_range(screen, buf, written);
- }
- else
- screen->buffer_unmap(screen, buf);
+ screen->buffer_unmap(screen, buf);
}
static INLINE void *
pipe_buffer_map_range(struct pipe_screen *screen,
struct pipe_buffer *buf,
- struct pipe_buffer_range read,
- struct pipe_buffer_range write)
+ unsigned offset,
+ unsigned length,
+ unsigned usage)
{
- unsigned usage = 0;
- if(read.size)
- usage |= PIPE_BUFFER_USAGE_CPU_READ;
- if(write.size)
- usage |= PIPE_BUFFER_USAGE_CPU_WRITE;
+ assert(offset < buf->size);
+ assert(offset + length <= buf->size);
+ assert(length);
if(screen->buffer_map_range)
- return screen->buffer_map_range(screen, buf, read, write, usage);
+ return screen->buffer_map_range(screen, buf, offset, length, usage);
else
return screen->buffer_map(screen, buf, usage);
}
static INLINE void
-pipe_buffer_unmap_range(struct pipe_screen *screen,
- struct pipe_buffer *buf,
- struct pipe_buffer_range written)
+pipe_buffer_flush_mapped_range(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned offset,
+ unsigned length)
{
- if(screen->buffer_unmap_range)
- screen->buffer_unmap_range(screen, buf, written);
- else
- screen->buffer_unmap(screen, buf);
+ 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);
}
static INLINE void
unsigned offset, unsigned size,
const void *data)
{
- struct pipe_buffer_range read;
- struct pipe_buffer_range write;
- uint8_t *map;
+ void *map;
assert(offset < buf->size);
assert(offset + size <= buf->size);
-
- read.offset = 0;
- read.size = 0;
- write.offset = offset;
- write.size = size;
-
- map = pipe_buffer_map_range(screen, buf, read, write);
+ assert(size);
+
+ map = pipe_buffer_map_range(screen, buf, offset, size,
+ PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_FLUSH_EXPLICIT |
+ PIPE_BUFFER_USAGE_DISCARD);
assert(map);
if(map) {
- memcpy(map + offset, data, size);
- pipe_buffer_unmap_range(screen, buf, write);
+ memcpy((uint8_t *)map + offset, data, size);
+ pipe_buffer_flush_mapped_range(screen, buf, offset, size);
+ pipe_buffer_unmap(screen, buf);
+ }
+}
+
+/**
+ * Special case for writing non-overlapping ranges.
+ *
+ * We can avoid GPU/CPU synchronization when writing range that has never
+ * been written before.
+ */
+static INLINE void
+pipe_buffer_write_nooverlap(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned offset, unsigned size,
+ const void *data)
+{
+ 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 |
+ PIPE_BUFFER_USAGE_DISCARD |
+ PIPE_BUFFER_USAGE_UNSYNCHRONIZED);
+ 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);
}
}
unsigned offset, unsigned size,
void *data)
{
- struct pipe_buffer_range read;
- struct pipe_buffer_range write;
- uint8_t *map;
+ void *map;
assert(offset < buf->size);
assert(offset + size <= buf->size);
-
- read.offset = offset;
- read.size = size;
- write.offset = 0;
- write.size = 0;
-
- map = pipe_buffer_map_range(screen, buf, read, write);
+ assert(size);
+
+ map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_READ);
assert(map);
if(map) {
- memcpy(data, map + offset, size);
- pipe_buffer_unmap_range(screen, buf, write);
+ memcpy(data, (const uint8_t *)map + offset, size);
+ pipe_buffer_unmap(screen, buf);
}
}
-/* XXX: thread safety issues!
- */
-static INLINE void
-pipe_buffer_reference(struct pipe_screen *screen,
- struct pipe_buffer **ptr,
- struct pipe_buffer *buf)
+static INLINE void *
+pipe_transfer_map( struct pipe_transfer *transf )
{
- if (buf) {
- assert(buf->refcount);
- buf->refcount++;
- }
+ struct pipe_screen *screen = transf->texture->screen;
+ return screen->transfer_map(screen, transf);
+}
- if (*ptr) {
- assert((*ptr)->refcount);
- if(--(*ptr)->refcount == 0) {
- screen->buffer_destroy( screen, *ptr );
- }
- }
+static INLINE void
+pipe_transfer_unmap( struct pipe_transfer *transf )
+{
+ struct pipe_screen *screen = transf->texture->screen;
+ screen->transfer_unmap(screen, transf);
+}
- *ptr = buf;
+static INLINE void
+pipe_transfer_destroy( struct pipe_transfer *transf )
+{
+ 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
}