void _tnl_FlushVertices( GLcontext *ctx, GLuint flags ) { TNLcontext *tnl = TNL_CONTEXT(ctx); (void) flags; if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { /* still inside a glBegin/End pair. How'd we get here??? */ return; } if (tnl->DiscardPrimitive) { /* discard any primitives */ tnl->vtx.prim_count = 0; tnl->vtx.counter = tnl->vtx.initial_counter; tnl->vtx.vbptr = tnl->vtx.buffer; } if (tnl->vtx.counter != tnl->vtx.initial_counter) { _tnl_flush_vtx( ctx ); } if (tnl->vtx.vertex_size) { _tnl_copy_to_current( ctx ); reset_attrfv( tnl ); } ctx->Driver.NeedFlush = 0; }
/* Called for pure, locked VERT_BIT_ELT cassettes instead of * _tnl_run_cassette. */ static void exec_elt_cassette( GLcontext *ctx, struct immediate *IM ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; _tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, ctx->Array.LockCount ); /* Take only elements and primitive information from the immediate: */ VB->Elts = IM->Elt + IM->CopyStart; VB->Primitive = IM->Primitive + IM->CopyStart; VB->PrimitiveLength = IM->PrimitiveLength + IM->CopyStart; VB->FirstPrimitive = 0; /* Run the pipeline. No input changes as a result of this action. */ tnl->Driver.RunPipeline( ctx ); /* Still need to update current values: */ if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { _tnl_translate_array_elts( ctx, IM, IM->LastData, IM->LastData ); _tnl_copy_to_current( ctx, IM, ctx->Array._Enabled, IM->LastData ); } }
static void exec_empty_cassette( GLcontext *ctx, struct immediate *IM ) { if (IM->FlushElt) _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->CopyStart ); _tnl_copy_to_current( ctx, IM, IM->OrFlag, IM->LastData ); }
/** * Called by exec_vert_cassette, execute_compiled_cassette, but not * exec_elt_cassette. */ void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM ) { TNLcontext *tnl = TNL_CONTEXT(ctx); _tnl_vb_bind_immediate( ctx, IM ); if (IM->OrFlag & VERT_BITS_EVAL_ANY) _tnl_eval_immediate( ctx, IM ); /* Invalidate all stored data before and after run: */ tnl->pipeline.run_input_changes |= tnl->pipeline.inputs; tnl->Driver.RunPipeline( ctx ); tnl->pipeline.run_input_changes |= tnl->pipeline.inputs; _tnl_copy_to_current( ctx, IM, IM->OrFlag, IM->LastData ); }
/* Flush existing data, set new attrib size, replay copied vertices. */ static void _tnl_wrap_upgrade_vertex( GLcontext *ctx, GLuint attr, GLuint newsz ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint oldsz; GLuint i; GLfloat *tmp; GLint lastcount = tnl->vtx.initial_counter - tnl->vtx.counter; /* Run pipeline on current vertices, copy wrapped vertices * to tnl->vtx.copied. */ _tnl_wrap_buffers( ctx ); /* Do a COPY_TO_CURRENT to ensure back-copying works for the case * when the attribute already exists in the vertex and is having * its size increased. */ _tnl_copy_to_current( ctx ); /* Heuristic: Attempt to isolate attributes received outside * begin/end so that they don't bloat the vertices. */ if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END && tnl->vtx.attrsz[attr] == 0 && lastcount > 8 && tnl->vtx.vertex_size) { reset_attrfv( tnl ); } /* Fix up sizes: */ oldsz = tnl->vtx.attrsz[attr]; tnl->vtx.attrsz[attr] = newsz; tnl->vtx.vertex_size += newsz - oldsz; tnl->vtx.counter = MIN2( VERT_BUFFER_SIZE / tnl->vtx.vertex_size, ctx->Const.MaxArrayLockSize ); tnl->vtx.initial_counter = tnl->vtx.counter; tnl->vtx.vbptr = tnl->vtx.buffer; /* Recalculate all the attrptr[] values */ for (i = 0, tmp = tnl->vtx.vertex ; i < _TNL_ATTRIB_MAX ; i++) { if (tnl->vtx.attrsz[i]) { tnl->vtx.attrptr[i] = tmp; tmp += tnl->vtx.attrsz[i]; } else tnl->vtx.attrptr[i] = NULL; /* will not be dereferenced */ } /* Copy from current to repopulate the vertex with correct values. */ _tnl_copy_from_current( ctx ); /* Replay stored vertices to translate them * to new format here. * * -- No need to replay - just copy piecewise */ if (tnl->vtx.copied.nr) { GLfloat *data = tnl->vtx.copied.buffer; GLfloat *dest = tnl->vtx.buffer; GLuint j; for (i = 0 ; i < tnl->vtx.copied.nr ; i++) { for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { if (tnl->vtx.attrsz[j]) { if (j == attr) { if (oldsz) { COPY_CLEAN_4V( dest, oldsz, data ); data += oldsz; dest += newsz; } else { COPY_SZ_4V( dest, newsz, tnl->vtx.current[j] ); dest += newsz; } } else { GLuint sz = tnl->vtx.attrsz[j]; COPY_SZ_4V( dest, sz, data ); dest += sz; data += sz; } } } } tnl->vtx.vbptr = dest; tnl->vtx.counter -= tnl->vtx.copied.nr; tnl->vtx.copied.nr = 0; } /* For codegen - attrptr's may have changed, so need to redo * codegen. Might be a reasonable place to try & detect attributes * in the vertex which aren't being submitted any more. */ for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) if (tnl->vtx.attrsz[i]) { GLuint j = tnl->vtx.attrsz[i] - 1; if (i < _TNL_MAX_ATTR_CODEGEN) tnl->vtx.tabfv[i][j] = choose[i][j]; } }