st/mesa: refactor guess_and_alloc_texture() code
[mesa.git] / src / mesa / vbo / vbo_save_api.c
index a5d027982f4fea001abfdae00cb5f389bfbba551..c8199544526d7264aac2b482f04ccd70738237e1 100644 (file)
@@ -74,6 +74,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/enums.h"
 #include "main/eval.h"
 #include "main/macros.h"
+#include "main/mfeatures.h"
 #include "main/api_noop.h"
 #include "main/api_validate.h"
 #include "main/api_arrayelt.h"
@@ -83,6 +84,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "vbo_context.h"
 
 
+#if FEATURE_dlist
+
+
 #ifdef ERROR
 #undef ERROR
 #endif
@@ -96,7 +100,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  * NOTE: Old 'parity' issue is gone, but copying can still be
  * wrong-footed on replay.
  */
-static GLuint _save_copy_vertices( GLcontext *ctx, 
+static GLuint _save_copy_vertices( struct gl_context *ctx, 
                                   const struct vbo_save_vertex_list *node,
                                   const GLfloat *src_buffer)
 {
@@ -167,7 +171,7 @@ static GLuint _save_copy_vertices( GLcontext *ctx,
 }
 
 
-static struct vbo_save_vertex_store *alloc_vertex_store( GLcontext *ctx )
+static struct vbo_save_vertex_store *alloc_vertex_store( struct gl_context *ctx )
 {
    struct vbo_save_vertex_store *vertex_store = CALLOC_STRUCT(vbo_save_vertex_store);
 
@@ -195,7 +199,7 @@ static struct vbo_save_vertex_store *alloc_vertex_store( GLcontext *ctx )
    return vertex_store;
 }
 
-static void free_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store )
+static void free_vertex_store( struct gl_context *ctx, struct vbo_save_vertex_store *vertex_store )
 {
    assert(!vertex_store->buffer);
 
@@ -206,7 +210,7 @@ static void free_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *ver
    FREE( vertex_store );
 }
 
-static GLfloat *map_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store )
+static GLfloat *map_vertex_store( struct gl_context *ctx, struct vbo_save_vertex_store *vertex_store )
 {
    assert(vertex_store->bufferobj);
    assert(!vertex_store->buffer);
@@ -219,14 +223,14 @@ static GLfloat *map_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *
    return vertex_store->buffer + vertex_store->used;
 }
 
-static void unmap_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store )
+static void unmap_vertex_store( struct gl_context *ctx, struct vbo_save_vertex_store *vertex_store )
 {
    ctx->Driver.UnmapBuffer( ctx, GL_ARRAY_BUFFER_ARB, vertex_store->bufferobj );
    vertex_store->buffer = NULL;
 }
 
 
-static struct vbo_save_primitive_store *alloc_prim_store( GLcontext *ctx )
+static struct vbo_save_primitive_store *alloc_prim_store( struct gl_context *ctx )
 {
    struct vbo_save_primitive_store *store = CALLOC_STRUCT(vbo_save_primitive_store);
    (void) ctx;
@@ -235,7 +239,7 @@ static struct vbo_save_primitive_store *alloc_prim_store( GLcontext *ctx )
    return store;
 }
 
-static void _save_reset_counters( GLcontext *ctx )
+static void _save_reset_counters( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
 
@@ -261,7 +265,7 @@ static void _save_reset_counters( GLcontext *ctx )
 /* Insert the active immediate struct onto the display list currently
  * being built.
  */
-static void _save_compile_vertex_list( GLcontext *ctx )
+static void _save_compile_vertex_list( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    struct vbo_save_vertex_list *node;
@@ -291,26 +295,30 @@ static void _save_compile_vertex_list( GLcontext *ctx )
    node->vertex_store->refcount++;
    node->prim_store->refcount++;
 
-
-   node->current_size = node->vertex_size - node->attrsz[0];
-   node->current_data = NULL;
-
-   if (node->current_size) {
-      /* If the malloc fails, we just pull the data out of the VBO
-       * later instead.
-       */
-      node->current_data = MALLOC( node->current_size * sizeof(GLfloat) );
-      if (node->current_data) {
-         const char *buffer = (const char *)save->vertex_store->buffer;
-         unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
-         unsigned vertex_offset = 0;
-
-         if (node->count)
-            vertex_offset = (node->count-1) * node->vertex_size * sizeof(GLfloat);
-
-         memcpy( node->current_data,
-                 buffer + node->buffer_offset + vertex_offset + attr_offset,
-                 node->current_size * sizeof(GLfloat) );
+   if (node->prim[0].no_current_update) {
+      node->current_size = 0;
+      node->current_data = NULL;
+   } else {
+      node->current_size = node->vertex_size - node->attrsz[0];
+      node->current_data = NULL;
+     
+      if (node->current_size) {
+         /* If the malloc fails, we just pull the data out of the VBO
+          * later instead.
+          */
+         node->current_data = MALLOC( node->current_size * sizeof(GLfloat) );
+         if (node->current_data) {
+            const char *buffer = (const char *)save->vertex_store->buffer;
+            unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
+            unsigned vertex_offset = 0;
+            
+            if (node->count)
+               vertex_offset = (node->count-1) * node->vertex_size * sizeof(GLfloat);
+         
+            memcpy( node->current_data,
+                    buffer + node->buffer_offset + vertex_offset + attr_offset,
+                    node->current_size * sizeof(GLfloat) );
+         }
       }
    }
 
@@ -388,12 +396,13 @@ static void _save_compile_vertex_list( GLcontext *ctx )
 /* TODO -- If no new vertices have been stored, don't bother saving
  * it.
  */
-static void _save_wrap_buffers( GLcontext *ctx )
+static void _save_wrap_buffers( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    GLint i = save->prim_count - 1;
    GLenum mode;
    GLboolean weak;
+   GLboolean no_current_update;
 
    assert(i < (GLint) save->prim_max);
    assert(i >= 0);
@@ -404,6 +413,7 @@ static void _save_wrap_buffers( GLcontext *ctx )
                          save->prim[i].start);
    mode = save->prim[i].mode;
    weak = save->prim[i].weak;
+   no_current_update = save->prim[i].no_current_update;
    
    /* store the copied vertices, and allocate a new list.
     */
@@ -413,11 +423,13 @@ static void _save_wrap_buffers( GLcontext *ctx )
     */
    save->prim[0].mode = mode;
    save->prim[0].weak = weak;
+   save->prim[0].no_current_update = no_current_update;
    save->prim[0].begin = 0;
    save->prim[0].end = 0;
    save->prim[0].pad = 0;
    save->prim[0].start = 0;
    save->prim[0].count = 0;
+   save->prim[0].num_instances = 1;
    save->prim_count = 1;
 }
 
@@ -426,7 +438,7 @@ static void _save_wrap_buffers( GLcontext *ctx )
 /* Called only when buffers are wrapped as the result of filling the
  * vertex_store struct.  
  */
-static void _save_wrap_filled_vertex( GLcontext *ctx )
+static void _save_wrap_filled_vertex( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    GLfloat *data = save->copied.buffer;
@@ -449,7 +461,7 @@ static void _save_wrap_filled_vertex( GLcontext *ctx )
 }
 
 
-static void _save_copy_to_current( GLcontext *ctx )
+static void _save_copy_to_current( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save; 
    GLuint i;
@@ -465,7 +477,7 @@ static void _save_copy_to_current( GLcontext *ctx )
 }
 
 
-static void _save_copy_from_current( GLcontext *ctx )
+static void _save_copy_from_current( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save; 
    GLint i;
@@ -486,7 +498,7 @@ static void _save_copy_from_current( GLcontext *ctx )
 
 /* Flush existing data, set new attrib size, replay copied vertices.
  */ 
-static void _save_upgrade_vertex( GLcontext *ctx, 
+static void _save_upgrade_vertex( struct gl_context *ctx, 
                                 GLuint attr,
                                 GLuint newsz )
 {
@@ -582,7 +594,7 @@ static void _save_upgrade_vertex( GLcontext *ctx,
    }
 }
 
-static void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz )
+static void save_fixup_vertex( struct gl_context *ctx, GLuint attr, GLuint sz )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save; 
 
@@ -606,7 +618,7 @@ static void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz )
    save->active_sz[attr] = sz;
 }
 
-static void _save_reset_vertex( GLcontext *ctx )
+static void _save_reset_vertex( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    GLuint i;
@@ -634,11 +646,11 @@ static void _save_reset_vertex( GLcontext *ctx )
 do {                                                           \
    struct vbo_save_context *save = &vbo_context(ctx)->save;    \
                                                                \
-   if (save->active_sz[A] != N)                                \
+   if (save->active_sz[A] != N)                                        \
       save_fixup_vertex(ctx, A, N);                            \
                                                                \
    {                                                           \
-      GLfloat *dest = save->attrptr[A];                        \
+      GLfloat *dest = save->attrptr[A];                                \
       if (N>0) dest[0] = V0;                                   \
       if (N>1) dest[1] = V1;                                   \
       if (N>2) dest[2] = V2;                                   \
@@ -651,7 +663,7 @@ do {                                                                \
       for (i = 0; i < save->vertex_size; i++)                  \
         save->buffer_ptr[i] = save->vertex[i];                 \
                                                                \
-      save->buffer_ptr += save->vertex_size;                           \
+      save->buffer_ptr += save->vertex_size;                   \
                                                                \
       if (++save->vert_count >= save->max_vert)                        \
         _save_wrap_filled_vertex( ctx );                       \
@@ -669,7 +681,7 @@ do {                                                                \
  *     -- Flush current buffer
  *     -- Fallback to opcodes for the rest of the begin/end object.
  */
-static void DO_FALLBACK( GLcontext *ctx )
+static void DO_FALLBACK( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
 
@@ -701,56 +713,56 @@ static void GLAPIENTRY _save_EvalCoord1f( GLfloat u )
 {
    GET_CURRENT_CONTEXT(ctx);
    DO_FALLBACK(ctx);
-   ctx->Save->EvalCoord1f( u );
+   CALL_EvalCoord1f(ctx->Save, (u));
 }
 
 static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v )
 {
    GET_CURRENT_CONTEXT(ctx);
    DO_FALLBACK(ctx);
-   ctx->Save->EvalCoord1fv( v );
+   CALL_EvalCoord1fv(ctx->Save, (v));
 }
 
 static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v )
 {
    GET_CURRENT_CONTEXT(ctx);
    DO_FALLBACK(ctx);
-   ctx->Save->EvalCoord2f( u, v );
+   CALL_EvalCoord2f(ctx->Save, (u, v));
 }
 
 static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v )
 {
    GET_CURRENT_CONTEXT(ctx);
    DO_FALLBACK(ctx);
-   ctx->Save->EvalCoord2fv( v );
+   CALL_EvalCoord2fv(ctx->Save, (v));
 }
 
 static void GLAPIENTRY _save_EvalPoint1( GLint i )
 {
    GET_CURRENT_CONTEXT(ctx);
    DO_FALLBACK(ctx);
-   ctx->Save->EvalPoint1( i );
+   CALL_EvalPoint1(ctx->Save, (i));
 }
 
 static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j )
 {
    GET_CURRENT_CONTEXT(ctx);
    DO_FALLBACK(ctx);
-   ctx->Save->EvalPoint2( i, j );
+   CALL_EvalPoint2(ctx->Save, (i, j));
 }
 
 static void GLAPIENTRY _save_CallList( GLuint l )
 {
    GET_CURRENT_CONTEXT(ctx);
    DO_FALLBACK(ctx);
-   ctx->Save->CallList( l );
+   CALL_CallList(ctx->Save, (l));
 }
 
 static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v )
 {
    GET_CURRENT_CONTEXT(ctx);
    DO_FALLBACK(ctx);
-   ctx->Save->CallLists( n, type, v );
+   CALL_CallLists(ctx->Save, (n, type, v));
 }
 
 
@@ -759,20 +771,22 @@ static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v
 /* This begin is hooked into ...  Updating of
  * ctx->Driver.CurrentSavePrimitive is already taken care of.
  */
-GLboolean vbo_save_NotifyBegin( GLcontext *ctx, GLenum mode )
+GLboolean vbo_save_NotifyBegin( struct gl_context *ctx, GLenum mode )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save; 
 
    GLuint i = save->prim_count++;
 
    assert(i < save->prim_max);
-   save->prim[i].mode = mode & ~VBO_SAVE_PRIM_WEAK;
+   save->prim[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
    save->prim[i].begin = 1;
    save->prim[i].end = 0;
    save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
+   save->prim[i].no_current_update = (mode & VBO_SAVE_PRIM_NO_CURRENT_UPDATE) ? 1 : 0;
    save->prim[i].pad = 0;
    save->prim[i].start = save->vert_count;
    save->prim[i].count = 0;   
+   save->prim[i].num_instances = 1;   
 
    _mesa_install_save_vtxfmt( ctx, &save->vtxfmt );      
    ctx->Driver.SaveNeedFlush = 1;
@@ -891,6 +905,18 @@ static void GLAPIENTRY _save_Begin( GLenum mode )
 }
 
 
+static void GLAPIENTRY _save_PrimitiveRestartNV( void )
+{
+   GLenum curPrim;
+   GET_CURRENT_CONTEXT( ctx ); 
+
+   curPrim = ctx->Driver.CurrentSavePrimitive;
+
+   _save_End();
+   _save_Begin(curPrim);
+}
+
+
 /* Unlike the functions above, these are to be hooked into the vtxfmt
  * maintained in ctx->ListState, active when the list is known or
  * suspected to be outside any begin/end primitive.
@@ -917,7 +943,7 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei co
 
    _ae_map_vbos( ctx );
 
-   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
+   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK | VBO_SAVE_PRIM_NO_CURRENT_UPDATE);
 
    for (i = 0; i < count; i++)
        CALL_ArrayElement(GET_DISPATCH(), (start + i));
@@ -943,7 +969,7 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
    if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj))
       indices = ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Pointer, indices);
 
-   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
+   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK | VBO_SAVE_PRIM_NO_CURRENT_UPDATE );
 
    switch (type) {
    case GL_UNSIGNED_BYTE:
@@ -984,7 +1010,7 @@ static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,
 
 
 
-static void _save_vtxfmt_init( GLcontext *ctx )
+static void _save_vtxfmt_init( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    GLvertexformat *vfmt = &save->vtxfmt;
@@ -998,6 +1024,7 @@ static void _save_vtxfmt_init( GLcontext *ctx )
    vfmt->Color4fv = _save_Color4fv;
    vfmt->EdgeFlag = _save_EdgeFlag;
    vfmt->End = _save_End;
+   vfmt->PrimitiveRestartNV = _save_PrimitiveRestartNV;
    vfmt->FogCoordfEXT = _save_FogCoordfEXT;
    vfmt->FogCoordfvEXT = _save_FogCoordfvEXT;
    vfmt->Indexf = _save_Indexf;
@@ -1047,6 +1074,24 @@ static void _save_vtxfmt_init( GLcontext *ctx )
    vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV;
    vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV;
    
+   /* integer-valued */
+   vfmt->VertexAttribI1i = _save_VertexAttribI1i;
+   vfmt->VertexAttribI2i = _save_VertexAttribI2i;
+   vfmt->VertexAttribI3i = _save_VertexAttribI3i;
+   vfmt->VertexAttribI4i = _save_VertexAttribI4i;
+   vfmt->VertexAttribI2iv = _save_VertexAttribI2iv;
+   vfmt->VertexAttribI3iv = _save_VertexAttribI3iv;
+   vfmt->VertexAttribI4iv = _save_VertexAttribI4iv;
+
+   /* unsigned integer-valued */
+   vfmt->VertexAttribI1ui = _save_VertexAttribI1ui;
+   vfmt->VertexAttribI2ui = _save_VertexAttribI2ui;
+   vfmt->VertexAttribI3ui = _save_VertexAttribI3ui;
+   vfmt->VertexAttribI4ui = _save_VertexAttribI4ui;
+   vfmt->VertexAttribI2uiv = _save_VertexAttribI2uiv;
+   vfmt->VertexAttribI3uiv = _save_VertexAttribI3uiv;
+   vfmt->VertexAttribI4uiv = _save_VertexAttribI4uiv;
+
    /* This will all require us to fallback to saving the list as opcodes:
     */ 
    _MESA_INIT_DLIST_VTXFMT(vfmt, _save_); /* inside begin/end */
@@ -1069,7 +1114,7 @@ static void _save_vtxfmt_init( GLcontext *ctx )
 }
 
 
-void vbo_save_SaveFlushVertices( GLcontext *ctx )
+void vbo_save_SaveFlushVertices( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
 
@@ -1089,7 +1134,7 @@ void vbo_save_SaveFlushVertices( GLcontext *ctx )
    ctx->Driver.SaveNeedFlush = 0;
 }
 
-void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode )
+void vbo_save_NewList( struct gl_context *ctx, GLuint list, GLenum mode )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
 
@@ -1108,7 +1153,7 @@ void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode )
    ctx->Driver.SaveNeedFlush = 0;
 }
 
-void vbo_save_EndList( GLcontext *ctx )
+void vbo_save_EndList( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
 
@@ -1142,13 +1187,13 @@ void vbo_save_EndList( GLcontext *ctx )
    assert(save->vertex_size == 0);
 }
  
-void vbo_save_BeginCallList( GLcontext *ctx, struct gl_display_list *dlist )
+void vbo_save_BeginCallList( struct gl_context *ctx, struct gl_display_list *dlist )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    save->replay_flags |= dlist->Flags;
 }
 
-void vbo_save_EndCallList( GLcontext *ctx )
+void vbo_save_EndCallList( struct gl_context *ctx )
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    
@@ -1161,7 +1206,7 @@ void vbo_save_EndCallList( GLcontext *ctx )
 }
 
 
-static void vbo_destroy_vertex_list( GLcontext *ctx, void *data )
+static void vbo_destroy_vertex_list( struct gl_context *ctx, void *data )
 {
    struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data;
    (void) ctx;
@@ -1179,7 +1224,7 @@ static void vbo_destroy_vertex_list( GLcontext *ctx, void *data )
 }
 
 
-static void vbo_print_vertex_list( GLcontext *ctx, void *data )
+static void vbo_print_vertex_list( struct gl_context *ctx, void *data )
 {
    struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data;
    GLuint i;
@@ -1204,7 +1249,7 @@ static void vbo_print_vertex_list( GLcontext *ctx, void *data )
 }
 
 
-static void _save_current_init( GLcontext *ctx ) 
+static void _save_current_init( struct gl_context *ctx ) 
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    GLint i;
@@ -1229,7 +1274,7 @@ static void _save_current_init( GLcontext *ctx )
  */
 void vbo_save_api_init( struct vbo_save_context *save )
 {
-   GLcontext *ctx = save->ctx;
+   struct gl_context *ctx = save->ctx;
    GLuint i;
 
    save->opcode_vertex_list =
@@ -1261,3 +1306,5 @@ void vbo_save_api_init( struct vbo_save_context *save )
    _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
 }
 
+
+#endif /* FEATURE_dlist */