Esempio n. 1
0
/**
 * 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;
}
Esempio n. 2
0
/**
 * 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 );
}
Esempio n. 3
0
/**
 * 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.
    */
}