OSDN Git Service

Merge commit 'origin/master' into gallium-map-range
authorJosé Fonseca <jfonseca@vmware.com>
Wed, 4 Mar 2009 17:42:36 +0000 (17:42 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Wed, 4 Mar 2009 17:42:36 +0000 (17:42 +0000)
src/gallium/include/pipe/p_inlines.h
src/gallium/include/pipe/p_screen.h
src/mesa/state_tracker/st_cb_bufferobjects.c
src/mesa/vbo/vbo_exec_draw.c

index a68b521..4e5252d 100644 (file)
@@ -60,7 +60,13 @@ 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) {
+      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);
 }
 
 static INLINE void
@@ -70,6 +76,36 @@ pipe_buffer_unmap(struct pipe_screen *screen,
    screen->buffer_unmap(screen, buf);
 }
 
+static INLINE void *
+pipe_buffer_map_range(struct pipe_screen *screen,
+                struct pipe_buffer *buf,
+                unsigned offset,
+                unsigned length,
+                unsigned usage)
+{
+   assert(offset < buf->size);
+   assert(offset + length <= buf->size);
+   if(screen->buffer_map_range)
+      return screen->buffer_map_range(screen, buf, offset, length, usage);
+   else {
+      uint8_t *map;
+      map = screen->buffer_map(screen, buf, usage);
+      return map ? map + offset : NULL;
+   }
+}
+
+static INLINE void
+pipe_buffer_flush_mapped_range(struct pipe_screen *screen,
+                               struct pipe_buffer *buf,
+                               unsigned offset,
+                               unsigned length)
+{
+   assert(offset < buf->size);
+   assert(offset + length <= buf->size);
+   if(screen->buffer_flush_mapped_range)
+      screen->buffer_flush_mapped_range(screen, buf, offset, length);
+}
+
 static INLINE void
 pipe_buffer_write(struct pipe_screen *screen,
                   struct pipe_buffer *buf,
@@ -81,10 +117,11 @@ pipe_buffer_write(struct pipe_screen *screen,
    assert(offset < buf->size);
    assert(offset + size <= buf->size);
    
-   map = pipe_buffer_map(screen, buf, PIPE_BUFFER_USAGE_CPU_WRITE);
+   map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_WRITE);
    assert(map);
    if(map) {
-      memcpy(map + offset, data, size);
+      memcpy(map, data, size);
+      pipe_buffer_flush_mapped_range(screen, buf, offset, size);
       pipe_buffer_unmap(screen, buf);
    }
 }
@@ -100,10 +137,10 @@ pipe_buffer_read(struct pipe_screen *screen,
    assert(offset < buf->size);
    assert(offset + size <= buf->size);
    
-   map = pipe_buffer_map(screen, buf, PIPE_BUFFER_USAGE_CPU_READ);
+   map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_READ);
    assert(map);
    if(map) {
-      memcpy(data, map + offset, size);
+      memcpy(data, map, size);
       pipe_buffer_unmap(screen, buf);
    }
 }
index 3688d58..d7e79ec 100644 (file)
@@ -202,9 +202,28 @@ struct pipe_screen {
    void *(*buffer_map)( struct pipe_screen *screen,
                        struct pipe_buffer *buf,
                        unsigned usage );
+   /**
+    * 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,
+                              unsigned offset,
+                              unsigned length,
+                              unsigned usage);
+
+   /**
+    * written is the range that the client actually wrote. 
+    */
+   void (*buffer_flush_mapped_range)( struct pipe_screen *screen,
+                                      struct pipe_buffer *buf,
+                                      unsigned offset,
+                                      unsigned length);
 
    void (*buffer_unmap)( struct pipe_screen *screen,
-                        struct pipe_buffer *buf );
+                         struct pipe_buffer *buf );
 
    void (*buffer_destroy)( struct pipe_buffer *buf );
 
index 5209923..45fbe8c 100644 (file)
@@ -217,6 +217,7 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target,
    struct pipe_context *pipe = st_context(ctx)->pipe;
    struct st_buffer_object *st_obj = st_buffer_object(obj);
    GLuint flags = 0;
+   char *map;
 
    if (access & GL_MAP_WRITE_BIT)
       flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
@@ -230,11 +231,25 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target,
    if (access & MESA_MAP_NOWAIT_BIT)
       flags |= PIPE_BUFFER_USAGE_DONTBLOCK;
 
-   obj->Pointer = pipe_buffer_map(pipe->screen, st_obj->buffer, flags);
-   return obj->Pointer;
+   map = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags);
+   /* this is expected to point to the buffer start, in order to calculate the
+    * vertices offsets 
+    */
+   obj->Pointer = map ? map - offset : NULL;
+   return map;
 }
 
 
+static void
+st_bufferobj_flush_mapped_range(GLcontext *ctx, GLenum target, 
+                                GLintptr offset, GLsizeiptr length,
+                                struct gl_buffer_object *obj)
+{
+   struct pipe_context *pipe = st_context(ctx)->pipe;
+   struct st_buffer_object *st_obj = st_buffer_object(obj);
+
+   pipe_buffer_flush_mapped_range(pipe->screen, st_obj->buffer, offset, length);
+}
 
 
 /**
@@ -262,5 +277,6 @@ st_init_bufferobject_functions(struct dd_function_table *functions)
    functions->GetBufferSubData = st_bufferobj_get_subdata;
    functions->MapBuffer = st_bufferobj_map;
    functions->MapBufferRange = st_bufferobj_map_range;
+   functions->FlushMappedBufferRange = st_bufferobj_flush_mapped_range;
    functions->UnmapBuffer = st_bufferobj_unmap;
 }
index 59e176b..6f8d1f8 100644 (file)
@@ -240,6 +240,13 @@ static void vbo_exec_vtx_unmap( struct vbo_exec_context *exec )
 
    if (exec->vtx.bufferobj->Name) {
       GLcontext *ctx = exec->ctx;
+      GLintptr offset = exec->vtx.buffer_used;
+      GLsizeiptr length = (exec->vtx.buffer_ptr - exec->vtx.buffer_map) * sizeof(float);
+      
+      if(ctx->Driver.FlushMappedBufferRange)
+         ctx->Driver.FlushMappedBufferRange(ctx, target,
+                                            offset, length,
+                                            exec->vtx.bufferobj);
 
       exec->vtx.buffer_used += (exec->vtx.buffer_ptr -
                                 exec->vtx.buffer_map) * sizeof(float);
@@ -286,11 +293,8 @@ void vbo_exec_vtx_map( struct vbo_exec_context *exec )
                                                exec->vtx.bufferobj);
       exec->vtx.buffer_ptr = exec->vtx.buffer_map;
    }
-
-   if (exec->vtx.buffer_map) {
-      exec->vtx.buffer_map += exec->vtx.buffer_used / sizeof(float);
-   }
-   else {
+   
+   if (!exec->vtx.buffer_map) {
       exec->vtx.buffer_used = 0;
 
       ctx->Driver.BufferData(ctx, target,