mesa3d原始碼閱讀筆記(6)_vbo_exec_vtx_flush執行流程

來源:互聯網
上載者:User

vbo_exec_vtx_flush定義在vbo_exec_draw.c第353行處,具體代碼如下:

vbo_exec_vtx_flush// vbo_exec_draw.c   從第349行至417行/** * Execute the buffer and save copied verts. */voidvbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap ){   if (0)      vbo_exec_debug_verts( exec );   if (exec->vtx.prim_count &&        exec->vtx.vert_count) {      exec->vtx.copied.nr = vbo_copy_vertices( exec );       if (exec->vtx.copied.nr != exec->vtx.vert_count) { GLcontext *ctx = exec->ctx;  /* Before the update_state() as this may raise _NEW_ARRAY          * from _mesa_set_varying_vp_inputs().  */ vbo_exec_bind_arrays( ctx );         if (ctx->NewState)            _mesa_update_state( ctx );         if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {            vbo_exec_vtx_unmap( exec );         }         if (0)            _mesa_printf("%s %d %d\n", __FUNCTION__, exec->vtx.prim_count,                         exec->vtx.vert_count); vbo_context(ctx)->draw_prims( ctx,        exec->vtx.inputs,        exec->vtx.prim,        exec->vtx.prim_count,       NULL,       GL_TRUE,       0,       exec->vtx.vert_count - 1); /* If using a real VBO, get new storage -- unless asked not to.          */         if (_mesa_is_bufferobj(exec->vtx.bufferobj) && !unmap) {            vbo_exec_vtx_map( exec );         }      }   }   /* May have to unmap explicitly if we didn't draw:    */   if (unmap &&        _mesa_is_bufferobj(exec->vtx.bufferobj) &&       exec->vtx.buffer_map) {      vbo_exec_vtx_unmap( exec );   }   if (unmap || exec->vtx.vertex_size == 0)      exec->vtx.max_vert = 0;   else      exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /                             (exec->vtx.vertex_size * sizeof(GLfloat)));   exec->vtx.buffer_ptr = exec->vtx.buffer_map;   exec->vtx.prim_count = 0;   exec->vtx.vert_count = 0;}

第382行是開始準備進入管道繪製處的語句,具體對應t_draw.c第363行處的_tnl_vbo_draw_prims,然後到達_tnl_draw_prims函數;

_tnl_draw_prims// t_draw.c  從第378行到450行/* This is the main entrypoint into the slimmed-down software tnl * module.  In a regular swtnl driver, this can be plugged straight * into the vbo->Driver.DrawPrims() callback. */void _tnl_draw_prims( GLcontext *ctx,      const struct gl_client_array *arrays[],      const struct _mesa_prim *prim,      GLuint nr_prims,      const struct _mesa_index_buffer *ib,      GLuint min_index,      GLuint max_index){   TNLcontext *tnl = TNL_CONTEXT(ctx);   const GLuint TEST_SPLIT = 0;   const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;   if (0)   {      GLuint i;      _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);      for (i = 0; i < nr_prims; i++) _mesa_printf("prim %d: %s start %d count %d\n", i,       _mesa_lookup_enum_by_nr(prim[i].mode),      prim[i].start,      prim[i].count);   }   if (min_index) {      /* We always translate away calls with min_index != 0.        */      vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index,_tnl_vbo_draw_prims );      return;   }   else if (max_index > max) {      /* The software TNL pipeline has a fixed amount of storage for       * vertices and it is necessary to split incoming drawing commands       * if they exceed that limit.       */      struct split_limits limits;      limits.max_verts = max;      limits.max_vb_size = ~0;      limits.max_indices = ~0;      /* This will split the buffers one way or another and       * recursively call back into this function.       */      vbo_split_prims( ctx, arrays, prim, nr_prims, ib,        0, max_index,       _tnl_vbo_draw_prims,       &limits );   }   else {      /* May need to map a vertex buffer object for every attribute plus       * one for the index buffer.       */      struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];      GLuint nr_bo = 0;      /* Binding inputs may imply mapping some vertex buffer objects.       * They will need to be unmapped below.       */      bind_inputs(ctx, arrays, max_index+1, bo, &nr_bo);      bind_indices(ctx, ib, bo, &nr_bo);      bind_prims(ctx, prim, nr_prims );      TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);      unmap_vbos(ctx, bo, nr_bo);      free_space(ctx);   }}

實際執行時只會執行第431行起的else {}代碼塊,而第445行處的TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);是正式的進入管道的入口語句,它對應在t_pipeline.c第121行處的_tnl_run_pipeline。

_tnl_run_pipeline// t_pipeline.c   從第121行至162行void _tnl_run_pipeline( GLcontext *ctx ){   TNLcontext *tnl = TNL_CONTEXT(ctx);   unsigned short __tmp;   GLuint i;   if (!tnl->vb.Count)      return;   /* Check for changed input sizes or change in stride to/from zero    * (ie const or non-const).    */   if (check_input_changes( ctx ) || tnl->pipeline.new_state) {      if (ctx->VertexProgram._MaintainTnlProgram) _tnl_UpdateFixedFunctionProgram( ctx );      for (i = 0; i < tnl->pipeline.nr_stages ; i++) { struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i]; if (s->validate)    s->validate( ctx, s );      }            tnl->pipeline.new_state = 0;      tnl->pipeline.input_changes = 0;            /* Pipeline can only change its output in response to either a       * statechange or an input size/stride change.  No other changes       * are allowed.       */      if (check_output_changes( ctx )) _tnl_notify_pipeline_output_change( ctx );   }   START_FAST_MATH(__tmp);   for (i = 0; i < tnl->pipeline.nr_stages ; i++) {      struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i];      if (!s->run( ctx, s )) break;   }   END_FAST_MATH(__tmp);}

 

其中對應的管道結構變數是:

const struct tnl_pipeline_stage *_tnl_default_pipeline[] = {   &_tnl_vertex_transform_stage,   &_tnl_normal_transform_stage,   &_tnl_lighting_stage,   &_tnl_texgen_stage,   &_tnl_texture_transform_stage,   &_tnl_point_attenuation_stage,   &_tnl_vertex_program_stage,    &_tnl_fog_coordinate_stage,   &_tnl_render_stage,   NULL };

由上可見首先計算頂點,然後變換,再光照等等,最後運行渲染。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.