diff options
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_save_api.c | 8 | ||||
| -rw-r--r-- | src/mesa/main/api_arrayelt.c | 95 | ||||
| -rw-r--r-- | src/mesa/main/api_arrayelt.h | 5 | ||||
| -rw-r--r-- | src/mesa/tnl/t_save_api.c | 8 | 
4 files changed, 110 insertions, 6 deletions
| diff --git a/src/mesa/drivers/dri/i965/brw_save_api.c b/src/mesa/drivers/dri/i965/brw_save_api.c index 9c0e4af48a..b2f255d095 100644 --- a/src/mesa/drivers/dri/i965/brw_save_api.c +++ b/src/mesa/drivers/dri/i965/brw_save_api.c @@ -855,10 +855,14 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei co     if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))        return; +   _ae_map_vbos( ctx ); +     brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK );     for (i = 0; i < count; i++)         CALL_ArrayElement(GET_DISPATCH(), (start + i));     CALL_End(GET_DISPATCH(), ()); + +   _ae_unmap_vbos( ctx );  }  /* Could do better by copying the arrays and element list intact and @@ -873,6 +877,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum     if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))        return; +   _ae_map_vbos( ctx ); +     brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK );     switch (type) { @@ -894,6 +900,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum     }     CALL_End(GET_DISPATCH(), ()); + +   _ae_unmap_vbos( ctx );  }  static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c index dda659bbc3..3c26c2c590 100644 --- a/src/mesa/main/api_arrayelt.c +++ b/src/mesa/main/api_arrayelt.c @@ -53,6 +53,11 @@ typedef struct {     AEarray arrays[32];     AEattrib attribs[VERT_ATTRIB_MAX + 1];     GLuint NewState; + +   struct gl_buffer_object *vbo[VERT_ATTRIB_MAX]; +   GLuint nr_vbos; +   GLboolean mapped_vbos; +  } AEcontext;  #define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context) @@ -1063,6 +1068,18 @@ void _ae_destroy_context( GLcontext *ctx )     }  } +static void check_vbo( AEcontext *actx, +		       struct gl_buffer_object *vbo ) +{ +   if (vbo->Name && !vbo->Pointer) { +      GLuint i; +      for (i = 0; i < actx->nr_vbos; i++) +	 if (actx->vbo[i] == vbo) +	    return; +      actx->vbo[actx->nr_vbos++] = vbo; +   } +} +  /**   * Make a list of per-vertex functions to call for each glArrayElement call. @@ -1081,31 +1098,37 @@ static void _ae_update_state( GLcontext *ctx )    if (ctx->Array.ArrayObj->Index.Enabled) {        aa->array = &ctx->Array.ArrayObj->Index;        aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)]; +      check_vbo(actx, aa->array->BufferObj);        aa++;     }     if (ctx->Array.ArrayObj->EdgeFlag.Enabled) {        aa->array = &ctx->Array.ArrayObj->EdgeFlag;        aa->offset = _gloffset_EdgeFlagv; +      check_vbo(actx, aa->array->BufferObj);        aa++;     }     if (ctx->Array.ArrayObj->Normal.Enabled) {        aa->array = &ctx->Array.ArrayObj->Normal;        aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)]; +      check_vbo(actx, aa->array->BufferObj);        aa++;     }     if (ctx->Array.ArrayObj->Color.Enabled) {        aa->array = &ctx->Array.ArrayObj->Color;        aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)]; +      check_vbo(actx, aa->array->BufferObj);        aa++;     }     if (ctx->Array.ArrayObj->SecondaryColor.Enabled) {        aa->array = &ctx->Array.ArrayObj->SecondaryColor;        aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)]; +      check_vbo(actx, aa->array->BufferObj);        aa++;     }     if (ctx->Array.ArrayObj->FogCoord.Enabled) {        aa->array = &ctx->Array.ArrayObj->FogCoord;        aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)]; +      check_vbo(actx, aa->array->BufferObj);        aa++;     }     for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { @@ -1120,11 +1143,12 @@ static void _ae_update_state( GLcontext *ctx )                                   [at->array->Size-1]                                   [TYPE_IDX(at->array->Type)];           at->index = VERT_ATTRIB_TEX0 + i; +	 check_vbo(actx, aa->array->BufferObj);           at++;        }     } -   /* generic vertex attribute arrays */ +   /* generic vertex attribute arrays */        for (i = 1; i < VERT_ATTRIB_MAX; i++) {  /* skip zero! */        struct gl_client_array *attribArray = &ctx->Array.ArrayObj->VertexAttrib[i];        if (attribArray->Enabled) { @@ -1146,6 +1170,7 @@ static void _ae_update_state( GLcontext *ctx )                                       [TYPE_IDX(at->array->Type)];           }           at->index = i; +	 check_vbo(actx, aa->array->BufferObj);           at++;        }     } @@ -1158,14 +1183,18 @@ static void _ae_update_state( GLcontext *ctx )        aa->array = &ctx->Array.ArrayObj->VertexAttrib[0];        assert(aa->array->Size >= 2); /* XXX fix someday? */        aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)]; +      check_vbo(actx, aa->array->BufferObj);        aa++;     }     else if (ctx->Array.ArrayObj->Vertex.Enabled) {        aa->array = &ctx->Array.ArrayObj->Vertex;        aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)]; +      check_vbo(actx, aa->array->BufferObj);        aa++;     } +   check_vbo(actx, ctx->Array.ElementArrayBufferObj); +     ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);     ASSERT(aa - actx->arrays < 32);     at->func = NULL;  /* terminate the list */ @@ -1174,6 +1203,45 @@ static void _ae_update_state( GLcontext *ctx )     actx->NewState = 0;  } +void _ae_map_vbos( GLcontext *ctx ) +{ +   AEcontext *actx = AE_CONTEXT(ctx); +   GLuint i; +    +   if (actx->mapped_vbos) +      return; + +   if (actx->NewState) +      _ae_update_state(ctx); + +   for (i = 0; i < actx->nr_vbos; i++) +      ctx->Driver.MapBuffer(ctx, +			    GL_ARRAY_BUFFER_ARB, +			    GL_DYNAMIC_DRAW_ARB, +			    actx->vbo[i]); + +   actx->mapped_vbos = GL_TRUE; +} + +void _ae_unmap_vbos( GLcontext *ctx ) +{ +   AEcontext *actx = AE_CONTEXT(ctx); +   GLuint i; + +   if (actx->mapped_vbos) +      return; + +   if (actx->NewState) +      _ae_update_state(ctx); + +   for (i = 0; i < actx->nr_vbos; i++) +      ctx->Driver.UnmapBuffer(ctx, +			      GL_ARRAY_BUFFER_ARB, +			      actx->vbo[i]); + +   actx->mapped_vbos = GL_TRUE; +} +  /**   * Called via glArrayElement() and glDrawArrays(). @@ -1188,15 +1256,24 @@ void GLAPIENTRY _ae_loopback_array_elt( GLint elt )     const AEarray *aa;     const AEattrib *at;     const struct _glapi_table * const disp = GET_DISPATCH(); +   GLboolean do_map; - -   if (actx->NewState) +   if (actx->NewState) { +      assert(!actx->mapped_vbos);        _ae_update_state( ctx ); +   } +   do_map = actx->nr_vbos && !actx->mapped_vbos; + +   /*  +    */ +   if (do_map) +      _ae_map_vbos(ctx); +        /* generic attributes */     for (at = actx->attribs; at->func; at++) {        const GLubyte *src -         = ADD_POINTERS(at->array->BufferObj->Data, at->array->Ptr) +         = ADD_POINTERS(at->array->BufferObj->Pointer, at->array->Ptr)           + elt * at->array->StrideB;        at->func( at->index, src );     } @@ -1204,15 +1281,21 @@ void GLAPIENTRY _ae_loopback_array_elt( GLint elt )     /* conventional arrays */     for (aa = actx->arrays; aa->offset != -1 ; aa++) {        const GLubyte *src -         = ADD_POINTERS(aa->array->BufferObj->Data, aa->array->Ptr) +         = ADD_POINTERS(aa->array->BufferObj->Pointer, aa->array->Ptr)           + elt * aa->array->StrideB;        CALL_by_offset( disp, (array_func), aa->offset,   		      ((const void *) src) );     } + +   if (do_map) +      _ae_unmap_vbos(ctx);  }  void _ae_invalidate_state( GLcontext *ctx, GLuint new_state )  { -   AE_CONTEXT(ctx)->NewState |= new_state; +   AEcontext *actx = AE_CONTEXT(ctx); + +   assert(!actx->mapped_vbos); +   actx->NewState |= new_state;  } diff --git a/src/mesa/main/api_arrayelt.h b/src/mesa/main/api_arrayelt.h index 1c0af9f3ea..e621724fb2 100644 --- a/src/mesa/main/api_arrayelt.h +++ b/src/mesa/main/api_arrayelt.h @@ -34,4 +34,9 @@ extern void _ae_destroy_context( GLcontext *ctx );  extern void _ae_invalidate_state( GLcontext *ctx, GLuint new_state );  extern void GLAPIENTRY _ae_loopback_array_elt( GLint elt ); +/* May optionally be called before a batch of element calls: + */ +extern void _ae_map_vbos( GLcontext *ctx ); +extern void _ae_unmap_vbos( GLcontext *ctx ); +  #endif diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c index 11d21301d9..dbbd095fe4 100644 --- a/src/mesa/tnl/t_save_api.c +++ b/src/mesa/tnl/t_save_api.c @@ -1413,10 +1413,14 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei co     if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))        return; +   _ae_map_vbos( ctx ); +     _save_NotifyBegin( ctx, mode | PRIM_WEAK );     for (i = 0; i < count; i++)         CALL_ArrayElement(GET_DISPATCH(), (start + i));     CALL_End(GET_DISPATCH(), ()); + +   _ae_unmap_vbos( ctx );  } @@ -1429,6 +1433,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum     if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))        return; +   _ae_map_vbos( ctx ); +     _save_NotifyBegin( ctx, mode | PRIM_WEAK );     switch (type) { @@ -1450,6 +1456,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum     }     CALL_End(GET_DISPATCH(), ()); + +   _ae_unmap_vbos( ctx );  }  static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, | 
