summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2009-02-24 12:29:09 +0000
committerJosé Fonseca <[email protected]>2009-02-24 12:29:09 +0000
commit60e5fe65067da76dea816535bec1e9073adc0ba7 (patch)
tree5db1052818795cbe80a13751a1a1c2acd176e343 /src
parent693fac8ae2e5812265222b1335695bd33b90bd8a (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/include/pipe/p_inlines.h71
-rw-r--r--src/gallium/include/pipe/p_screen.h28
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 );