ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

vbo_exec_api.c
Go to the documentation of this file.
00001 /**************************************************************************
00002 
00003 Copyright 2002-2008 Tungsten Graphics Inc., Cedar Park, Texas.
00004 
00005 All Rights Reserved.
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a
00008 copy of this software and associated documentation files (the "Software"),
00009 to deal in the Software without restriction, including without limitation
00010 on the rights to use, copy, modify, merge, publish, distribute, sub
00011 license, and/or sell copies of the Software, and to permit persons to whom
00012 the Software is furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice (including the next
00015 paragraph) shall be included in all copies or substantial portions of the
00016 Software.
00017 
00018 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00019 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
00021 TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
00022 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
00023 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
00024 USE OR OTHER DEALINGS IN THE SOFTWARE.
00025 
00026 **************************************************************************/
00027 
00028 /*
00029  * Authors:
00030  *   Keith Whitwell <keith@tungstengraphics.com>
00031  */
00032 
00033 #include "main/glheader.h"
00034 #include "main/bufferobj.h"
00035 #include "main/context.h"
00036 #include "main/macros.h"
00037 #include "main/vtxfmt.h"
00038 #if FEATURE_dlist
00039 #include "main/dlist.h"
00040 #endif
00041 #include "main/state.h"
00042 #include "main/light.h"
00043 #include "main/api_arrayelt.h"
00044 #include "main/api_noop.h"
00045 #include "glapi/dispatch.h"
00046 
00047 #include "vbo_context.h"
00048 
00049 #ifdef ERROR
00050 #undef ERROR
00051 #endif
00052 
00053 
00054 static void reset_attrfv( struct vbo_exec_context *exec );
00055 
00056 
00057 /* Close off the last primitive, execute the buffer, restart the
00058  * primitive.  
00059  */
00060 static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )
00061 {
00062    if (exec->vtx.prim_count == 0) {
00063       exec->vtx.copied.nr = 0;
00064       exec->vtx.vert_count = 0;
00065       exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map;
00066    }
00067    else {
00068       GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin;
00069       GLuint last_count;
00070 
00071       if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
00072      GLint i = exec->vtx.prim_count - 1;
00073      assert(i >= 0);
00074      exec->vtx.prim[i].count = (exec->vtx.vert_count - 
00075                     exec->vtx.prim[i].start);
00076       }
00077 
00078       last_count = exec->vtx.prim[exec->vtx.prim_count-1].count;
00079 
00080       /* Execute the buffer and save copied vertices.
00081        */
00082       if (exec->vtx.vert_count)
00083      vbo_exec_vtx_flush( exec );
00084       else {
00085      exec->vtx.prim_count = 0;
00086      exec->vtx.copied.nr = 0;
00087       }
00088 
00089       /* Emit a glBegin to start the new list.
00090        */
00091       assert(exec->vtx.prim_count == 0);
00092 
00093       if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
00094      exec->vtx.prim[0].mode = exec->ctx->Driver.CurrentExecPrimitive;
00095      exec->vtx.prim[0].start = 0;
00096      exec->vtx.prim[0].count = 0;
00097      exec->vtx.prim_count++;
00098       
00099      if (exec->vtx.copied.nr == last_count)
00100         exec->vtx.prim[0].begin = last_begin;
00101       }
00102    }
00103 }
00104 
00105 
00106 /* Deal with buffer wrapping where provoked by the vertex buffer
00107  * filling up, as opposed to upgrade_vertex().
00108  */
00109 void vbo_exec_vtx_wrap( struct vbo_exec_context *exec )
00110 {
00111    GLfloat *data = exec->vtx.copied.buffer;
00112    GLuint i;
00113 
00114    /* Run pipeline on current vertices, copy wrapped vertices
00115     * to exec->vtx.copied.
00116     */
00117    vbo_exec_wrap_buffers( exec );
00118    
00119    /* Copy stored stored vertices to start of new list. 
00120     */
00121    assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr);
00122 
00123    for (i = 0 ; i < exec->vtx.copied.nr ; i++) {
00124       _mesa_memcpy( exec->vtx.vbptr, data, 
00125             exec->vtx.vertex_size * sizeof(GLfloat));
00126       exec->vtx.vbptr += exec->vtx.vertex_size;
00127       data += exec->vtx.vertex_size;
00128       exec->vtx.vert_count++;
00129    }
00130 
00131    exec->vtx.copied.nr = 0;
00132 }
00133 
00134 
00135 /*
00136  * Copy the active vertex's values to the ctx->Current fields.
00137  */
00138 static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
00139 {
00140    GLcontext *ctx = exec->ctx;
00141    struct vbo_context *vbo = vbo_context(ctx);
00142    GLuint i;
00143 
00144    for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
00145       if (exec->vtx.attrsz[i]) {
00146      GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
00147 
00148          /* Note: the exec->vtx.current[i] pointers point into the
00149           * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
00150           */
00151          if (exec->vtx.attrptr[i]) {
00152 
00153      COPY_CLEAN_4V(current, 
00154                exec->vtx.attrsz[i], 
00155                exec->vtx.attrptr[i]);
00156 
00157      }
00158 
00159      /* Given that we explicitly state size here, there is no need
00160       * for the COPY_CLEAN above, could just copy 16 bytes and be
00161       * done.  The only problem is when Mesa accesses ctx->Current
00162       * directly.
00163       */
00164      vbo->currval[i].Size = exec->vtx.attrsz[i];
00165 
00166      /* This triggers rather too much recalculation of Mesa state
00167       * that doesn't get used (eg light positions).
00168       */
00169      if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT &&
00170          i <= VBO_ATTRIB_MAT_BACK_INDEXES)
00171         ctx->NewState |= _NEW_LIGHT;
00172       }
00173    }
00174 
00175    /* Colormaterial -- this kindof sucks.
00176     */
00177    if (ctx->Light.ColorMaterialEnabled &&
00178        exec->vtx.attrsz[VBO_ATTRIB_COLOR0]) {
00179       _mesa_update_color_material(ctx, 
00180                   ctx->Current.Attrib[VBO_ATTRIB_COLOR0]);
00181    }
00182 
00183    ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
00184 }
00185 
00186 
00187 static void vbo_exec_copy_from_current( struct vbo_exec_context *exec )
00188 {
00189    GLcontext *ctx = exec->ctx;
00190    struct vbo_context *vbo = vbo_context(ctx);
00191    GLint i;
00192 
00193    for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
00194       const GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
00195       switch (exec->vtx.attrsz[i]) {
00196       case 4: exec->vtx.attrptr[i][3] = current[3];
00197       case 3: exec->vtx.attrptr[i][2] = current[2];
00198       case 2: exec->vtx.attrptr[i][1] = current[1];
00199       case 1: exec->vtx.attrptr[i][0] = current[0];
00200      break;
00201       }
00202    }
00203 
00204    ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
00205 }
00206 
00207 
00208 /* Flush existing data, set new attrib size, replay copied vertices.
00209  */ 
00210 static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,
00211                       GLuint attr,
00212                       GLuint newsz )
00213 {
00214    GLcontext *ctx = exec->ctx;
00215    struct vbo_context *vbo = vbo_context(ctx);
00216    GLint lastcount = exec->vtx.vert_count;
00217    GLfloat *tmp;
00218    GLuint oldsz;
00219    GLuint i;
00220 
00221    /* Run pipeline on current vertices, copy wrapped vertices
00222     * to exec->vtx.copied.
00223     */
00224    vbo_exec_wrap_buffers( exec );
00225 
00226 
00227    /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
00228     * when the attribute already exists in the vertex and is having
00229     * its size increased.  
00230     */
00231    vbo_exec_copy_to_current( exec );
00232 
00233 
00234    /* Heuristic: Attempt to isolate attributes received outside
00235     * begin/end so that they don't bloat the vertices.
00236     */
00237    if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END &&
00238        exec->vtx.attrsz[attr] == 0 && 
00239        lastcount > 8 &&
00240        exec->vtx.vertex_size) {
00241       reset_attrfv( exec );
00242    }
00243 
00244    /* Fix up sizes:
00245     */
00246    oldsz = exec->vtx.attrsz[attr];
00247    exec->vtx.attrsz[attr] = newsz;
00248 
00249    exec->vtx.vertex_size += newsz - oldsz;
00250    exec->vtx.max_vert = VBO_VERT_BUFFER_SIZE / exec->vtx.vertex_size;
00251    exec->vtx.vert_count = 0;
00252    exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map;
00253    
00254 
00255    /* Recalculate all the attrptr[] values
00256     */
00257    for (i = 0, tmp = exec->vtx.vertex ; i < VBO_ATTRIB_MAX ; i++) {
00258       if (exec->vtx.attrsz[i]) {
00259      exec->vtx.attrptr[i] = tmp;
00260      tmp += exec->vtx.attrsz[i];
00261       }
00262       else 
00263      exec->vtx.attrptr[i] = NULL; /* will not be dereferenced */
00264    }
00265 
00266    /* Copy from current to repopulate the vertex with correct values.
00267     */
00268    vbo_exec_copy_from_current( exec );
00269 
00270    /* Replay stored vertices to translate them
00271     * to new format here.
00272     *
00273     * -- No need to replay - just copy piecewise
00274     */
00275    if (exec->vtx.copied.nr)
00276    {
00277       GLfloat *data = exec->vtx.copied.buffer;
00278       GLfloat *dest = exec->vtx.vbptr;
00279       GLuint j;
00280 
00281       assert(exec->vtx.vbptr == (GLfloat *)exec->vtx.buffer_map);
00282       
00283       for (i = 0 ; i < exec->vtx.copied.nr ; i++) {
00284      for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {
00285         if (exec->vtx.attrsz[j]) {
00286            if (j == attr) {
00287           if (oldsz) {
00288              COPY_CLEAN_4V( dest, oldsz, data );
00289              data += oldsz;
00290              dest += newsz;
00291           } else {
00292              const GLfloat *current = (const GLfloat *)vbo->currval[j].Ptr;
00293              COPY_SZ_4V( dest, newsz, current );
00294              dest += newsz;
00295           }
00296            }
00297            else {
00298           GLuint sz = exec->vtx.attrsz[j];
00299           COPY_SZ_4V( dest, sz, data );
00300           dest += sz;
00301           data += sz;
00302            }
00303         }
00304      }
00305       }
00306 
00307       exec->vtx.vbptr = dest;
00308       exec->vtx.vert_count += exec->vtx.copied.nr;
00309       exec->vtx.copied.nr = 0;
00310    }
00311 }
00312 
00313 
00314 static void vbo_exec_fixup_vertex( GLcontext *ctx,
00315                    GLuint attr, GLuint sz )
00316 {
00317    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
00318    int i;
00319 
00320    if (sz > exec->vtx.attrsz[attr]) {
00321       /* New size is larger.  Need to flush existing vertices and get
00322        * an enlarged vertex format.
00323        */
00324       vbo_exec_wrap_upgrade_vertex( exec, attr, sz );
00325    }
00326    else if (sz < exec->vtx.active_sz[attr]) {
00327       static const GLfloat id[4] = { 0, 0, 0, 1 };
00328 
00329       /* New size is smaller - just need to fill in some
00330        * zeros.  Don't need to flush or wrap.
00331        */
00332       for (i = sz ; i <= exec->vtx.attrsz[attr] ; i++)
00333      exec->vtx.attrptr[attr][i-1] = id[i-1];
00334    }
00335 
00336    exec->vtx.active_sz[attr] = sz;
00337 
00338    /* Does setting NeedFlush belong here?  Necessitates resetting
00339     * vtxfmt on each flush (otherwise flags won't get reset
00340     * afterwards).
00341     */
00342    if (attr == 0) 
00343       exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
00344    else 
00345       exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
00346 }
00347 
00348 
00349 
00350 
00351 /* 
00352  */
00353 #define ATTR( A, N, V0, V1, V2, V3 )                \
00354 do {                                \
00355    struct vbo_exec_context *exec = &vbo_context(ctx)->exec; \
00356                                 \
00357    if (exec->vtx.active_sz[A] != N)             \
00358       vbo_exec_fixup_vertex(ctx, A, N);         \
00359                                 \
00360    {                                \
00361       GLfloat *dest = exec->vtx.attrptr[A];         \
00362       if (N>0) dest[0] = V0;                    \
00363       if (N>1) dest[1] = V1;                    \
00364       if (N>2) dest[2] = V2;                    \
00365       if (N>3) dest[3] = V3;                    \
00366    }                                \
00367                                 \
00368    if ((A) == 0) {                      \
00369       GLuint i;                         \
00370                                 \
00371       for (i = 0; i < exec->vtx.vertex_size; i++)       \
00372      exec->vtx.vbptr[i] = exec->vtx.vertex[i];      \
00373                                 \
00374       exec->vtx.vbptr += exec->vtx.vertex_size;         \
00375       exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \
00376                                 \
00377       if (++exec->vtx.vert_count >= exec->vtx.max_vert)     \
00378      vbo_exec_vtx_wrap( exec );             \
00379    }                                \
00380 } while (0)
00381 
00382 
00383 #define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ )
00384 #define TAG(x) vbo_##x
00385 
00386 #include "vbo_attrib_tmp.h"
00387 
00388 
00389 
00390 
00391 
00392 /* Eval
00393  */
00394 static void GLAPIENTRY vbo_exec_EvalCoord1f( GLfloat u )
00395 {
00396    GET_CURRENT_CONTEXT( ctx );
00397    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
00398 
00399    {
00400       GLint i;
00401       if (exec->eval.recalculate_maps) 
00402      vbo_exec_eval_update( exec );
00403 
00404       for (i = 0; i <= VBO_ATTRIB_TEX7; i++) {
00405      if (exec->eval.map1[i].map) 
00406         if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz)
00407            vbo_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz );
00408       }
00409    }
00410 
00411 
00412    _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, 
00413                  exec->vtx.vertex_size * sizeof(GLfloat));
00414 
00415    vbo_exec_do_EvalCoord1f( exec, u );
00416 
00417    _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer,
00418                  exec->vtx.vertex_size * sizeof(GLfloat));
00419 }
00420 
00421 static void GLAPIENTRY vbo_exec_EvalCoord2f( GLfloat u, GLfloat v )
00422 {
00423    GET_CURRENT_CONTEXT( ctx );
00424    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
00425 
00426    {
00427       GLint i;
00428       if (exec->eval.recalculate_maps) 
00429      vbo_exec_eval_update( exec );
00430 
00431       for (i = 0; i <= VBO_ATTRIB_TEX7; i++) {
00432      if (exec->eval.map2[i].map) 
00433         if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz)
00434            vbo_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz );
00435       }
00436 
00437       if (ctx->Eval.AutoNormal) 
00438      if (exec->vtx.active_sz[VBO_ATTRIB_NORMAL] != 3)
00439         vbo_exec_fixup_vertex( ctx, VBO_ATTRIB_NORMAL, 3 );
00440    }
00441 
00442    _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, 
00443                  exec->vtx.vertex_size * sizeof(GLfloat));
00444 
00445    vbo_exec_do_EvalCoord2f( exec, u, v );
00446 
00447    _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, 
00448                  exec->vtx.vertex_size * sizeof(GLfloat));
00449 }
00450 
00451 static void GLAPIENTRY vbo_exec_EvalCoord1fv( const GLfloat *u )
00452 {
00453    vbo_exec_EvalCoord1f( u[0] );
00454 }
00455 
00456 static void GLAPIENTRY vbo_exec_EvalCoord2fv( const GLfloat *u )
00457 {
00458    vbo_exec_EvalCoord2f( u[0], u[1] );
00459 }
00460 
00461 static void GLAPIENTRY vbo_exec_EvalPoint1( GLint i )
00462 {
00463    GET_CURRENT_CONTEXT( ctx );
00464    GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) /
00465          (GLfloat) ctx->Eval.MapGrid1un);
00466    GLfloat u = i * du + ctx->Eval.MapGrid1u1;
00467 
00468    vbo_exec_EvalCoord1f( u );
00469 }
00470 
00471 
00472 static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j )
00473 {
00474    GET_CURRENT_CONTEXT( ctx );
00475    GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / 
00476          (GLfloat) ctx->Eval.MapGrid2un);
00477    GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / 
00478          (GLfloat) ctx->Eval.MapGrid2vn);
00479    GLfloat u = i * du + ctx->Eval.MapGrid2u1;
00480    GLfloat v = j * dv + ctx->Eval.MapGrid2v1;
00481 
00482    vbo_exec_EvalCoord2f( u, v );
00483 }
00484 
00485 
00489 GLboolean 
00490 vbo_validate_shaders(GLcontext *ctx)
00491 {
00492    if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) ||
00493        (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) {
00494       return GL_FALSE;
00495    }
00496    if (ctx->Shader.CurrentProgram && !ctx->Shader.CurrentProgram->LinkStatus) {
00497       return GL_FALSE;
00498    }
00499    return GL_TRUE;
00500 }
00501 
00502 
00503 /* Build a list of primitives on the fly.  Keep
00504  * ctx->Driver.CurrentExecPrimitive uptodate as well.
00505  */
00506 static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
00507 {
00508    GET_CURRENT_CONTEXT( ctx ); 
00509 
00510    if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
00511       struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
00512       int i;
00513 
00514       if (ctx->NewState) {
00515      _mesa_update_state( ctx );
00516 
00517      CALL_Begin(ctx->Exec, (mode));
00518      return;
00519       }
00520 
00521       if (!vbo_validate_shaders(ctx)) {
00522          _mesa_error(ctx, GL_INVALID_OPERATION,
00523                      "glBegin (invalid vertex/fragment program)");
00524          return;
00525       }
00526 
00527       /* Heuristic: attempt to isolate attributes occuring outside
00528        * begin/end pairs.
00529        */
00530       if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) 
00531      vbo_exec_FlushVertices( ctx, ~0 );
00532 
00533       i = exec->vtx.prim_count++;
00534       exec->vtx.prim[i].mode = mode;
00535       exec->vtx.prim[i].begin = 1;
00536       exec->vtx.prim[i].end = 0;
00537       exec->vtx.prim[i].indexed = 0;
00538       exec->vtx.prim[i].weak = 0;
00539       exec->vtx.prim[i].pad = 0;
00540       exec->vtx.prim[i].start = exec->vtx.vert_count;
00541       exec->vtx.prim[i].count = 0;
00542 
00543       ctx->Driver.CurrentExecPrimitive = mode;
00544    }
00545    else 
00546       _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
00547       
00548 }
00549 
00550 static void GLAPIENTRY vbo_exec_End( void )
00551 {
00552    GET_CURRENT_CONTEXT( ctx ); 
00553 
00554    if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
00555       struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
00556       int idx = exec->vtx.vert_count;
00557       int i = exec->vtx.prim_count - 1;
00558 
00559       exec->vtx.prim[i].end = 1; 
00560       exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start;
00561 
00562       ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
00563 
00564       if (exec->vtx.prim_count == VBO_MAX_PRIM)
00565      vbo_exec_vtx_flush( exec );    
00566    }
00567    else 
00568       _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
00569 }
00570 
00571 
00572 static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
00573 {
00574    GLvertexformat *vfmt = &exec->vtxfmt;
00575 
00576    vfmt->ArrayElement = _ae_loopback_array_elt;         /* generic helper */
00577    vfmt->Begin = vbo_exec_Begin;
00578 #if FEATURE_dlist
00579    vfmt->CallList = _mesa_CallList;
00580    vfmt->CallLists = _mesa_CallLists;
00581 #endif
00582    vfmt->End = vbo_exec_End;
00583    vfmt->EvalCoord1f = vbo_exec_EvalCoord1f;
00584    vfmt->EvalCoord1fv = vbo_exec_EvalCoord1fv;
00585    vfmt->EvalCoord2f = vbo_exec_EvalCoord2f;
00586    vfmt->EvalCoord2fv = vbo_exec_EvalCoord2fv;
00587    vfmt->EvalPoint1 = vbo_exec_EvalPoint1;
00588    vfmt->EvalPoint2 = vbo_exec_EvalPoint2;
00589 
00590    vfmt->Rectf = _mesa_noop_Rectf;
00591    vfmt->EvalMesh1 = _mesa_noop_EvalMesh1;
00592    vfmt->EvalMesh2 = _mesa_noop_EvalMesh2;
00593 
00594 
00595    /* from attrib_tmp.h:
00596     */
00597    vfmt->Color3f = vbo_Color3f;
00598    vfmt->Color3fv = vbo_Color3fv;
00599    vfmt->Color4f = vbo_Color4f;
00600    vfmt->Color4fv = vbo_Color4fv;
00601    vfmt->FogCoordfEXT = vbo_FogCoordfEXT;
00602    vfmt->FogCoordfvEXT = vbo_FogCoordfvEXT;
00603    vfmt->MultiTexCoord1fARB = vbo_MultiTexCoord1f;
00604    vfmt->MultiTexCoord1fvARB = vbo_MultiTexCoord1fv;
00605    vfmt->MultiTexCoord2fARB = vbo_MultiTexCoord2f;
00606    vfmt->MultiTexCoord2fvARB = vbo_MultiTexCoord2fv;
00607    vfmt->MultiTexCoord3fARB = vbo_MultiTexCoord3f;
00608    vfmt->MultiTexCoord3fvARB = vbo_MultiTexCoord3fv;
00609    vfmt->MultiTexCoord4fARB = vbo_MultiTexCoord4f;
00610    vfmt->MultiTexCoord4fvARB = vbo_MultiTexCoord4fv;
00611    vfmt->Normal3f = vbo_Normal3f;
00612    vfmt->Normal3fv = vbo_Normal3fv;
00613    vfmt->SecondaryColor3fEXT = vbo_SecondaryColor3fEXT;
00614    vfmt->SecondaryColor3fvEXT = vbo_SecondaryColor3fvEXT;
00615    vfmt->TexCoord1f = vbo_TexCoord1f;
00616    vfmt->TexCoord1fv = vbo_TexCoord1fv;
00617    vfmt->TexCoord2f = vbo_TexCoord2f;
00618    vfmt->TexCoord2fv = vbo_TexCoord2fv;
00619    vfmt->TexCoord3f = vbo_TexCoord3f;
00620    vfmt->TexCoord3fv = vbo_TexCoord3fv;
00621    vfmt->TexCoord4f = vbo_TexCoord4f;
00622    vfmt->TexCoord4fv = vbo_TexCoord4fv;
00623    vfmt->Vertex2f = vbo_Vertex2f;
00624    vfmt->Vertex2fv = vbo_Vertex2fv;
00625    vfmt->Vertex3f = vbo_Vertex3f;
00626    vfmt->Vertex3fv = vbo_Vertex3fv;
00627    vfmt->Vertex4f = vbo_Vertex4f;
00628    vfmt->Vertex4fv = vbo_Vertex4fv;
00629    
00630    vfmt->VertexAttrib1fARB = vbo_VertexAttrib1fARB;
00631    vfmt->VertexAttrib1fvARB = vbo_VertexAttrib1fvARB;
00632    vfmt->VertexAttrib2fARB = vbo_VertexAttrib2fARB;
00633    vfmt->VertexAttrib2fvARB = vbo_VertexAttrib2fvARB;
00634    vfmt->VertexAttrib3fARB = vbo_VertexAttrib3fARB;
00635    vfmt->VertexAttrib3fvARB = vbo_VertexAttrib3fvARB;
00636    vfmt->VertexAttrib4fARB = vbo_VertexAttrib4fARB;
00637    vfmt->VertexAttrib4fvARB = vbo_VertexAttrib4fvARB;
00638 
00639    vfmt->VertexAttrib1fNV = vbo_VertexAttrib1fNV;
00640    vfmt->VertexAttrib1fvNV = vbo_VertexAttrib1fvNV;
00641    vfmt->VertexAttrib2fNV = vbo_VertexAttrib2fNV;
00642    vfmt->VertexAttrib2fvNV = vbo_VertexAttrib2fvNV;
00643    vfmt->VertexAttrib3fNV = vbo_VertexAttrib3fNV;
00644    vfmt->VertexAttrib3fvNV = vbo_VertexAttrib3fvNV;
00645    vfmt->VertexAttrib4fNV = vbo_VertexAttrib4fNV;
00646    vfmt->VertexAttrib4fvNV = vbo_VertexAttrib4fvNV;
00647 
00648    vfmt->Materialfv = vbo_Materialfv;
00649 
00650    vfmt->EdgeFlag = vbo_EdgeFlag;
00651    vfmt->Indexf = vbo_Indexf;
00652    vfmt->Indexfv = vbo_Indexfv;
00653 
00654 }
00655 
00656 
00663 void vbo_use_buffer_objects(GLcontext *ctx)
00664 {
00665    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
00666    /* Any buffer name but 0 can be used here since this bufferobj won't
00667     * go into the bufferobj hashtable.
00668     */
00669    GLuint bufName = 0xaabbccdd;
00670    GLenum target = GL_ARRAY_BUFFER_ARB;
00671    GLenum access = GL_READ_WRITE_ARB;
00672    GLenum usage = GL_STREAM_DRAW_ARB;
00673    GLsizei size = VBO_VERT_BUFFER_SIZE * sizeof(GLfloat);
00674 
00675    /* Make sure this func is only used once */
00676    assert(exec->vtx.bufferobj == ctx->Array.NullBufferObj);
00677    if (exec->vtx.buffer_map) {
00678       _mesa_align_free(exec->vtx.buffer_map);
00679    }
00680 
00681    /* Allocate a real buffer object now */
00682    exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target);
00683    ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj);
00684 
00685    /* and map it */
00686    exec->vtx.buffer_map
00687       = ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
00688 }
00689 
00690 
00691 
00692 void vbo_exec_vtx_init( struct vbo_exec_context *exec )
00693 {
00694    GLcontext *ctx = exec->ctx;
00695    struct vbo_context *vbo = vbo_context(ctx);
00696    GLuint i;
00697 
00698    /* Allocate a buffer object.  Will just reuse this object
00699     * continuously.
00700     */
00701    _mesa_reference_buffer_object(ctx,
00702                                  &exec->vtx.bufferobj,
00703                                  ctx->Array.NullBufferObj);
00704 
00705    ASSERT(!exec->vtx.buffer_map);
00706    exec->vtx.buffer_map = ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE * sizeof(GLfloat), 64);
00707    vbo_exec_vtxfmt_init( exec );
00708 
00709    /* Hook our functions into the dispatch table.
00710     */
00711    _mesa_install_exec_vtxfmt( exec->ctx, &exec->vtxfmt );
00712 
00713    for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
00714       exec->vtx.attrsz[i] = 0;
00715       exec->vtx.active_sz[i] = 0;
00716       exec->vtx.inputs[i] = &exec->vtx.arrays[i];
00717    }
00718    
00719    {
00720       struct gl_client_array *arrays = exec->vtx.arrays;
00721       memcpy(arrays,      vbo->legacy_currval,  16 * sizeof(arrays[0]));
00722       memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0]));
00723    }
00724 
00725    exec->vtx.vertex_size = 0;
00726 }
00727 
00728 
00729 void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )
00730 {
00731    if (exec->vtx.bufferobj->Name) {
00732       /* using a real VBO for vertex data */
00733       GLcontext *ctx = exec->ctx;
00734       _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
00735    }
00736    else {
00737       /* just using malloc'd space for vertex data */
00738       if (exec->vtx.buffer_map) {
00739          ALIGN_FREE(exec->vtx.buffer_map);
00740          exec->vtx.buffer_map = NULL;
00741       }
00742    }
00743 }
00744 
00745 
00746 void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags )
00747 {
00748    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
00749 
00750    if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)
00751       return;
00752 
00753    if (exec->vtx.vert_count) {
00754       vbo_exec_vtx_flush( exec );
00755    }
00756 
00757    if (exec->vtx.vertex_size) {
00758       vbo_exec_copy_to_current( exec );
00759       reset_attrfv( exec );
00760    }
00761 
00762    exec->ctx->Driver.NeedFlush = 0;
00763 }
00764 
00765 
00766 static void reset_attrfv( struct vbo_exec_context *exec )
00767 {   
00768    GLuint i;
00769 
00770    for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
00771       exec->vtx.attrsz[i] = 0;
00772       exec->vtx.active_sz[i] = 0;
00773    }
00774 
00775    exec->vtx.vertex_size = 0;
00776 }
00777       

Generated on Sat May 26 2012 04:19:38 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.