Mesa (master): gallium: Allow to specify how much will be read / was written in buffer map/unmap.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Wed Mar 4 21:46:41 UTC 2009


Module: Mesa
Branch: master
Commit: 60e5fe65067da76dea816535bec1e9073adc0ba7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=60e5fe65067da76dea816535bec1e9073adc0ba7

Author: José Fonseca <jfonseca at vmware.com>
Date:   Tue Feb 24 12:29:09 2009 +0000

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 4eb928d..a7ce0c2 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 341d1ca..69db80e 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 );
 




More information about the mesa-commit mailing list