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

t_dd_dmatmp.h
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  6.5.1
00004  *
00005  * Copyright (C) 1999-2006  Brian Paul   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  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  *
00024  * Authors:
00025  *    Keith Whitwell <keith@tungstengraphics.com>
00026  */
00027 
00028 
00042 #if !defined(HAVE_TRIANGLES)
00043 #error "must have at least triangles to use render template"
00044 #endif
00045 
00046 #if !HAVE_ELTS
00047 #define ELTS_VARS(buf)
00048 #define ALLOC_ELTS(nr) 0
00049 #define EMIT_ELT( offset, elt )
00050 #define EMIT_TWO_ELTS( offset, elt0, elt1 )
00051 #define INCR_ELTS( nr )
00052 #define ELT_INIT(prim)
00053 #define GET_CURRENT_VB_MAX_ELTS() 0
00054 #define GET_SUBSEQUENT_VB_MAX_ELTS() 0
00055 #define RELEASE_ELT_VERTS()
00056 #define EMIT_INDEXED_VERTS( ctx, start, count )
00057 #endif
00058 
00059 #ifndef EMIT_TWO_ELTS
00060 #define EMIT_TWO_ELTS( offset, elt0, elt1 ) \
00061 do {                        \
00062    EMIT_ELT( offset, elt0 );            \
00063    EMIT_ELT( offset+1, elt1 );          \
00064 } while (0)
00065 #endif
00066 
00067 
00068 /**********************************************************************/
00069 /*                  Render whole begin/end objects                    */
00070 /**********************************************************************/
00071 
00072 
00073 
00074 
00075 #if (HAVE_ELTS)
00076 static void *TAG(emit_elts)( GLcontext *ctx, GLuint *elts, GLuint nr,
00077                  void *buf)
00078 {
00079    GLint i;
00080    LOCAL_VARS;
00081    ELTS_VARS(buf);
00082 
00083    for ( i = 0 ; i+1 < nr ; i+=2, elts += 2 ) {
00084       EMIT_TWO_ELTS( 0, elts[0], elts[1] );
00085       INCR_ELTS( 2 );
00086    }
00087    
00088    if (i < nr) {
00089       EMIT_ELT( 0, elts[0] );
00090       INCR_ELTS( 1 );
00091    }
00092 
00093    return (void *)ELTPTR;
00094 }
00095 #endif
00096 
00097 static __inline void *TAG(emit_verts)( GLcontext *ctx, GLuint start, 
00098                      GLuint count, void *buf )
00099 {
00100    return EMIT_VERTS(ctx, start, count, buf);
00101 }
00102 
00103 /***********************************************************************
00104  *                    Render non-indexed primitives.
00105  ***********************************************************************/
00106 
00107 static void TAG(render_points_verts)( GLcontext *ctx,
00108                       GLuint start,
00109                       GLuint count,
00110                       GLuint flags )
00111 {
00112    if (HAVE_POINTS) {
00113       LOCAL_VARS;
00114       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
00115       int currentsz;
00116       GLuint j, nr;
00117 
00118       INIT( GL_POINTS );
00119 
00120       currentsz = GET_CURRENT_VB_MAX_VERTS();
00121       if (currentsz < 8)
00122      currentsz = dmasz;
00123 
00124       for (j = start; j < count; j += nr ) {
00125      nr = MIN2( currentsz, count - j );
00126      TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
00127      currentsz = dmasz;
00128       }
00129 
00130    } else {
00131       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00132       return;
00133    }
00134 }
00135 
00136 static void TAG(render_lines_verts)( GLcontext *ctx,
00137                      GLuint start,
00138                      GLuint count,
00139                      GLuint flags )
00140 {
00141    if (HAVE_LINES) {
00142       LOCAL_VARS;
00143       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
00144       int currentsz;
00145       GLuint j, nr;
00146 
00147       INIT( GL_LINES );
00148 
00149       /* Emit whole number of lines in total and in each buffer:
00150        */
00151       count -= (count-start) & 1;
00152       currentsz = GET_CURRENT_VB_MAX_VERTS();
00153       currentsz -= currentsz & 1;
00154       dmasz -= dmasz & 1;
00155 
00156       if (currentsz < 8)
00157      currentsz = dmasz;
00158 
00159       for (j = start; j < count; j += nr ) {
00160      nr = MIN2( currentsz, count - j );
00161      TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
00162      currentsz = dmasz;
00163       }
00164 
00165    } else {
00166       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00167       return;
00168    }
00169 }
00170 
00171 
00172 static void TAG(render_line_strip_verts)( GLcontext *ctx,
00173                       GLuint start,
00174                       GLuint count,
00175                       GLuint flags )
00176 {
00177    if (HAVE_LINE_STRIPS) {
00178       LOCAL_VARS;
00179       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
00180       int currentsz;
00181       GLuint j, nr;
00182 
00183       INIT( GL_LINE_STRIP );
00184 
00185       currentsz = GET_CURRENT_VB_MAX_VERTS();
00186       if (currentsz < 8)
00187      currentsz = dmasz;
00188 
00189       for (j = start; j + 1 < count; j += nr - 1 ) {
00190      nr = MIN2( currentsz, count - j );
00191      TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
00192      currentsz = dmasz;
00193       }
00194  
00195       FLUSH();
00196 
00197    } else {
00198       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00199       return;
00200    }
00201 }
00202 
00203 
00204 static void TAG(render_line_loop_verts)( GLcontext *ctx,
00205                      GLuint start,
00206                      GLuint count,
00207                      GLuint flags )
00208 {
00209    if (HAVE_LINE_STRIPS) {
00210       LOCAL_VARS;
00211       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
00212       int currentsz;
00213       GLuint j, nr;
00214 
00215       INIT( GL_LINE_STRIP );
00216 
00217       if (flags & PRIM_BEGIN)
00218      j = start;
00219       else
00220      j = start + 1;
00221 
00222       /* Ensure last vertex won't wrap buffers:
00223        */
00224       currentsz = GET_CURRENT_VB_MAX_VERTS();
00225       currentsz--;
00226       dmasz--;
00227 
00228       if (currentsz < 8) {
00229      currentsz = dmasz;
00230       }
00231 
00232       if (j + 1 < count) {
00233      for ( ; j + 1 < count; j += nr - 1 ) {
00234         nr = MIN2( currentsz, count - j );
00235 
00236         if (j + nr >= count &&
00237         start < count - 1 && 
00238         (flags & PRIM_END)) 
00239         {
00240            void *tmp;
00241            tmp = ALLOC_VERTS(nr+1);
00242            tmp = TAG(emit_verts)( ctx, j, nr, tmp );
00243            tmp = TAG(emit_verts)( ctx, start, 1, tmp );
00244         }
00245         else {
00246            TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
00247            currentsz = dmasz;
00248         }
00249      }
00250 
00251       }
00252       else if (start + 1 < count && (flags & PRIM_END)) {
00253      void *tmp;
00254      tmp = ALLOC_VERTS(2);
00255      tmp = TAG(emit_verts)( ctx, start+1, 1, tmp );
00256      tmp = TAG(emit_verts)( ctx, start, 1, tmp );
00257       }
00258 
00259       FLUSH();
00260 
00261    } else {
00262       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00263       return;
00264    }
00265 }
00266 
00267 
00268 static void TAG(render_triangles_verts)( GLcontext *ctx,
00269                      GLuint start,
00270                      GLuint count,
00271                      GLuint flags )
00272 {
00273    LOCAL_VARS;
00274    int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/3) * 3;
00275    int currentsz;
00276    GLuint j, nr;
00277 
00278    INIT(GL_TRIANGLES);
00279 
00280    currentsz = (GET_CURRENT_VB_MAX_VERTS()/3) * 3;
00281 
00282    /* Emit whole number of tris in total.  dmasz is already a multiple
00283     * of 3.
00284     */
00285    count -= (count-start)%3;
00286 
00287    if (currentsz < 8)
00288       currentsz = dmasz;
00289 
00290    for (j = start; j < count; j += nr) {
00291       nr = MIN2( currentsz, count - j );
00292       TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
00293       currentsz = dmasz;
00294    }
00295 }
00296 
00297 
00298 
00299 static void TAG(render_tri_strip_verts)( GLcontext *ctx,
00300                      GLuint start,
00301                      GLuint count,
00302                      GLuint flags )
00303 {
00304    if (HAVE_TRI_STRIPS) {
00305       LOCAL_VARS;
00306       GLuint j, nr;
00307       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
00308       int currentsz;
00309 
00310       INIT(GL_TRIANGLE_STRIP);
00311 
00312       currentsz = GET_CURRENT_VB_MAX_VERTS();
00313 
00314       if (currentsz < 8) {
00315      currentsz = dmasz;
00316       }
00317 
00318       /* From here on emit even numbers of tris when wrapping over buffers:
00319        */
00320       dmasz -= (dmasz & 1);
00321       currentsz -= (currentsz & 1);
00322 
00323       for (j = start ; j + 2 < count; j += nr - 2 ) {
00324      nr = MIN2( currentsz, count - j );
00325      TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
00326      currentsz = dmasz;
00327       }
00328 
00329       FLUSH();
00330 
00331    } else {
00332       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00333       return;
00334    }
00335 }
00336 
00337 static void TAG(render_tri_fan_verts)( GLcontext *ctx,
00338                        GLuint start,
00339                        GLuint count,
00340                        GLuint flags )
00341 {
00342    if (HAVE_TRI_FANS) {
00343       LOCAL_VARS;
00344       GLuint j, nr;
00345       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
00346       int currentsz;
00347 
00348       INIT(GL_TRIANGLE_FAN);
00349 
00350       currentsz = GET_CURRENT_VB_MAX_VERTS();
00351       if (currentsz < 8) {
00352      currentsz = dmasz;
00353       }
00354 
00355       for (j = start + 1 ; j + 1 < count; j += nr - 2 ) {
00356      void *tmp;
00357      nr = MIN2( currentsz, count - j + 1 );
00358      tmp = ALLOC_VERTS( nr );
00359      tmp = TAG(emit_verts)( ctx, start, 1, tmp );
00360      tmp = TAG(emit_verts)( ctx, j, nr - 1, tmp );
00361      currentsz = dmasz;
00362       }
00363 
00364       FLUSH();
00365    }
00366    else {
00367       /* Could write code to emit these as indexed vertices (for the
00368        * g400, for instance).
00369        */
00370       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00371       return;
00372    }
00373 }
00374 
00375 
00376 static void TAG(render_poly_verts)( GLcontext *ctx,
00377                     GLuint start,
00378                     GLuint count,
00379                     GLuint flags )
00380 {
00381    if (HAVE_POLYGONS) {
00382       LOCAL_VARS;
00383       GLuint j, nr;
00384       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
00385       int currentsz;
00386 
00387       INIT(GL_POLYGON);
00388 
00389       currentsz = GET_CURRENT_VB_MAX_VERTS();
00390       if (currentsz < 8) {
00391      currentsz = dmasz;
00392       }
00393 
00394       for (j = start + 1 ; j + 1 < count ; j += nr - 2 ) {
00395      void *tmp;
00396      nr = MIN2( currentsz, count - j + 1 );
00397      tmp = ALLOC_VERTS( nr );
00398      tmp = TAG(emit_verts)( ctx, start, 1, tmp );
00399      tmp = TAG(emit_verts)( ctx, j, nr - 1, tmp );
00400      currentsz = dmasz;
00401       }
00402 
00403       FLUSH();
00404    }
00405    else if (HAVE_TRI_FANS && ctx->Light.ShadeModel == GL_SMOOTH) {
00406       TAG(render_tri_fan_verts)( ctx, start, count, flags );
00407    } else {
00408       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00409       return;
00410    }
00411 }
00412 
00413 static void TAG(render_quad_strip_verts)( GLcontext *ctx,
00414                       GLuint start,
00415                       GLuint count,
00416                       GLuint flags )
00417 {
00418    GLuint j, nr;
00419 
00420    if (HAVE_QUAD_STRIPS) {
00421       LOCAL_VARS;
00422       GLuint j, nr;
00423       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
00424       int currentsz;
00425 
00426       INIT(GL_QUAD_STRIP);
00427 
00428       currentsz = GET_CURRENT_VB_MAX_VERTS();
00429       if (currentsz < 8) {
00430      currentsz = dmasz;
00431       }
00432 
00433       dmasz -= (dmasz & 2);
00434       currentsz -= (currentsz & 2);
00435 
00436       for (j = start ; j + 3 < count; j += nr - 2 ) {
00437      nr = MIN2( currentsz, count - j );
00438      TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
00439      currentsz = dmasz;
00440       }
00441 
00442       FLUSH();
00443 
00444    } else if (HAVE_TRI_STRIPS && 
00445           ctx->Light.ShadeModel == GL_FLAT &&
00446           TNL_CONTEXT(ctx)->vb.ColorPtr[0]->stride) {
00447       if (HAVE_ELTS) {
00448      LOCAL_VARS;
00449      int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
00450      int currentsz;
00451      GLuint j, nr;
00452 
00453          EMIT_INDEXED_VERTS( ctx, start, count );
00454 
00455      /* Simulate flat-shaded quadstrips using indexed vertices:
00456       */
00457      ELT_INIT( GL_TRIANGLES );
00458 
00459      currentsz = GET_CURRENT_VB_MAX_ELTS();
00460 
00461      /* Emit whole number of quads in total, and in each buffer.
00462       */
00463      dmasz -= dmasz & 1;
00464      count -= (count-start) & 1;
00465      currentsz -= currentsz & 1;
00466 
00467      if (currentsz < 12)
00468         currentsz = dmasz;
00469 
00470      currentsz = currentsz/6*2;
00471      dmasz = dmasz/6*2;
00472 
00473      for (j = start; j + 3 < count; j += nr - 2 ) {
00474         nr = MIN2( currentsz, count - j );
00475         if (nr >= 4) {
00476            GLint quads = (nr/2)-1;
00477            GLint i;
00478            ELTS_VARS( ALLOC_ELTS( quads*6 ) );
00479 
00480            for ( i = j-start ; i < j-start+quads*2 ; i+=2 ) {
00481           EMIT_TWO_ELTS( 0, (i+0), (i+1) );
00482           EMIT_TWO_ELTS( 2, (i+2), (i+1) );
00483           EMIT_TWO_ELTS( 4, (i+3), (i+2) );
00484           INCR_ELTS( 6 );
00485            }
00486 
00487            FLUSH();
00488         }
00489         currentsz = dmasz;
00490      }
00491 
00492      RELEASE_ELT_VERTS();
00493      FLUSH();
00494       }
00495       else {
00496      /* Vertices won't fit in a single buffer or elts not
00497       * available - should never happen.
00498       */
00499      fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00500      return;
00501       }
00502    }
00503    else if (HAVE_TRI_STRIPS) {
00504       LOCAL_VARS;
00505       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
00506       int currentsz;
00507 
00508       /* Emit smooth-shaded quadstrips as tristrips:
00509        */
00510       FLUSH();
00511       INIT( GL_TRIANGLE_STRIP );
00512 
00513       /* Emit whole number of quads in total, and in each buffer.
00514        */
00515       dmasz -= dmasz & 1;
00516       currentsz = GET_CURRENT_VB_MAX_VERTS();
00517       currentsz -= currentsz & 1;
00518       count -= (count-start) & 1;
00519 
00520       if (currentsz < 8) {
00521      currentsz = dmasz;
00522       }
00523 
00524       for (j = start; j + 3 < count; j += nr - 2 ) {
00525      nr = MIN2( currentsz, count - j );
00526      TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
00527      currentsz = dmasz;
00528       }
00529 
00530       FLUSH();
00531 
00532    } else {
00533       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00534       return;
00535    }
00536 }
00537 
00538 
00539 static void TAG(render_quads_verts)( GLcontext *ctx,
00540                      GLuint start,
00541                      GLuint count,
00542                      GLuint flags )
00543 {
00544    if (HAVE_QUADS) {
00545       LOCAL_VARS;
00546       int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/4) * 4;
00547       int currentsz;
00548       GLuint j, nr;
00549 
00550       INIT(GL_QUADS);
00551 
00552       /* Emit whole number of quads in total.  dmasz is already a multiple
00553        * of 4.
00554        */
00555       count -= (count-start)%4;
00556 
00557       currentsz = (GET_CURRENT_VB_MAX_VERTS()/4) * 4;
00558       if (currentsz < 8)
00559          currentsz = dmasz;
00560 
00561       for (j = start; j < count; j += nr) {
00562          nr = MIN2( currentsz, count - j );
00563          TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
00564          currentsz = dmasz;
00565       }
00566    }
00567    else if (HAVE_ELTS) {
00568       /* Hardware doesn't have a quad primitive type -- try to
00569        * simulate it using indexed vertices and the triangle
00570        * primitive:
00571        */
00572       LOCAL_VARS;
00573       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
00574       int currentsz;
00575       GLuint j, nr;
00576 
00577       EMIT_INDEXED_VERTS( ctx, start, count );
00578 
00579       FLUSH();
00580       ELT_INIT( GL_TRIANGLES );
00581       currentsz = GET_CURRENT_VB_MAX_ELTS();
00582 
00583       /* Emit whole number of quads in total, and in each buffer.
00584        */
00585       dmasz -= dmasz & 3;
00586       count -= (count-start) & 3;
00587       currentsz -= currentsz & 3;
00588 
00589       /* Adjust for rendering as triangles:
00590        */
00591       currentsz = currentsz/6*4;
00592       dmasz = dmasz/6*4;
00593 
00594       if (currentsz < 8)
00595      currentsz = dmasz;
00596 
00597       for (j = start; j < count; j += nr ) {
00598      nr = MIN2( currentsz, count - j );
00599      if (nr >= 4) {
00600         GLint quads = nr/4;
00601         GLint i;
00602         ELTS_VARS( ALLOC_ELTS( quads*6 ) );
00603 
00604         for ( i = j-start ; i < j-start+quads*4 ; i+=4 ) {
00605            EMIT_TWO_ELTS( 0, (i+0), (i+1) );
00606            EMIT_TWO_ELTS( 2, (i+3), (i+1) );
00607            EMIT_TWO_ELTS( 4, (i+2), (i+3) );
00608            INCR_ELTS( 6 );
00609         }
00610 
00611         FLUSH();
00612      }
00613      currentsz = dmasz;
00614       }
00615 
00616       RELEASE_ELT_VERTS();
00617    }
00618    else if (HAVE_TRIANGLES) {
00619       /* Hardware doesn't have a quad primitive type -- try to
00620        * simulate it using triangle primitive.  This is a win for
00621        * gears, but is it useful in the broader world?
00622        */
00623       LOCAL_VARS;
00624       GLuint j;
00625 
00626       INIT(GL_TRIANGLES);
00627 
00628       for (j = start; j < count-3; j += 4) {
00629      void *tmp = ALLOC_VERTS( 6 );
00630      /* Send v0, v1, v3
00631       */
00632      tmp = EMIT_VERTS(ctx, j,     2, tmp);
00633      tmp = EMIT_VERTS(ctx, j + 3, 1, tmp);
00634      /* Send v1, v2, v3
00635       */
00636      tmp = EMIT_VERTS(ctx, j + 1, 3, tmp);
00637       }
00638    }
00639    else {
00640       /* Vertices won't fit in a single buffer, should never happen.
00641        */
00642       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00643       return;
00644    }
00645 }
00646 
00647 static void TAG(render_noop)( GLcontext *ctx,
00648                   GLuint start,
00649                   GLuint count,
00650                   GLuint flags )
00651 {
00652 }
00653 
00654 
00655 
00656 
00657 static tnl_render_func TAG(render_tab_verts)[GL_POLYGON+2] =
00658 {
00659    TAG(render_points_verts),
00660    TAG(render_lines_verts),
00661    TAG(render_line_loop_verts),
00662    TAG(render_line_strip_verts),
00663    TAG(render_triangles_verts),
00664    TAG(render_tri_strip_verts),
00665    TAG(render_tri_fan_verts),
00666    TAG(render_quads_verts),
00667    TAG(render_quad_strip_verts),
00668    TAG(render_poly_verts),
00669    TAG(render_noop),
00670 };
00671 
00672 
00673 /****************************************************************************
00674  *                 Render elts using hardware indexed verts                 *
00675  ****************************************************************************/
00676 
00677 #if (HAVE_ELTS)
00678 static void TAG(render_points_elts)( GLcontext *ctx,
00679                      GLuint start,
00680                      GLuint count,
00681                      GLuint flags )
00682 {
00683    if (HAVE_POINTS) {
00684       LOCAL_VARS;
00685       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
00686       int currentsz;
00687       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
00688       GLuint j, nr;
00689 
00690       ELT_INIT( GL_POINTS );
00691 
00692       currentsz = GET_CURRENT_VB_MAX_ELTS();
00693       if (currentsz < 8)
00694      currentsz = dmasz;
00695 
00696       for (j = start; j < count; j += nr ) {
00697      nr = MIN2( currentsz, count - j );
00698      TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
00699      FLUSH();
00700      currentsz = dmasz;
00701       }
00702    } else {
00703       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00704       return;
00705    }
00706 }
00707 
00708 
00709 
00710 static void TAG(render_lines_elts)( GLcontext *ctx,
00711                     GLuint start,
00712                     GLuint count,
00713                     GLuint flags )
00714 {
00715    if (HAVE_LINES) {
00716       LOCAL_VARS;
00717       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
00718       int currentsz;
00719       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
00720       GLuint j, nr;
00721 
00722       ELT_INIT( GL_LINES );
00723 
00724       /* Emit whole number of lines in total and in each buffer:
00725        */
00726       count -= (count-start) & 1;
00727       currentsz -= currentsz & 1;
00728       dmasz -= dmasz & 1;
00729 
00730       currentsz = GET_CURRENT_VB_MAX_ELTS();
00731       if (currentsz < 8)
00732      currentsz = dmasz;
00733 
00734       for (j = start; j < count; j += nr ) {
00735      nr = MIN2( currentsz, count - j );
00736      TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
00737      FLUSH();
00738      currentsz = dmasz;
00739       }
00740    } else {
00741       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00742       return;
00743    }
00744 }
00745 
00746 
00747 static void TAG(render_line_strip_elts)( GLcontext *ctx,
00748                      GLuint start,
00749                      GLuint count,
00750                      GLuint flags )
00751 {
00752    if (HAVE_LINE_STRIPS) {
00753       LOCAL_VARS;
00754       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
00755       int currentsz;
00756       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
00757       GLuint j, nr;
00758 
00759       FLUSH(); /* always a new primitive */
00760       ELT_INIT( GL_LINE_STRIP );
00761 
00762       currentsz = GET_CURRENT_VB_MAX_ELTS();
00763       if (currentsz < 8)
00764      currentsz = dmasz;
00765 
00766       for (j = start; j + 1 < count; j += nr - 1 ) {
00767      nr = MIN2( currentsz, count - j );
00768      TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
00769      FLUSH();
00770      currentsz = dmasz;
00771       }
00772    } else {
00773       /* TODO: Try to emit as indexed lines.
00774        */
00775       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00776       return;
00777    }
00778 }
00779 
00780 
00781 static void TAG(render_line_loop_elts)( GLcontext *ctx,
00782                     GLuint start,
00783                     GLuint count,
00784                     GLuint flags )
00785 {
00786    if (HAVE_LINE_STRIPS) {
00787       LOCAL_VARS;
00788       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
00789       int currentsz;
00790       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
00791       GLuint j, nr;
00792 
00793       FLUSH();
00794       ELT_INIT( GL_LINE_STRIP );
00795 
00796       if (flags & PRIM_BEGIN)
00797      j = start;
00798       else
00799      j = start + 1;
00800 
00801       currentsz = GET_CURRENT_VB_MAX_ELTS();
00802       if (currentsz < 8) {
00803      currentsz = dmasz;
00804       }
00805 
00806       /* Ensure last vertex doesn't wrap:
00807        */
00808       currentsz--;
00809       dmasz--;
00810 
00811       if (j + 1 < count) {
00812      for ( ; j + 1 < count; j += nr - 1 ) {
00813         nr = MIN2( currentsz, count - j );
00814 
00815         if (j + nr >= count &&
00816         start < count - 1 && 
00817         (flags & PRIM_END)) 
00818         {
00819            void *tmp;
00820            tmp = ALLOC_ELTS(nr+1);
00821            tmp = TAG(emit_elts)( ctx, elts+j, nr, tmp );
00822            tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
00823         }
00824         else {
00825            TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
00826            currentsz = dmasz;
00827         }
00828      }
00829 
00830       }
00831       else if (start + 1 < count && (flags & PRIM_END)) {
00832      void *tmp;
00833      tmp = ALLOC_ELTS(2);
00834      tmp = TAG(emit_elts)( ctx, elts+start+1, 1, tmp );
00835      tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
00836       }
00837 
00838       FLUSH();
00839    } else {
00840       /* TODO: Try to emit as indexed lines */
00841       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00842       return;
00843    }
00844 }
00845 
00846 
00847 /* For verts, we still eliminate the copy from main memory to dma
00848  * buffers.  For elts, this is probably no better (worse?) than the
00849  * standard path.
00850  */
00851 static void TAG(render_triangles_elts)( GLcontext *ctx,
00852                     GLuint start,
00853                     GLuint count,
00854                     GLuint flags )
00855 {
00856    LOCAL_VARS;
00857    GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
00858    int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS()/3*3;
00859    int currentsz;
00860    GLuint j, nr;
00861 
00862    FLUSH();
00863    ELT_INIT( GL_TRIANGLES );
00864 
00865    currentsz = GET_CURRENT_VB_MAX_ELTS();
00866 
00867    /* Emit whole number of tris in total.  dmasz is already a multiple
00868     * of 3.
00869     */
00870    count -= (count-start)%3;
00871    currentsz -= currentsz%3;
00872    if (currentsz < 8)
00873       currentsz = dmasz;
00874 
00875    for (j = start; j < count; j += nr) {
00876       nr = MIN2( currentsz, count - j );
00877       TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
00878       FLUSH();
00879       currentsz = dmasz;
00880    }
00881 }
00882 
00883 
00884 
00885 static void TAG(render_tri_strip_elts)( GLcontext *ctx,
00886                     GLuint start,
00887                     GLuint count,
00888                     GLuint flags )
00889 {
00890    if (HAVE_TRI_STRIPS) {
00891       LOCAL_VARS;
00892       GLuint j, nr;
00893       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
00894       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
00895       int currentsz;
00896 
00897       FLUSH();
00898       ELT_INIT( GL_TRIANGLE_STRIP );
00899 
00900       currentsz = GET_CURRENT_VB_MAX_ELTS();
00901       if (currentsz < 8) {
00902      currentsz = dmasz;
00903       }
00904 
00905       /* Keep the same winding over multiple buffers:
00906        */
00907       dmasz -= (dmasz & 1);
00908       currentsz -= (currentsz & 1);
00909 
00910       for (j = start ; j + 2 < count; j += nr - 2 ) {
00911      nr = MIN2( currentsz, count - j );
00912      TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
00913      FLUSH();
00914      currentsz = dmasz;
00915       }
00916    } else {
00917       /* TODO: try to emit as indexed triangles */
00918       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00919       return;
00920    }
00921 }
00922 
00923 static void TAG(render_tri_fan_elts)( GLcontext *ctx,
00924                       GLuint start,
00925                       GLuint count,
00926                       GLuint flags )
00927 {
00928    if (HAVE_TRI_FANS) {
00929       LOCAL_VARS;
00930       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
00931       GLuint j, nr;
00932       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
00933       int currentsz;
00934 
00935       FLUSH();
00936       ELT_INIT( GL_TRIANGLE_FAN );
00937 
00938       currentsz = GET_CURRENT_VB_MAX_ELTS();
00939       if (currentsz < 8) {
00940      currentsz = dmasz;
00941       }
00942 
00943       for (j = start + 1 ; j + 1 < count; j += nr - 2 ) {
00944      void *tmp;
00945      nr = MIN2( currentsz, count - j + 1 );
00946      tmp = ALLOC_ELTS( nr );
00947      tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
00948      tmp = TAG(emit_elts)( ctx, elts+j, nr - 1, tmp );
00949      FLUSH();
00950      currentsz = dmasz;
00951       }
00952    } else {
00953       /* TODO: try to emit as indexed triangles */
00954       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00955       return;
00956    }
00957 }
00958 
00959 
00960 static void TAG(render_poly_elts)( GLcontext *ctx,
00961                    GLuint start,
00962                    GLuint count,
00963                    GLuint flags )
00964 {
00965    if (HAVE_POLYGONS) {
00966       LOCAL_VARS;
00967       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
00968       GLuint j, nr;
00969       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
00970       int currentsz;
00971 
00972       FLUSH();
00973       ELT_INIT( GL_POLYGON );
00974 
00975       currentsz = GET_CURRENT_VB_MAX_ELTS();
00976       if (currentsz < 8) {
00977      currentsz = dmasz;
00978       }
00979 
00980       for (j = start + 1 ; j + 1 < count; j += nr - 2 ) {
00981      void *tmp;
00982      nr = MIN2( currentsz, count - j + 1 );
00983      tmp = ALLOC_ELTS( nr );
00984      tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
00985      tmp = TAG(emit_elts)( ctx, elts+j, nr - 1, tmp );
00986      FLUSH();
00987      currentsz = dmasz;
00988       }
00989    } else if (HAVE_TRI_FANS && ctx->Light.ShadeModel == GL_SMOOTH) {
00990       TAG(render_tri_fan_verts)( ctx, start, count, flags );
00991    } else {
00992       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
00993       return;
00994    }
00995 }
00996 
00997 static void TAG(render_quad_strip_elts)( GLcontext *ctx,
00998                      GLuint start,
00999                      GLuint count,
01000                      GLuint flags )
01001 {
01002    if (HAVE_QUAD_STRIPS && 0) {
01003    }
01004    else if (HAVE_TRI_STRIPS) {
01005       LOCAL_VARS;
01006       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
01007       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
01008       int currentsz;
01009       GLuint j, nr;
01010 
01011       FLUSH();
01012       currentsz = GET_CURRENT_VB_MAX_ELTS();
01013 
01014       /* Emit whole number of quads in total, and in each buffer.
01015        */
01016       dmasz -= dmasz & 1;
01017       count -= (count-start) & 1;
01018       currentsz -= currentsz & 1;
01019 
01020       if (currentsz < 12)
01021      currentsz = dmasz;
01022 
01023       if (ctx->Light.ShadeModel == GL_FLAT) {
01024      ELT_INIT( GL_TRIANGLES );
01025 
01026      currentsz = currentsz/6*2;
01027      dmasz = dmasz/6*2;
01028 
01029      for (j = start; j + 3 < count; j += nr - 2 ) {
01030         nr = MIN2( currentsz, count - j );
01031 
01032         if (nr >= 4)
01033         {
01034            GLint i;
01035            GLint quads = (nr/2)-1;
01036            ELTS_VARS( ALLOC_ELTS( quads*6 ) );
01037 
01038            for ( i = j-start ; i < j-start+quads ; i++, elts += 2 ) {
01039           EMIT_TWO_ELTS( 0, elts[0], elts[1] );
01040           EMIT_TWO_ELTS( 2, elts[2], elts[1] );
01041           EMIT_TWO_ELTS( 4, elts[3], elts[2] );
01042           INCR_ELTS( 6 );
01043            }
01044 
01045            FLUSH();
01046         }
01047 
01048         currentsz = dmasz;
01049      }
01050       }
01051       else {
01052      ELT_INIT( GL_TRIANGLE_STRIP );
01053 
01054      for (j = start; j + 3 < count; j += nr - 2 ) {
01055         nr = MIN2( currentsz, count - j );
01056         TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
01057         FLUSH();
01058         currentsz = dmasz;
01059      }
01060       }
01061    }
01062 }
01063 
01064 
01065 static void TAG(render_quads_elts)( GLcontext *ctx,
01066                     GLuint start,
01067                     GLuint count,
01068                     GLuint flags )
01069 {
01070    if (HAVE_QUADS) {
01071       LOCAL_VARS;
01072       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
01073       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS()/4*4;
01074       int currentsz;
01075       GLuint j, nr;
01076 
01077       FLUSH();
01078       ELT_INIT( GL_TRIANGLES );
01079 
01080       currentsz = GET_CURRENT_VB_MAX_ELTS()/4*4;
01081 
01082       count -= (count-start)%4;
01083 
01084       if (currentsz < 8)
01085      currentsz = dmasz;
01086 
01087       for (j = start; j < count; j += nr) {
01088      nr = MIN2( currentsz, count - j );
01089      TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
01090      FLUSH();
01091      currentsz = dmasz;
01092       }
01093    } else {
01094       LOCAL_VARS;
01095       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
01096       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
01097       int currentsz;
01098       GLuint j, nr;
01099 
01100       ELT_INIT( GL_TRIANGLES );
01101       currentsz = GET_CURRENT_VB_MAX_ELTS();
01102 
01103       /* Emit whole number of quads in total, and in each buffer.
01104        */
01105       dmasz -= dmasz & 3;
01106       count -= (count-start) & 3;
01107       currentsz -= currentsz & 3;
01108 
01109       /* Adjust for rendering as triangles:
01110        */
01111       currentsz = currentsz/6*4;
01112       dmasz = dmasz/6*4;
01113 
01114       if (currentsz < 8)
01115      currentsz = dmasz;
01116 
01117       for (j = start; j + 3 < count; j += nr - 2 ) {
01118      nr = MIN2( currentsz, count - j );
01119 
01120      if (nr >= 4)
01121      {
01122         GLint quads = nr/4;
01123         GLint i;
01124         ELTS_VARS( ALLOC_ELTS( quads * 6 ) );
01125 
01126         for ( i = j-start ; i < j-start+quads ; i++, elts += 4 ) {
01127            EMIT_TWO_ELTS( 0, elts[0], elts[1] );
01128            EMIT_TWO_ELTS( 2, elts[3], elts[1] );
01129            EMIT_TWO_ELTS( 4, elts[2], elts[3] );
01130            INCR_ELTS( 6 );
01131         }
01132 
01133         FLUSH();
01134      }
01135 
01136      currentsz = dmasz;
01137       }
01138    }
01139 }
01140 
01141 
01142 
01143 static tnl_render_func TAG(render_tab_elts)[GL_POLYGON+2] =
01144 {
01145    TAG(render_points_elts),
01146    TAG(render_lines_elts),
01147    TAG(render_line_loop_elts),
01148    TAG(render_line_strip_elts),
01149    TAG(render_triangles_elts),
01150    TAG(render_tri_strip_elts),
01151    TAG(render_tri_fan_elts),
01152    TAG(render_quads_elts),
01153    TAG(render_quad_strip_elts),
01154    TAG(render_poly_elts),
01155    TAG(render_noop),
01156 };
01157 
01158 
01159 
01160 #endif
01161 
01162 
01163 
01164 /* Pre-check the primitives in the VB to prevent the need for
01165  * fallbacks later on.
01166  */
01167 static GLboolean TAG(validate_render)( GLcontext *ctx,
01168                        struct vertex_buffer *VB )
01169 {
01170    GLint i;
01171 
01172    if (VB->ClipOrMask & ~CLIP_CULL_BIT)
01173       return GL_FALSE;
01174 
01175    if (VB->Elts && !HAVE_ELTS)
01176       return GL_FALSE;
01177 
01178    for (i = 0 ; i < VB->PrimitiveCount ; i++) {
01179       GLuint prim = VB->Primitive[i].mode;
01180       GLuint count = VB->Primitive[i].count;
01181       GLboolean ok = GL_FALSE;
01182 
01183       if (!count)
01184      continue;
01185 
01186       switch (prim & PRIM_MODE_MASK) {
01187       case GL_POINTS:
01188      ok = HAVE_POINTS;
01189      break;
01190       case GL_LINES:
01191      ok = HAVE_LINES && !ctx->Line.StippleFlag;
01192      break;
01193       case GL_LINE_STRIP:
01194      ok = HAVE_LINE_STRIPS && !ctx->Line.StippleFlag;
01195      break;
01196       case GL_LINE_LOOP:
01197      ok = HAVE_LINE_STRIPS && !ctx->Line.StippleFlag;
01198      break;
01199       case GL_TRIANGLES:
01200      ok = HAVE_TRIANGLES;
01201      break;
01202       case GL_TRIANGLE_STRIP:
01203      ok = HAVE_TRI_STRIPS;
01204      break;
01205       case GL_TRIANGLE_FAN:
01206      ok = HAVE_TRI_FANS;
01207      break;
01208       case GL_POLYGON:
01209      if (HAVE_POLYGONS) {
01210         ok = GL_TRUE;
01211      }
01212      else {
01213         ok = (HAVE_TRI_FANS && ctx->Light.ShadeModel == GL_SMOOTH);
01214          }
01215      break;
01216       case GL_QUAD_STRIP:
01217      if (VB->Elts) {
01218         ok = HAVE_TRI_STRIPS;
01219      }
01220      else if (HAVE_QUAD_STRIPS) {
01221         ok = GL_TRUE;
01222      } else if (HAVE_TRI_STRIPS && 
01223             ctx->Light.ShadeModel == GL_FLAT &&
01224             VB->ColorPtr[0]->stride != 0) {
01225         if (HAVE_ELTS) {
01226            ok = (GLint) count < GET_SUBSEQUENT_VB_MAX_ELTS();
01227         }
01228         else {
01229            ok = GL_FALSE;
01230         }
01231      }
01232      else 
01233         ok = HAVE_TRI_STRIPS;
01234      break;
01235       case GL_QUADS:
01236      if (HAVE_QUADS) {
01237         ok = GL_TRUE;
01238      } else if (HAVE_ELTS) {
01239         ok = (GLint) count < GET_SUBSEQUENT_VB_MAX_ELTS();
01240      }
01241      else {
01242         ok = HAVE_TRIANGLES; /* flatshading is ok. */
01243      }
01244      break;
01245       default:
01246      break;
01247       }
01248       
01249       if (!ok) {
01250 /*   fprintf(stderr, "not ok %s\n", _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK)); */
01251      return GL_FALSE;
01252       }
01253    }
01254 
01255    return GL_TRUE;
01256 }
01257 

Generated on Sun May 27 2012 04:20:47 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.