static void init_mat_currval(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); struct gl_client_array *arrays = &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT]; GLuint i; ASSERT(NR_MAT_ATTRIBS == MAT_ATTRIB_MAX); memset(arrays, 0, sizeof(*arrays) * NR_MAT_ATTRIBS); /* Set up a constant (StrideB == 0) array for each current * attribute: */ for (i = 0; i < NR_MAT_ATTRIBS; i++) { struct gl_client_array *cl = &arrays[i]; /* Size is fixed for the material attributes, for others will * be determined at runtime: */ switch (i - VERT_ATTRIB_GENERIC0) { case MAT_ATTRIB_FRONT_SHININESS: case MAT_ATTRIB_BACK_SHININESS: cl->Size = 1; break; case MAT_ATTRIB_FRONT_INDEXES: case MAT_ATTRIB_BACK_INDEXES: cl->Size = 3; break; default: cl->Size = 4; break; } cl->Ptr = (const void *)ctx->Light.Material.Attrib[i]; cl->Type = GL_FLOAT; cl->Format = GL_RGBA; cl->Stride = 0; cl->StrideB = 0; cl->Enabled = 1; cl->_ElementSize = cl->Size * sizeof(GLfloat); _mesa_reference_buffer_object(ctx, &cl->BufferObj, ctx->Shared->NullBufferObj); } }
/* Could do better by copying the arrays and element list intact and * then emitting an indexed prim at runtime. */ static void GLAPIENTRY _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.ArrayObj->ElementArrayBufferObj)) indices = ADD_POINTERS(ctx->Array.ArrayObj->ElementArrayBufferObj->Pointer, indices); vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK | VBO_SAVE_PRIM_NO_CURRENT_UPDATE)); switch (type) { case GL_UNSIGNED_BYTE: for (i = 0; i < count; i++) CALL_ArrayElement(GET_DISPATCH(), (((GLubyte *) indices)[i])); break; case GL_UNSIGNED_SHORT: for (i = 0; i < count; i++) CALL_ArrayElement(GET_DISPATCH(), (((GLushort *) indices)[i])); break; case GL_UNSIGNED_INT: for (i = 0; i < count; i++) CALL_ArrayElement(GET_DISPATCH(), (((GLuint *) indices)[i])); break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)"); break; } CALL_End(GET_DISPATCH(), ()); _ae_unmap_vbos(ctx); }
/** * Copy current vertex attribute values into the current vertex. */ static void vbo_exec_copy_from_current(struct vbo_exec_context *exec) { struct gl_context *ctx = exec->ctx; struct vbo_context *vbo = vbo_context(ctx); GLint i; for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) { const GLfloat *current = (GLfloat *) vbo->currval[i].Ptr; switch (exec->vtx.attrsz[i]) { case 4: exec->vtx.attrptr[i][3] = current[3]; case 3: exec->vtx.attrptr[i][2] = current[2]; case 2: exec->vtx.attrptr[i][1] = current[1]; case 1: exec->vtx.attrptr[i][0] = current[0]; break; } } }
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; }
/** * Print info/data for glDrawArrays(), for debugging. */ static void print_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, GLsizei count) { struct vbo_context *vbo = vbo_context(ctx); struct vbo_exec_context *exec = &vbo->exec; struct gl_array_object *arrayObj = ctx->Array.ArrayObj; int i; printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n", mode, start, count); for (i = 0; i < 32; i++) { struct gl_buffer_object *bufObj = exec->array.inputs[i]->BufferObj; GLuint bufName = bufObj->Name; GLint stride = exec->array.inputs[i]->Stride; printf("attr %2d: size %d stride %d enabled %d " "ptr %p Bufobj %u\n", i, exec->array.inputs[i]->Size, stride, /*exec->array.inputs[i]->Enabled,*/ arrayObj->VertexAttrib[VERT_ATTRIB_FF(i)].Enabled, exec->array.inputs[i]->Ptr, bufName); if (bufName) { GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, GL_MAP_READ_BIT, bufObj); int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr; float *f = (float *) (p + offset); int *k = (int *) f; int i; int n = (count * stride) / 4; if (n > 32) n = 32; printf(" Data at offset %d:\n", offset); for (i = 0; i < n; i++) { printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]); } ctx->Driver.UnmapBuffer(ctx, bufObj); } } }
void vbo_exec_vtx_init( struct vbo_exec_context *exec ) { GLcontext *ctx = exec->ctx; struct vbo_context *vbo = vbo_context(ctx); GLuint i; /* Allocate a buffer object. Will just reuse this object * continuously, unless vbo_use_buffer_objects() is called to enable * use of real VBOs. */ _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, ctx->Shared->NullBufferObj); ASSERT(!exec->vtx.buffer_map); exec->vtx.buffer_map = (GLfloat *)ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE, 64); exec->vtx.buffer_ptr = exec->vtx.buffer_map; vbo_exec_vtxfmt_init( exec ); /* Hook our functions into the dispatch table. */ _mesa_install_exec_vtxfmt( exec->ctx, &exec->vtxfmt ); for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { ASSERT(i < Elements(exec->vtx.attrsz)); exec->vtx.attrsz[i] = 0; ASSERT(i < Elements(exec->vtx.active_sz)); exec->vtx.active_sz[i] = 0; } for (i = 0 ; i < VERT_ATTRIB_MAX; i++) { ASSERT(i < Elements(exec->vtx.inputs)); ASSERT(i < Elements(exec->vtx.arrays)); exec->vtx.inputs[i] = &exec->vtx.arrays[i]; } { struct gl_client_array *arrays = exec->vtx.arrays; memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0])); } exec->vtx.vertex_size = 0; }
/** * Fallback for when a driver does not call vbo_set_indirect_draw_func(). */ static void vbo_draw_indirect_prims(struct gl_context *ctx, GLuint mode, struct gl_buffer_object *indirect_buffer, GLsizeiptr indirect_offset, unsigned draw_count, unsigned stride, struct gl_buffer_object *indirect_draw_count_buffer, GLsizeiptr indirect_draw_count_offset, const struct _mesa_index_buffer *ib) { struct vbo_context *vbo = vbo_context(ctx); struct _mesa_prim *prim; GLsizei i; prim = calloc(draw_count, sizeof(*prim)); if (prim == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sDraw%sIndirect%s", (draw_count > 1) ? "Multi" : "", ib ? "Elements" : "Arrays", indirect_buffer ? "CountARB" : ""); return; } prim[0].begin = 1; prim[draw_count - 1].end = 1; for (i = 0; i < draw_count; ++i, indirect_offset += stride) { prim[i].mode = mode; prim[i].indexed = !!ib; prim[i].indirect_offset = indirect_offset; prim[i].is_indirect = 1; prim[i].draw_id = i; } /* This should always be true at this time */ assert(indirect_buffer == ctx->DrawIndirectBuffer); vbo->draw_prims(ctx, prim, draw_count, ib, false, 0, ~0, NULL, 0, indirect_buffer); free(prim); }
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; }
static void init_mat_currval(GLcontext *ctx) { struct vbo_context *vbo = vbo_context(ctx); struct gl_client_array *arrays = vbo->mat_currval; GLuint i; memset(arrays, 0, sizeof(*arrays) * NR_MAT_ATTRIBS); /* Set up a constant (StrideB == 0) array for each current * attribute: */ for (i = 0; i < NR_MAT_ATTRIBS; i++) { struct gl_client_array *cl = &arrays[i]; /* Size is fixed for the material attributes, for others will * be determined at runtime: */ switch (i - VERT_ATTRIB_GENERIC0) { case MAT_ATTRIB_FRONT_SHININESS: case MAT_ATTRIB_BACK_SHININESS: cl->Size = 1; break; case MAT_ATTRIB_FRONT_INDEXES: case MAT_ATTRIB_BACK_INDEXES: cl->Size = 3; break; default: cl->Size = 4; break; } if (i < MAT_ATTRIB_MAX) cl->Ptr = (const void *)ctx->Light.Material.Attrib[i]; else cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]; cl->Type = GL_FLOAT; cl->Stride = 0; cl->StrideB = 0; cl->Enabled = 1; cl->BufferObj = ctx->Array.NullBufferObj; } }
static void _save_current_init( GLcontext *ctx ) { struct vbo_save_context *save = &vbo_context(ctx)->save; GLint i; for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) { const GLuint j = i - VBO_ATTRIB_POS; ASSERT(j < VERT_ATTRIB_MAX); save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j]; save->current[i] = ctx->ListState.CurrentAttrib[j]; } for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) { const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL; ASSERT(j < MAT_ATTRIB_MAX); save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; save->current[i] = ctx->ListState.CurrentMaterial[j]; } }
/* This begin is hooked into ... Updating of * ctx->Driver.CurrentSavePrimitive is already taken care of. */ GLboolean vbo_save_NotifyBegin( GLcontext *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].begin = 1; save->prim[i].end = 0; save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0; save->prim[i].pad = 0; save->prim[i].start = save->vert_count; save->prim[i].count = 0; _mesa_install_save_vtxfmt( ctx, &save->vtxfmt ); ctx->Driver.SaveNeedFlush = 1; return GL_TRUE; }
/* Build a list of primitives on the fly. Keep * ctx->Driver.CurrentExecPrimitive uptodate as well. */ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) { GET_CURRENT_CONTEXT( ctx ); if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; int i; if (ctx->NewState) { _mesa_update_state( ctx ); CALL_Begin(ctx->Exec, (mode)); return; } if (!vbo_validate_shaders(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBegin (invalid vertex/fragment program)"); return; } /* Heuristic: attempt to isolate attributes occuring outside * begin/end pairs. */ if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) vbo_exec_FlushVertices_internal( ctx, GL_FALSE ); i = exec->vtx.prim_count++; exec->vtx.prim[i].mode = mode; exec->vtx.prim[i].begin = 1; exec->vtx.prim[i].end = 0; exec->vtx.prim[i].indexed = 0; exec->vtx.prim[i].weak = 0; exec->vtx.prim[i].pad = 0; exec->vtx.prim[i].start = exec->vtx.vert_count; exec->vtx.prim[i].count = 0; ctx->Driver.CurrentExecPrimitive = mode; } else _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); }
void vbo_exec_invalidate_state(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); struct vbo_exec_context *exec = &vbo->exec; if (ctx->NewState & (_NEW_PROGRAM | _NEW_ARRAY)) { exec->array.recalculate_inputs = GL_TRUE; _ae_invalidate_state(ctx); } /* If _mesa_update_state is called in a non draw code path, * changes in the VAO need to be captured. */ if (ctx->Array.VAO->NewArrays) exec->array.recalculate_inputs = GL_TRUE; if (ctx->NewState & _NEW_EVAL) exec->eval.recalculate_maps = GL_TRUE; }
/** * Called via glEnd. */ static void GLAPIENTRY vbo_exec_End( void ) { GET_CURRENT_CONTEXT( ctx ); if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; int idx = exec->vtx.vert_count; int i = exec->vtx.prim_count - 1; exec->vtx.prim[i].end = 1; exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start; ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; if (exec->vtx.prim_count == VBO_MAX_PRIM) vbo_exec_vtx_flush( exec, GL_FALSE ); } else _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); }
static void _save_copy_from_current(struct gl_context *ctx) { struct vbo_save_context *save = &vbo_context(ctx)->save; GLint i; for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) { switch (save->attrsz[i]) { case 4: save->attrptr[i][3] = save->current[i][3]; case 3: save->attrptr[i][2] = save->current[i][2]; case 2: save->attrptr[i][1] = save->current[i][1]; case 1: save->attrptr[i][0] = save->current[i][0]; case 0: break; } } }
void vbo_exec_init( struct gl_context *ctx ) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; exec->ctx = ctx; /* Initialize the arrayelt helper */ if (!ctx->aelt_context && !_ae_create_context( ctx )) return; vbo_exec_vtx_init( exec ); ctx->Driver.NeedFlush = 0; ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; ctx->Driver.BeginVertices = vbo_exec_BeginVertices; ctx->Driver.FlushVertices = vbo_exec_FlushVertices; vbo_exec_invalidate_state( ctx, ~0 ); }
/* Called only when buffers are wrapped as the result of filling the * vertex_store struct. */ static void _save_wrap_filled_vertex( GLcontext *ctx ) { struct vbo_save_context *save = &vbo_context(ctx)->save; GLfloat *data = save->copied.buffer; GLuint i; /* Emit a glEnd to close off the last vertex list. */ _save_wrap_buffers( ctx ); /* Copy stored stored vertices to start of new list. */ assert(save->max_vert - save->vert_count > save->copied.nr); for (i = 0 ; i < save->copied.nr ; i++) { _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat)); data += save->vertex_size; save->vbptr += save->vertex_size; save->vert_count++; } }
static void _save_reset_counters( GLcontext *ctx ) { struct vbo_save_context *save = &vbo_context(ctx)->save; save->prim = save->prim_store->buffer + save->prim_store->used; save->buffer = (save->vertex_store->buffer + save->vertex_store->used); assert(save->buffer == save->vbptr); if (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; }
static void GLAPIENTRY _save_End( void ) { GET_CURRENT_CONTEXT( ctx ); struct vbo_save_context *save = &vbo_context(ctx)->save; GLint i = save->prim_count - 1; ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; save->prim[i].end = 1; save->prim[i].count = (save->vert_count - save->prim[i].start); if (i == (GLint) save->prim_max - 1) { _save_compile_vertex_list( ctx ); assert(save->copied.nr == 0); } /* Swap out this vertex format while outside begin/end. Any color, * etc. received between here and the next begin will be compiled * as opcodes. */ _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); }
void _vbo_DestroyContext( struct gl_context *ctx ) { struct vbo_context *vbo = vbo_context(ctx); if (ctx->aelt_context) { _ae_destroy_context( ctx ); ctx->aelt_context = NULL; } if (vbo) { GLuint i; for (i = 0; i < VBO_ATTRIB_MAX; i++) { _mesa_reference_buffer_object(ctx, &vbo->currval[i].BufferObj, NULL); } vbo_exec_destroy(ctx); vbo_save_destroy(ctx); FREE(vbo); ctx->swtnl_im = NULL; } }
/** * Called at context creation time. */ void vbo_save_init( struct gl_context *ctx ) { struct vbo_context *vbo = vbo_context(ctx); struct vbo_save_context *save = &vbo->save; save->ctx = ctx; vbo_save_api_init( save ); vbo_save_callback_init(ctx); { struct gl_client_array *arrays = save->arrays; unsigned i; memcpy(arrays, &vbo->currval[VBO_ATTRIB_POS], VERT_ATTRIB_FF_MAX * sizeof(arrays[0])); for (i = 0; i < VERT_ATTRIB_FF_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_FF(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &arrays->BufferObj, vbo->currval[VBO_ATTRIB_POS+i].BufferObj); } memcpy(arrays + VERT_ATTRIB_GENERIC(0), &vbo->currval[VBO_ATTRIB_GENERIC0], VERT_ATTRIB_GENERIC_MAX * sizeof(arrays[0])); for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_GENERIC(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &array->BufferObj, vbo->currval[VBO_ATTRIB_GENERIC0+i].BufferObj); } } ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; }
static void init_generic_currval(GLcontext *ctx) { struct vbo_context *vbo = vbo_context(ctx); struct gl_client_array *arrays = vbo->generic_currval; GLuint i; memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS); for (i = 0; i < NR_GENERIC_ATTRIBS; i++) { struct gl_client_array *cl = &arrays[i]; /* This will have to be determined at runtime: */ cl->Size = 1; cl->Type = GL_FLOAT; cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]; cl->Stride = 0; cl->StrideB = 0; cl->Enabled = 1; cl->BufferObj = ctx->Array.NullBufferObj; } }
/** * Handle a draw case that potentially has primitive restart enabled. * * If primitive restart is enabled, and PrimitiveRestartInSoftware is * set, then vbo_sw_primitive_restart is used to handle the primitive * restart case in software. */ static void vbo_handle_primitive_restart(struct gl_context *ctx, const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, GLuint max_index) { struct vbo_context *vbo = vbo_context(ctx); if ((ib != NULL) && ctx->Const.PrimitiveRestartInSoftware && ctx->Array._PrimitiveRestart) { /* Handle primitive restart in software */ vbo_sw_primitive_restart(ctx, prim, nr_prims, ib); } else { /* Call driver directly for draw_prims */ vbo->draw_prims(ctx, prim, nr_prims, ib, index_bounds_valid, min_index, max_index, NULL); } }
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); /* obj->Name needs to be non-zero, but won't ever be examined more * closely than that. In particular these buffers won't be entered * into the hash and can never be confused with ones visible to the * user. Perhaps there could be a special number for internal * buffers: */ 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; } 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; vertex_store->refcount = 1; return vertex_store; }
/** * Copy current vertex attribute values into the current vertex. */ static void vbo_exec_copy_from_current(struct vbo_exec_context *exec) { struct gl_context *ctx = exec->ctx; struct vbo_context *vbo = vbo_context(ctx); GLint i; for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) { if (exec->vtx.attrtype[i] == GL_DOUBLE) { memcpy(exec->vtx.attrptr[i], vbo->currval[i].Ptr, exec->vtx.attrsz[i] * sizeof(GLfloat)); } else { const fi_type *current = (fi_type *) vbo->currval[i].Ptr; switch (exec->vtx.attrsz[i]) { case 4: exec->vtx.attrptr[i][3] = current[3]; case 3: exec->vtx.attrptr[i][2] = current[2]; case 2: exec->vtx.attrptr[i][1] = current[1]; case 1: exec->vtx.attrptr[i][0] = current[0]; break; } } } }
void _vbo_DestroyContext(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); if (ctx->aelt_context) { _ae_destroy_context(ctx); ctx->aelt_context = NULL; } if (vbo) { _mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj, NULL); vbo_exec_destroy(ctx); if (ctx->API == API_OPENGL_COMPAT) vbo_save_destroy(ctx); _mesa_reference_vao(ctx, &vbo->VAO, NULL); free(vbo); ctx->vbo_context = NULL; } }
void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; if (0) _mesa_printf("%s\n", __FUNCTION__); if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { if (0) _mesa_printf("%s - inside begin/end\n", __FUNCTION__); return; } vbo_exec_FlushVertices_internal( ctx, GL_TRUE ); /* Need to do this to ensure BeginVertices gets called again: */ if (exec->ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { _mesa_restore_exec_vtxfmt( ctx ); exec->ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; } exec->ctx->Driver.NeedFlush &= ~flags; }
/** * This is called when we fill a vertex buffer before we hit a glEnd(). * We * TODO -- If no new vertices have been stored, don't bother saving it. */ 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); /* Close off in-progress primitive. */ save->prim[i].count = (save->vert_count - 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. */ _save_compile_vertex_list(ctx); /* Restart interrupted primitive */ 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[0].base_instance = 0; save->prim[0].is_indirect = 0; save->prim_count = 1; }
static void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ) { struct vbo_save_context *save = &vbo_context(ctx)->save; if (sz > save->attrsz[attr]) { /* New size is larger. Need to flush existing vertices and get * an enlarged vertex format. */ _save_upgrade_vertex( ctx, attr, sz ); } else if (sz < save->active_sz[attr]) { static GLfloat id[4] = { 0, 0, 0, 1 }; GLuint i; /* New size is equal or smaller - just need to fill in some * zeros. */ for (i = sz ; i <= save->attrsz[attr] ; i++) save->attrptr[attr][i-1] = id[i-1]; } save->active_sz[attr] = sz; }