i965/vec4: Print the predicate in dump_instructions().
[mesa.git] / src / mesa / vbo / vbo_save_api.c
index 26951bd9413d9b63232147140f96572515d162d5..1c6b91942d52dba7bfa1c9c0159588c4dd2630c5 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
 
-Copyright 2002-2008 Tungsten Graphics Inc., Cedar Park, Texas.
+Copyright 2002-2008 VMware, Inc.
 
 All Rights Reserved.
 
@@ -18,7 +18,7 @@ Software.
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -27,7 +27,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /*
  * Authors:
- *   Keith Whitwell <keith@tungstengraphics.com>
+ *   Keith Whitwell <keithw@vmware.com>
  */
 
 
@@ -41,7 +41,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  * example by building a list that consists of one very long primitive
  * (eg Begin(Triangles), 1000 vertices, End), and calling that list
  * from inside a different begin/end object (Begin(Lines), CallList,
- * End).  
+ * End).
  *
  * In that case the code will have to replay the list as individual
  * commands through the Exec dispatch table, or fix up the copied
@@ -60,7 +60,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  * The list compiler currently doesn't attempt to compile lists
  * containing EvalCoord or EvalPoint commands.  On encountering one of
- * these, compilation falls back to opcodes.  
+ * these, compilation falls back to opcodes.
  *
  * This could be improved to fallback only when a mix of EvalCoord and
  * Vertex commands are issued within a single primitive.
@@ -200,6 +200,8 @@ alloc_vertex_store(struct gl_context *ctx)
                                  GL_ARRAY_BUFFER_ARB,
                                  VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat),
                                  NULL, GL_STATIC_DRAW_ARB,
+                                 GL_MAP_WRITE_BIT |
+                                 GL_DYNAMIC_STORAGE_BIT,
                                  vertex_store->bufferobj);
    }
    else {
@@ -237,16 +239,32 @@ GLfloat *
 vbo_save_map_vertex_store(struct gl_context *ctx,
                           struct vbo_save_vertex_store *vertex_store)
 {
+   const GLbitfield access = (GL_MAP_WRITE_BIT |
+                              GL_MAP_INVALIDATE_RANGE_BIT |
+                              GL_MAP_UNSYNCHRONIZED_BIT |
+                              GL_MAP_FLUSH_EXPLICIT_BIT);
+
    assert(vertex_store->bufferobj);
-   assert(!vertex_store->buffer);
+   assert(!vertex_store->buffer);  /* the buffer should not be mapped */
+
    if (vertex_store->bufferobj->Size > 0) {
-      vertex_store->buffer =
-         (GLfloat *) ctx->Driver.MapBufferRange(ctx, 0,
-                                                vertex_store->bufferobj->Size,
-                                                GL_MAP_WRITE_BIT,  /* not used */
-                                                vertex_store->bufferobj);
-      assert(vertex_store->buffer);
-      return vertex_store->buffer + vertex_store->used;
+      /* Map the remaining free space in the VBO */
+      GLintptr offset = vertex_store->used * sizeof(GLfloat);
+      GLsizeiptr size = vertex_store->bufferobj->Size - offset;
+      GLfloat *range = (GLfloat *)
+         ctx->Driver.MapBufferRange(ctx, offset, size, access,
+                                    vertex_store->bufferobj,
+                                    MAP_INTERNAL);
+      if (range) {
+         /* compute address of start of whole buffer (needed elsewhere) */
+         vertex_store->buffer = range - vertex_store->used;
+         assert(vertex_store->buffer);
+         return range;
+      }
+      else {
+         vertex_store->buffer = NULL;
+         return NULL;
+      }
    }
    else {
       /* probably ran out of memory for buffers */
@@ -260,7 +278,16 @@ vbo_save_unmap_vertex_store(struct gl_context *ctx,
                             struct vbo_save_vertex_store *vertex_store)
 {
    if (vertex_store->bufferobj->Size > 0) {
-      ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj);
+      GLintptr offset = 0;
+      GLsizeiptr length = vertex_store->used * sizeof(GLfloat)
+         - vertex_store->bufferobj->Mappings[MAP_INTERNAL].Offset;
+
+      /* Explicitly flush the region we wrote to */
+      ctx->Driver.FlushMappedBufferRange(ctx, offset, length,
+                                         vertex_store->bufferobj,
+                                         MAP_INTERNAL);
+
+      ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj, MAP_INTERNAL);
    }
    vertex_store->buffer = NULL;
 }
@@ -289,15 +316,15 @@ _save_reset_counters(struct gl_context *ctx)
    assert(save->buffer == save->buffer_ptr);
 
    if (save->vertex_size)
-      save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
-                        save->vertex_size);
+      save->max_vert = (VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
+                        save->vertex_size;
    else
       save->max_vert = 0;
 
    save->vert_count = 0;
    save->prim_count = 0;
    save->prim_max = VBO_SAVE_PRIM_SIZE - save->prim_store->used;
-   save->dangling_attr_ref = 0;
+   save->dangling_attr_ref = GL_FALSE;
 }
 
 /**
@@ -410,7 +437,7 @@ _save_compile_vertex_list(struct gl_context *ctx)
    save->vertex_store->used += save->vertex_size * node->count;
    save->prim_store->used += node->prim_count;
 
-   /* Copy duplicated vertices 
+   /* Copy duplicated vertices
     */
    save->copied.nr = _save_copy_vertices(ctx, node, save->buffer);
 
@@ -508,13 +535,14 @@ _save_wrap_buffers(struct gl_context *ctx)
    save->prim[0].count = 0;
    save->prim[0].num_instances = 1;
    save->prim[0].base_instance = 0;
+   save->prim[0].is_indirect = 0;
    save->prim_count = 1;
 }
 
 
 /**
  * Called only when buffers are wrapped as the result of filling the
- * vertex_store struct.  
+ * vertex_store struct.
  */
 static void
 _save_wrap_filled_vertex(struct gl_context *ctx)
@@ -603,7 +631,7 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
 
    /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
     * when the attribute already exists in the vertex and is having
-    * its size increased.  
+    * its size increased.
     */
    _save_copy_to_current(ctx);
 
@@ -856,7 +884,7 @@ dlist_fallback(struct gl_context *ctx)
        * unfortunately, otherwise this primitive won't be handled
        * properly:
        */
-      save->dangling_attr_ref = 1;
+      save->dangling_attr_ref = GL_TRUE;
 
       _save_compile_vertex_list(ctx);
    }
@@ -963,6 +991,7 @@ vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
    save->prim[i].count = 0;
    save->prim[i].num_instances = 1;
    save->prim[i].base_instance = 0;
+   save->prim[i].is_indirect = 0;
 
    if (save->out_of_memory) {
       _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
@@ -1091,6 +1120,7 @@ _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
 {
    GET_CURRENT_CONTEXT(ctx);
    struct vbo_save_context *save = &vbo_context(ctx)->save;
+   struct gl_buffer_object *indexbuf = ctx->Array.VAO->IndexBufferObj;
    GLint i;
 
    if (!_mesa_is_valid_prim_mode(ctx, mode)) {
@@ -1113,9 +1143,9 @@ _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
 
    _ae_map_vbos(ctx);
 
-   if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj))
+   if (_mesa_is_bufferobj(indexbuf))
       indices =
-         ADD_POINTERS(ctx->Array.ArrayObj->ElementArrayBufferObj->Pointer, indices);
+         ADD_POINTERS(indexbuf->Mappings[MAP_INTERNAL].Pointer, indices);
 
    vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK |
                               VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
@@ -1182,7 +1212,7 @@ _save_OBE_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
 
 static void GLAPIENTRY
 _save_OBE_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
-                            const GLvoid **indices, GLsizei primcount)
+                            const GLvoid * const *indices, GLsizei primcount)
 {
    GLsizei i;
 
@@ -1433,13 +1463,13 @@ vbo_save_EndList(struct gl_context *ctx)
          GLint i = save->prim_count - 1;
          ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
          save->prim[i].end = 0;
-         save->prim[i].count = (save->vert_count - save->prim[i].start);
+         save->prim[i].count = save->vert_count - save->prim[i].start;
       }
 
       /* Make sure this vertex list gets replayed by the "loopback"
        * mechanism:
        */
-      save->dangling_attr_ref = 1;
+      save->dangling_attr_ref = GL_TRUE;
       vbo_save_SaveFlushVertices(ctx);
 
       /* Swap out this vertex format while outside begin/end.  Any color,