From 60e5fe65067da76dea816535bec1e9073adc0ba7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 24 Feb 2009 12:29:09 +0000 Subject: [PATCH] gallium: Allow to specify how much will be read / was written in buffer map/unmap. This allows the pipe driver to do more efficient DMA upload/downloads, by avoiding to read/write unneeded/unmodified data. --- src/gallium/include/pipe/p_inlines.h | 71 +++++++++++++++++++++++++--- src/gallium/include/pipe/p_screen.h | 28 +++++++++++ 2 files changed, 93 insertions(+), 6 deletions(-) diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index 4eb928d882f..a7ce0c2c277 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -151,14 +151,59 @@ pipe_buffer_map(struct pipe_screen *screen, struct pipe_buffer *buf, unsigned usage) { - return screen->buffer_map(screen, buf, 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); + } + else + return screen->buffer_map(screen, buf, usage); } static INLINE void pipe_buffer_unmap(struct pipe_screen *screen, struct pipe_buffer *buf) { - screen->buffer_unmap(screen, 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); +} + +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 usage = 0; + if(read.size) + usage |= PIPE_BUFFER_USAGE_CPU_READ; + if(write.size) + usage |= PIPE_BUFFER_USAGE_CPU_WRITE; + if(screen->buffer_map_range) + return screen->buffer_map_range(screen, buf, read, write, 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) +{ + if(screen->buffer_unmap_range) + screen->buffer_unmap_range(screen, buf, written); + else + screen->buffer_unmap(screen, buf); } static INLINE void @@ -167,16 +212,23 @@ pipe_buffer_write(struct pipe_screen *screen, unsigned offset, unsigned size, const void *data) { + struct pipe_buffer_range read; + struct pipe_buffer_range write; uint8_t *map; assert(offset < buf->size); assert(offset + size <= buf->size); - map = pipe_buffer_map(screen, buf, PIPE_BUFFER_USAGE_CPU_WRITE); + read.offset = 0; + read.size = 0; + write.offset = offset; + write.size = size; + + map = pipe_buffer_map_range(screen, buf, read, write); assert(map); if(map) { memcpy(map + offset, data, size); - pipe_buffer_unmap(screen, buf); + pipe_buffer_unmap_range(screen, buf, write); } } @@ -186,16 +238,23 @@ pipe_buffer_read(struct pipe_screen *screen, unsigned offset, unsigned size, void *data) { + struct pipe_buffer_range read; + struct pipe_buffer_range write; uint8_t *map; assert(offset < buf->size); assert(offset + size <= buf->size); - map = pipe_buffer_map(screen, buf, PIPE_BUFFER_USAGE_CPU_READ); + read.offset = offset; + read.size = size; + write.offset = 0; + write.size = 0; + + map = pipe_buffer_map_range(screen, buf, read, write); assert(map); if(map) { memcpy(data, map + offset, size); - pipe_buffer_unmap(screen, buf); + pipe_buffer_unmap_range(screen, buf, write); } } diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 341d1caea0f..69db80ee3f3 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -56,6 +56,13 @@ struct pipe_buffer; +struct pipe_buffer_range +{ + unsigned offset; + unsigned size; +}; + + /** * Gallium screen/adapter context. Basically everything * hardware-specific that doesn't actually require a rendering @@ -213,6 +220,27 @@ struct pipe_screen { void (*buffer_unmap)( struct pipe_screen *screen, struct pipe_buffer *buf ); + /** + * Map a subrange of the buffer data store into the client's address space. + * + * Return pointer is always relative to offset 0, regardless of the + * read/write ranges. + */ + void *(*buffer_map_range)( struct pipe_screen *screen, + struct pipe_buffer *buf, + struct pipe_buffer_range read, + struct pipe_buffer_range write, + unsigned usage /* XXX: deprecated? */); + + /** + * Unmap a buffer. + * + * written is the range that the client actually wrote. + */ + void (*buffer_unmap_range)( struct pipe_screen *screen, + struct pipe_buffer *buf, + struct pipe_buffer_range written); + void (*buffer_destroy)( struct pipe_screen *screen, struct pipe_buffer *buf ); -- 2.30.2