diff options
Diffstat (limited to 'mesalib/src/mesa/vbo/vbo_save_api.c')
-rw-r--r-- | mesalib/src/mesa/vbo/vbo_save_api.c | 171 |
1 files changed, 141 insertions, 30 deletions
diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c index 87a52e81f..64da7ac49 100644 --- a/mesalib/src/mesa/vbo/vbo_save_api.c +++ b/mesalib/src/mesa/vbo/vbo_save_api.c @@ -75,13 +75,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #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" #include "main/vtxfmt.h" #include "main/dispatch.h" #include "vbo_context.h" +#include "vbo_noop.h" #if FEATURE_dlist @@ -185,6 +185,7 @@ _save_copy_vertices(struct gl_context *ctx, static struct vbo_save_vertex_store * alloc_vertex_store(struct gl_context *ctx) { + struct vbo_save_context *save = &vbo_context(ctx)->save; struct vbo_save_vertex_store *vertex_store = CALLOC_STRUCT(vbo_save_vertex_store); @@ -197,11 +198,22 @@ alloc_vertex_store(struct gl_context *ctx) vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx, VBO_BUF_ID, GL_ARRAY_BUFFER_ARB); + if (vertex_store->bufferobj) { + save->out_of_memory = + !ctx->Driver.BufferData(ctx, + GL_ARRAY_BUFFER_ARB, + VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat), + NULL, GL_STATIC_DRAW_ARB, + vertex_store->bufferobj); + } + else { + save->out_of_memory = GL_TRUE; + } - ctx->Driver.BufferData(ctx, - GL_ARRAY_BUFFER_ARB, - VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat), - NULL, GL_STATIC_DRAW_ARB, vertex_store->bufferobj); + if (save->out_of_memory) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "internal VBO allocation"); + _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop); + } vertex_store->buffer = NULL; vertex_store->used = 0; @@ -231,14 +243,19 @@ map_vertex_store(struct gl_context *ctx, { assert(vertex_store->bufferobj); assert(!vertex_store->buffer); - 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; + 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; + } + else { + /* probably ran out of memory for buffers */ + return NULL; + } } @@ -246,7 +263,9 @@ static void unmap_vertex_store(struct gl_context *ctx, struct vbo_save_vertex_store *vertex_store) { - ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj); + if (vertex_store->bufferobj->Size > 0) { + ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj); + } vertex_store->buffer = NULL; } @@ -400,6 +419,7 @@ _save_compile_vertex_list(struct gl_context *ctx) */ save->vertex_store = alloc_vertex_store(ctx); save->buffer_ptr = map_vertex_store(ctx, save->vertex_store); + save->out_of_memory = save->buffer_ptr == NULL; } if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) { @@ -733,7 +753,12 @@ dlist_fallback(struct gl_context *ctx) _save_copy_to_current(ctx); _save_reset_vertex(ctx); _save_reset_counters(ctx); - _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); + if (save->out_of_memory) { + _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop); + } + else { + _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); + } ctx->Driver.SaveNeedFlush = 0; } @@ -826,7 +851,12 @@ vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode) save->prim[i].count = 0; save->prim[i].num_instances = 1; - _mesa_install_save_vtxfmt(ctx, &save->vtxfmt); + if (save->out_of_memory) { + _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop); + } + else { + _mesa_install_save_vtxfmt(ctx, &save->vtxfmt); + } ctx->Driver.SaveNeedFlush = 1; return GL_TRUE; } @@ -852,7 +882,12 @@ _save_End(void) * etc. received between here and the next begin will be compiled * as opcodes. */ - _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); + if (save->out_of_memory) { + _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop); + } + else { + _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); + } } @@ -933,6 +968,37 @@ _save_DrawArrays(GLenum mode, GLint start, GLsizei count) static void GLAPIENTRY +_save_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, + const GLvoid **indices, GLsizei primcount) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; + (void) count; + (void) type; + (void) indices; + (void) primcount; + _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glMultiDrawElements"); +} + + +static void GLAPIENTRY +_save_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, + GLenum type, const GLvoid **indices, + GLsizei primcount, const GLint *basevertex) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; + (void) count; + (void) type; + (void) indices; + (void) primcount; + (void) basevertex; + _mesa_compile_error(ctx, GL_INVALID_OPERATION, + "glMultiDrawElementsBaseVertex"); +} + + +static void GLAPIENTRY _save_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { GET_CURRENT_CONTEXT(ctx); @@ -993,6 +1059,7 @@ _save_PrimitiveRestartNV(void) /* 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. + * Note: OBE = Outside Begin/End */ static void GLAPIENTRY _save_OBE_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) @@ -1011,11 +1078,15 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count) { GET_CURRENT_CONTEXT(ctx); + struct vbo_save_context *save = &vbo_context(ctx)->save; GLint i; if (!_mesa_validate_DrawArrays(ctx, mode, start, count)) return; + if (save->out_of_memory) + return; + _ae_map_vbos(ctx); vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK @@ -1037,11 +1108,15 @@ _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { GET_CURRENT_CONTEXT(ctx); + struct vbo_save_context *save = &vbo_context(ctx)->save; GLint i; if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices, 0)) return; + if (save->out_of_memory) + return; + _ae_map_vbos(ctx); if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) @@ -1081,9 +1156,48 @@ _save_OBE_DrawRangeElements(GLenum mode, GLuint start, GLuint end, const GLvoid * indices) { GET_CURRENT_CONTEXT(ctx); - if (_mesa_validate_DrawRangeElements(ctx, mode, - start, end, count, type, indices, 0)) { - _save_OBE_DrawElements(mode, count, type, indices); + struct vbo_save_context *save = &vbo_context(ctx)->save; + + if (!_mesa_validate_DrawRangeElements(ctx, mode, + start, end, count, type, indices, 0)) + return; + + if (save->out_of_memory) + return; + + _save_OBE_DrawElements(mode, count, type, indices); +} + + +static void GLAPIENTRY +_save_OBE_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, + const GLvoid **indices, GLsizei primcount) +{ + GLsizei i; + + for (i = 0; i < primcount; i++) { + if (count[i] > 0) { + CALL_DrawElements(GET_DISPATCH(), (mode, count[i], type, indices[i])); + } + } +} + + +static void GLAPIENTRY +_save_OBE_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, + GLenum type, + const GLvoid **indices, + GLsizei primcount, + const GLint *basevertex) +{ + GLsizei i; + + for (i = 0; i < primcount; i++) { + if (count[i] > 0) { + CALL_DrawElementsBaseVertex(GET_DISPATCH(), (mode, count[i], type, + indices[i], + basevertex[i])); + } } } @@ -1223,8 +1337,8 @@ _save_vtxfmt_init(struct gl_context *ctx) _MESA_INIT_EVAL_VTXFMT(vfmt, _save_); - /* These are all errors as we at least know we are in some sort of - * begin/end pair: + /* These calls all generate GL_INVALID_OPERATION since this vtxfmt is + * only used when we're inside a glBegin/End pair. */ vfmt->Begin = _save_Begin; vfmt->Rectf = _save_Rectf; @@ -1233,9 +1347,8 @@ _save_vtxfmt_init(struct gl_context *ctx) vfmt->DrawRangeElements = _save_DrawRangeElements; vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex; vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex; - /* Loops back into vfmt->DrawElements */ - vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements; - vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex; + vfmt->MultiDrawElementsEXT = _save_MultiDrawElements; + vfmt->MultiDrawElementsBaseVertex = _save_MultiDrawElementsBaseVertex; } @@ -1424,6 +1537,7 @@ vbo_save_api_init(struct vbo_save_context *save) _save_vtxfmt_init(ctx); _save_current_init(ctx); + _mesa_noop_vtxfmt_init(&save->vtxfmt_noop); /* These will actually get set again when binding/drawing */ for (i = 0; i < VBO_ATTRIB_MAX; i++) @@ -1436,11 +1550,8 @@ vbo_save_api_init(struct vbo_save_context *save) ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; - /* loops back into _save_OBE_DrawElements */ - ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = - _mesa_noop_MultiDrawElements; - ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = - _mesa_noop_MultiDrawElementsBaseVertex; + ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = _save_OBE_MultiDrawElements; + ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = _save_OBE_MultiDrawElementsBaseVertex; _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); } |