static void _save_reset_vertex( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint i; save_init_0( tnl ); save_init_1( tnl ); save_init_2( tnl ); save_init_3( tnl ); save_init_4( tnl ); save_init_5( tnl ); save_init_6( tnl ); save_init_7( tnl ); save_init_8( tnl ); save_init_9( tnl ); save_init_10( tnl ); save_init_11( tnl ); save_init_12( tnl ); save_init_13( tnl ); save_init_14( tnl ); save_init_15( tnl ); for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) tnl->save.attrsz[i] = 0; tnl->save.vertex_size = 0; tnl->save.have_materials = 0; _save_reset_counters( ctx ); }
/* Cope with EvalCoord/CallList called within a begin/end object: * -- Flush current buffer * -- Fallback to opcodes for the rest of the begin/end object. */ static void DO_FALLBACK( struct gl_context *ctx ) { struct vbo_save_context *save = &vbo_context(ctx)->save; if (save->vert_count || save->prim_count) { if (save->prim_count > 0) { /* Close off in-progress primitive. */ GLint i = save->prim_count - 1; save->prim[i].count = save->vert_count - save->prim[i].start; } /* Need to replay this display list with loopback, * unfortunately, otherwise this primitive won't be handled * properly: */ save->dangling_attr_ref = 1; _save_compile_vertex_list( ctx ); } _save_copy_to_current( ctx ); _save_reset_vertex( ctx ); _save_reset_counters( ctx ); _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); ctx->Driver.SaveNeedFlush = 0; }
void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ) { struct vbo_save_context *save = &vbo_context(ctx)->save; (void) list; (void) mode; if (!save->prim_store) save->prim_store = alloc_prim_store( ctx ); if (!save->vertex_store) save->vertex_store = alloc_vertex_store( ctx ); save->vbptr = map_vertex_store( ctx, save->vertex_store ); _save_reset_vertex( ctx ); _save_reset_counters( ctx ); ctx->Driver.SaveNeedFlush = 0; }
void vbo_save_SaveFlushVertices(struct gl_context *ctx) { struct vbo_save_context *save = &vbo_context(ctx)->save; /* Noop when we are actually active: */ if (ctx->Driver.CurrentSavePrimitive <= PRIM_MAX) return; if (save->vert_count || save->prim_count) _save_compile_vertex_list(ctx); _save_copy_to_current(ctx); _save_reset_vertex(ctx); _save_reset_counters(ctx); ctx->Driver.SaveNeedFlush = GL_FALSE; }
void vbo_save_SaveFlushVertices( GLcontext *ctx ) { struct vbo_save_context *save = &vbo_context(ctx)->save; /* Noop when we are actually active: */ if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) return; if (save->vert_count || save->prim_count) _save_compile_vertex_list( ctx ); _save_copy_to_current( ctx ); _save_reset_vertex( ctx ); _save_reset_counters( ctx ); ctx->Driver.SaveNeedFlush = 0; }
/* Insert the active immediate struct onto the display list currently * being built. */ static void _save_compile_vertex_list( GLcontext *ctx ) { struct vbo_save_context *save = &vbo_context(ctx)->save; struct vbo_save_vertex_list *node; /* Allocate space for this structure in the display list currently * being compiled. */ node = (struct vbo_save_vertex_list *) _mesa_alloc_instruction(ctx, save->opcode_vertex_list, sizeof(*node)); if (!node) return; /* Duplicate our template, increment refcounts to the storage structs: */ _mesa_memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); node->vertex_size = save->vertex_size; node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat); node->count = save->vert_count; node->wrap_count = save->copied.nr; node->dangling_attr_ref = save->dangling_attr_ref; node->prim = save->prim; node->prim_count = save->prim_count; node->vertex_store = save->vertex_store; node->prim_store = save->prim_store; node->vertex_store->refcount++; node->prim_store->refcount++; assert(node->attrsz[VBO_ATTRIB_POS] != 0 || node->count == 0); if (save->dangling_attr_ref) ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS; save->vertex_store->used += save->vertex_size * node->count; save->prim_store->used += node->prim_count; /* Copy duplicated vertices */ save->copied.nr = _save_copy_vertices( ctx, node, save->buffer ); /* Deal with GL_COMPILE_AND_EXECUTE: */ if (ctx->ExecuteFlag) { struct _glapi_table *dispatch = GET_DISPATCH(); _glapi_set_dispatch(ctx->Exec); vbo_loopback_vertex_list( ctx, (const GLfloat *)((const char *)save->vertex_store->buffer + node->buffer_offset), node->attrsz, node->prim, node->prim_count, node->wrap_count, node->vertex_size); _glapi_set_dispatch(dispatch); } /* Decide whether the storage structs are full, or can be used for * the next vertex lists as well. */ if (save->vertex_store->used > VBO_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) { /* Unmap old store: */ unmap_vertex_store( ctx, save->vertex_store ); /* Release old reference: */ save->vertex_store->refcount--; assert(save->vertex_store->refcount != 0); save->vertex_store = NULL; /* Allocate and map new store: */ save->vertex_store = alloc_vertex_store( ctx ); save->vbptr = map_vertex_store( ctx, save->vertex_store ); } if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) { save->prim_store->refcount--; assert(save->prim_store->refcount != 0); save->prim_store = alloc_prim_store( ctx ); } /* Reset our structures for the next run of vertices: */ _save_reset_counters( ctx ); }
/* Insert the active immediate struct onto the display list currently * being built. */ static void _save_compile_vertex_list( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct tnl_vertex_list *node; /* Allocate space for this structure in the display list currently * being compiled. */ node = (struct tnl_vertex_list *) _mesa_alloc_instruction(ctx, tnl->save.opcode_vertex_list, sizeof(*node)); if (!node) return; /* Duplicate our template, increment refcounts to the storage structs: */ _mesa_memcpy(node->attrsz, tnl->save.attrsz, sizeof(node->attrsz)); node->vertex_size = tnl->save.vertex_size; node->buffer = tnl->save.buffer; node->wrap_count = tnl->save.copied.nr; node->count = tnl->save.initial_counter - tnl->save.counter; node->prim = tnl->save.prim; node->prim_count = tnl->save.prim_count; node->vertex_store = tnl->save.vertex_store; node->prim_store = tnl->save.prim_store; node->dangling_attr_ref = tnl->save.dangling_attr_ref; node->normal_lengths = 0; node->vertex_store->refcount++; node->prim_store->refcount++; assert(node->attrsz[_TNL_ATTRIB_POS] != 0 || node->count == 0); /* Maybe calculate normal lengths: */ if (tnl->CalcDListNormalLengths && node->attrsz[_TNL_ATTRIB_NORMAL] == 3 && !node->dangling_attr_ref) build_normal_lengths( node ); tnl->save.vertex_store->used += tnl->save.vertex_size * node->count; tnl->save.prim_store->used += node->prim_count; /* Decide whether the storage structs are full, or can be used for * the next vertex lists as well. */ if (tnl->save.vertex_store->used > SAVE_BUFFER_SIZE - 16 * (tnl->save.vertex_size + 4)) { tnl->save.vertex_store->refcount--; assert(tnl->save.vertex_store->refcount != 0); tnl->save.vertex_store = alloc_vertex_store( ctx ); tnl->save.vbptr = tnl->save.vertex_store->buffer; } if (tnl->save.prim_store->used > SAVE_PRIM_SIZE - 6) { tnl->save.prim_store->refcount--; assert(tnl->save.prim_store->refcount != 0); tnl->save.prim_store = alloc_prim_store( ctx ); } /* Reset our structures for the next run of vertices: */ _save_reset_counters( ctx ); /* Copy duplicated vertices */ tnl->save.copied.nr = _save_copy_vertices( ctx, node ); /* Deal with GL_COMPILE_AND_EXECUTE: */ if (ctx->ExecuteFlag) { _tnl_playback_vertex_list( ctx, (void *) node ); } }
/** * Insert the active immediate struct onto the display list currently * being built. */ 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; /* Allocate space for this structure in the display list currently * being compiled. */ node = (struct vbo_save_vertex_list *) _mesa_dlist_alloc(ctx, save->opcode_vertex_list, sizeof(*node)); if (!node) return; /* Duplicate our template, increment refcounts to the storage structs: */ memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); node->vertex_size = save->vertex_size; node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat); node->count = save->vert_count; node->wrap_count = save->copied.nr; node->dangling_attr_ref = save->dangling_attr_ref; node->prim = save->prim; node->prim_count = save->prim_count; node->vertex_store = save->vertex_store; node->prim_store = save->prim_store; node->vertex_store->refcount++; node->prim_store->refcount++; 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)); } } } assert(node->attrsz[VBO_ATTRIB_POS] != 0 || node->count == 0); if (save->dangling_attr_ref) ctx->ListState.CurrentList->Flags |= DLIST_DANGLING_REFS; save->vertex_store->used += save->vertex_size * node->count; save->prim_store->used += node->prim_count; /* Copy duplicated vertices */ save->copied.nr = _save_copy_vertices(ctx, node, save->buffer); /* Deal with GL_COMPILE_AND_EXECUTE: */ if (ctx->ExecuteFlag) { struct _glapi_table *dispatch = GET_DISPATCH(); _glapi_set_dispatch(ctx->Exec); vbo_loopback_vertex_list(ctx, (const GLfloat *) ((const char *) save-> vertex_store->buffer + node->buffer_offset), node->attrsz, node->prim, node->prim_count, node->wrap_count, node->vertex_size); _glapi_set_dispatch(dispatch); } /* Decide whether the storage structs are full, or can be used for * the next vertex lists as well. */ if (save->vertex_store->used > VBO_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) { /* Unmap old store: */ vbo_save_unmap_vertex_store(ctx, save->vertex_store); /* Release old reference: */ save->vertex_store->refcount--; assert(save->vertex_store->refcount != 0); save->vertex_store = NULL; /* Allocate and map new store: */ save->vertex_store = alloc_vertex_store(ctx); save->buffer_ptr = vbo_save_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) { save->prim_store->refcount--; assert(save->prim_store->refcount != 0); save->prim_store = alloc_prim_store(ctx); } /* Reset our structures for the next run of vertices: */ _save_reset_counters(ctx); }