コード例 #1
0
/* 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 );
   }
}
コード例 #2
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 );
}
コード例 #3
0
/**
 * 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);
}