/** * Execute the buffer and save copied verts. */ void _tnl_flush_vtx( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); if (0) _tnl_print_vtx( ctx ); if (tnl->vtx.prim_count && tnl->vtx.counter != tnl->vtx.initial_counter) { tnl->vtx.copied.nr = _tnl_copy_vertices( ctx ); if (ctx->NewState) _mesa_update_state( ctx ); if (tnl->pipeline.build_state_changes) _tnl_validate_pipeline( ctx ); _tnl_vb_bind_vtx( ctx ); /* 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->vtx.prim_count = 0; tnl->vtx.counter = tnl->vtx.initial_counter; tnl->vtx.vbptr = tnl->vtx.buffer; }
/** * Execute the buffer and save copied verts. */ void _tnl_playback_vertex_list( GLcontext *ctx, void *data ) { const struct tnl_vertex_list *node = (const struct tnl_vertex_list *) data; TNLcontext *tnl = TNL_CONTEXT(ctx); FLUSH_CURRENT(ctx, 0); if (node->prim_count > 0 && node->count > 0) { if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END && (node->prim[0].mode & PRIM_BEGIN)) { /* Degenerate case: list is called inside begin/end pair and * includes operations such as glBegin or glDrawArrays. */ _mesa_error( ctx, GL_INVALID_OPERATION, "displaylist recursive begin"); _tnl_loopback_vertex_list( ctx, node ); return; } else if (tnl->LoopbackDListCassettes || node->dangling_attr_ref) { /* Degenerate case: list references current data and would * require fixup. Take the easier option & loop it back. */ _tnl_loopback_vertex_list( ctx, node ); return; } if (ctx->NewState) _mesa_update_state( ctx ); if (tnl->pipeline.build_state_changes) _tnl_validate_pipeline( ctx ); _tnl_bind_vertex_list( ctx, node ); /* 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; } /* Copy to current? */ _playback_copy_to_current( ctx, node ); }
/** * Called for all cassettes when not compiling or playing a display * list. */ void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM ) { TNLcontext *tnl = TNL_CONTEXT(ctx); _tnl_compute_orflag( IM, IM->Start ); _tnl_copy_immediate_vertices( ctx, IM ); _tnl_get_exec_copy_verts( ctx, IM ); if (tnl->pipeline.build_state_changes) _tnl_validate_pipeline( ctx ); if (IM->CopyStart == IM->Count) { exec_empty_cassette( ctx, IM ); } else if ((IM->CopyOrFlag & VERT_BITS_DATA) == VERT_BIT_ELT && ctx->Array.LockCount && ctx->Array.Vertex.Enabled) { exec_elt_cassette( ctx, IM ); } else { exec_vert_cassette( ctx, IM ); } /* Only reuse the immediate if there are no copied vertices living * inside it: */ { GLuint begin_state = IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1); GLuint saved_begin_state = IM->SavedBeginState; if (--IM->ref_count != 0) { IM = _tnl_alloc_immediate( ctx ); SET_IMMEDIATE( ctx, IM ); } IM->ref_count++; _tnl_reset_exec_input( ctx, IMM_MAX_COPIED_VERTS, begin_state, saved_begin_state ); } /* Don't unset FLUSH_STORED_VERTICES flag here as the driver might * have other stored data of its own & be relying on the * FlushVertices notification to clear it. */ }