Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Keith Whitwell <keith@tungstengraphics.com>
  26.  */
  27.  
  28.  
  29. /**
  30.  * \file t_dd_dmatmp.h
  31.  * Template for render stages which build and emit vertices directly
  32.  * to fixed-size dma buffers.  Useful for rendering strips and other
  33.  * native primitives where clipping and per-vertex tweaks such as
  34.  * those in t_dd_tritmp.h are not required.
  35.  *
  36.  * Produces code for both inline triangles and indexed triangles.
  37.  * Where various primitive types are unaccelerated by hardware, the
  38.  * code attempts to fallback to other primitive types (quadstrips to
  39.  * tristrips, lineloops to linestrips), or to indexed vertices.
  40.  */
  41.  
  42. #if !defined(HAVE_TRIANGLES)
  43. #error "must have at least triangles to use render template"
  44. #endif
  45.  
  46. #if !HAVE_ELTS
  47. #define ELTS_VARS(buf)
  48. #define ALLOC_ELTS(nr) 0
  49. #define EMIT_ELT( offset, elt )
  50. #define EMIT_TWO_ELTS( offset, elt0, elt1 )
  51. #define INCR_ELTS( nr )
  52. #define ELT_INIT(prim)
  53. #define GET_CURRENT_VB_MAX_ELTS() 0
  54. #define GET_SUBSEQUENT_VB_MAX_ELTS() 0
  55. #define RELEASE_ELT_VERTS()
  56. #define EMIT_INDEXED_VERTS( ctx, start, count )
  57. #endif
  58.  
  59. #ifndef EMIT_TWO_ELTS
  60. #define EMIT_TWO_ELTS( offset, elt0, elt1 )     \
  61. do {                                            \
  62.    EMIT_ELT( offset, elt0 );                    \
  63.    EMIT_ELT( offset+1, elt1 );                  \
  64. } while (0)
  65. #endif
  66.  
  67.  
  68. /**********************************************************************/
  69. /*                  Render whole begin/end objects                    */
  70. /**********************************************************************/
  71.  
  72.  
  73.  
  74.  
  75. #if (HAVE_ELTS)
  76. static void *TAG(emit_elts)( struct gl_context *ctx, GLuint *elts, GLuint nr,
  77.                              void *buf)
  78. {
  79.    GLint i;
  80.    LOCAL_VARS;
  81.    ELTS_VARS(buf);
  82.  
  83.    for ( i = 0 ; i+1 < nr ; i+=2, elts += 2 ) {
  84.       EMIT_TWO_ELTS( 0, elts[0], elts[1] );
  85.       INCR_ELTS( 2 );
  86.    }
  87.    
  88.    if (i < nr) {
  89.       EMIT_ELT( 0, elts[0] );
  90.       INCR_ELTS( 1 );
  91.    }
  92.  
  93.    return (void *)ELTPTR;
  94. }
  95. #endif
  96.  
  97. static __inline void *TAG(emit_verts)( struct gl_context *ctx, GLuint start,
  98.                                      GLuint count, void *buf )
  99. {
  100.    return EMIT_VERTS(ctx, start, count, buf);
  101. }
  102.  
  103. /***********************************************************************
  104.  *                    Render non-indexed primitives.
  105.  ***********************************************************************/
  106.  
  107. static void TAG(render_points_verts)( struct gl_context *ctx,
  108.                                       GLuint start,
  109.                                       GLuint count,
  110.                                       GLuint flags )
  111. {
  112.    if (HAVE_POINTS) {
  113.       LOCAL_VARS;
  114.       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
  115.       int currentsz;
  116.       GLuint j, nr;
  117.  
  118.       INIT( GL_POINTS );
  119.  
  120.       currentsz = GET_CURRENT_VB_MAX_VERTS();
  121.       if (currentsz < 8)
  122.          currentsz = dmasz;
  123.  
  124.       for (j = start; j < count; j += nr ) {
  125.          nr = MIN2( currentsz, count - j );
  126.          TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
  127.          currentsz = dmasz;
  128.       }
  129.  
  130.    } else {
  131.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  132.       return;
  133.    }
  134. }
  135.  
  136. static void TAG(render_lines_verts)( struct gl_context *ctx,
  137.                                      GLuint start,
  138.                                      GLuint count,
  139.                                      GLuint flags )
  140. {
  141.    if (HAVE_LINES) {
  142.       LOCAL_VARS;
  143.       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
  144.       int currentsz;
  145.       GLuint j, nr;
  146.  
  147.       INIT( GL_LINES );
  148.  
  149.       /* Emit whole number of lines in total and in each buffer:
  150.        */
  151.       count -= (count-start) & 1;
  152.       currentsz = GET_CURRENT_VB_MAX_VERTS();
  153.       currentsz -= currentsz & 1;
  154.       dmasz -= dmasz & 1;
  155.  
  156.       if (currentsz < 8)
  157.          currentsz = dmasz;
  158.  
  159.       for (j = start; j < count; j += nr ) {
  160.          nr = MIN2( currentsz, count - j );
  161.          TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
  162.          currentsz = dmasz;
  163.       }
  164.  
  165.    } else {
  166.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  167.       return;
  168.    }
  169. }
  170.  
  171.  
  172. static void TAG(render_line_strip_verts)( struct gl_context *ctx,
  173.                                           GLuint start,
  174.                                           GLuint count,
  175.                                           GLuint flags )
  176. {
  177.    if (HAVE_LINE_STRIPS) {
  178.       LOCAL_VARS;
  179.       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
  180.       int currentsz;
  181.       GLuint j, nr;
  182.  
  183.       INIT( GL_LINE_STRIP );
  184.  
  185.       currentsz = GET_CURRENT_VB_MAX_VERTS();
  186.       if (currentsz < 8)
  187.          currentsz = dmasz;
  188.  
  189.       for (j = start; j + 1 < count; j += nr - 1 ) {
  190.          nr = MIN2( currentsz, count - j );
  191.          TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
  192.          currentsz = dmasz;
  193.       }
  194.  
  195.       FLUSH();
  196.  
  197.    } else {
  198.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  199.       return;
  200.    }
  201. }
  202.  
  203.  
  204. static void TAG(render_line_loop_verts)( struct gl_context *ctx,
  205.                                          GLuint start,
  206.                                          GLuint count,
  207.                                          GLuint flags )
  208. {
  209.    if (HAVE_LINE_STRIPS) {
  210.       LOCAL_VARS;
  211.       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
  212.       int currentsz;
  213.       GLuint j, nr;
  214.  
  215.       INIT( GL_LINE_STRIP );
  216.  
  217.       if (flags & PRIM_BEGIN)
  218.          j = start;
  219.       else
  220.          j = start + 1;
  221.  
  222.       /* Ensure last vertex won't wrap buffers:
  223.        */
  224.       currentsz = GET_CURRENT_VB_MAX_VERTS();
  225.       currentsz--;
  226.       dmasz--;
  227.  
  228.       if (currentsz < 8) {
  229.          currentsz = dmasz;
  230.       }
  231.  
  232.       if (j + 1 < count) {
  233.          for ( ; j + 1 < count; j += nr - 1 ) {
  234.             nr = MIN2( currentsz, count - j );
  235.  
  236.             if (j + nr >= count &&
  237.                 start < count - 1 &&
  238.                 (flags & PRIM_END))
  239.             {
  240.                void *tmp;
  241.                tmp = ALLOC_VERTS(nr+1);
  242.                tmp = TAG(emit_verts)( ctx, j, nr, tmp );
  243.                tmp = TAG(emit_verts)( ctx, start, 1, tmp );
  244.                (void) tmp;
  245.             }
  246.             else {
  247.                TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
  248.                currentsz = dmasz;
  249.             }
  250.          }
  251.  
  252.       }
  253.       else if (start + 1 < count && (flags & PRIM_END)) {
  254.          void *tmp;
  255.          tmp = ALLOC_VERTS(2);
  256.          tmp = TAG(emit_verts)( ctx, start+1, 1, tmp );
  257.          tmp = TAG(emit_verts)( ctx, start, 1, tmp );
  258.          (void) tmp;
  259.       }
  260.  
  261.       FLUSH();
  262.  
  263.    } else {
  264.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  265.       return;
  266.    }
  267. }
  268.  
  269.  
  270. static void TAG(render_triangles_verts)( struct gl_context *ctx,
  271.                                          GLuint start,
  272.                                          GLuint count,
  273.                                          GLuint flags )
  274. {
  275.    LOCAL_VARS;
  276.    int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/3) * 3;
  277.    int currentsz;
  278.    GLuint j, nr;
  279.  
  280.    INIT(GL_TRIANGLES);
  281.  
  282.    currentsz = (GET_CURRENT_VB_MAX_VERTS()/3) * 3;
  283.  
  284.    /* Emit whole number of tris in total.  dmasz is already a multiple
  285.     * of 3.
  286.     */
  287.    count -= (count-start)%3;
  288.  
  289.    if (currentsz < 8)
  290.       currentsz = dmasz;
  291.  
  292.    for (j = start; j < count; j += nr) {
  293.       nr = MIN2( currentsz, count - j );
  294.       TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
  295.       currentsz = dmasz;
  296.    }
  297. }
  298.  
  299.  
  300.  
  301. static void TAG(render_tri_strip_verts)( struct gl_context *ctx,
  302.                                          GLuint start,
  303.                                          GLuint count,
  304.                                          GLuint flags )
  305. {
  306.    if (HAVE_TRI_STRIPS) {
  307.       LOCAL_VARS;
  308.       GLuint j, nr;
  309.       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
  310.       int currentsz;
  311.  
  312.       INIT(GL_TRIANGLE_STRIP);
  313.  
  314.       currentsz = GET_CURRENT_VB_MAX_VERTS();
  315.  
  316.       if (currentsz < 8) {
  317.          currentsz = dmasz;
  318.       }
  319.  
  320.       /* From here on emit even numbers of tris when wrapping over buffers:
  321.        */
  322.       dmasz -= (dmasz & 1);
  323.       currentsz -= (currentsz & 1);
  324.  
  325.       for (j = start ; j + 2 < count; j += nr - 2 ) {
  326.          nr = MIN2( currentsz, count - j );
  327.          TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
  328.          currentsz = dmasz;
  329.       }
  330.  
  331.       FLUSH();
  332.  
  333.    } else {
  334.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  335.       return;
  336.    }
  337. }
  338.  
  339. static void TAG(render_tri_fan_verts)( struct gl_context *ctx,
  340.                                        GLuint start,
  341.                                        GLuint count,
  342.                                        GLuint flags )
  343. {
  344.    if (HAVE_TRI_FANS) {
  345.       LOCAL_VARS;
  346.       GLuint j, nr;
  347.       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
  348.       int currentsz;
  349.  
  350.       INIT(GL_TRIANGLE_FAN);
  351.  
  352.       currentsz = GET_CURRENT_VB_MAX_VERTS();
  353.       if (currentsz < 8) {
  354.          currentsz = dmasz;
  355.       }
  356.  
  357.       for (j = start + 1 ; j + 1 < count; j += nr - 2 ) {
  358.          void *tmp;
  359.          nr = MIN2( currentsz, count - j + 1 );
  360.          tmp = ALLOC_VERTS( nr );
  361.          tmp = TAG(emit_verts)( ctx, start, 1, tmp );
  362.          tmp = TAG(emit_verts)( ctx, j, nr - 1, tmp );
  363.          (void) tmp;
  364.          currentsz = dmasz;
  365.       }
  366.  
  367.       FLUSH();
  368.    }
  369.    else {
  370.       /* Could write code to emit these as indexed vertices (for the
  371.        * g400, for instance).
  372.        */
  373.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  374.       return;
  375.    }
  376. }
  377.  
  378.  
  379. static void TAG(render_poly_verts)( struct gl_context *ctx,
  380.                                     GLuint start,
  381.                                     GLuint count,
  382.                                     GLuint flags )
  383. {
  384.    if (HAVE_POLYGONS) {
  385.       LOCAL_VARS;
  386.       GLuint j, nr;
  387.       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
  388.       int currentsz;
  389.  
  390.       INIT(GL_POLYGON);
  391.  
  392.       currentsz = GET_CURRENT_VB_MAX_VERTS();
  393.       if (currentsz < 8) {
  394.          currentsz = dmasz;
  395.       }
  396.  
  397.       for (j = start + 1 ; j + 1 < count ; j += nr - 2 ) {
  398.          void *tmp;
  399.          nr = MIN2( currentsz, count - j + 1 );
  400.          tmp = ALLOC_VERTS( nr );
  401.          tmp = TAG(emit_verts)( ctx, start, 1, tmp );
  402.          tmp = TAG(emit_verts)( ctx, j, nr - 1, tmp );
  403.          (void) tmp;
  404.          currentsz = dmasz;
  405.       }
  406.  
  407.       FLUSH();
  408.    }
  409.    else if (HAVE_TRI_FANS && ctx->Light.ShadeModel == GL_SMOOTH) {
  410.       TAG(render_tri_fan_verts)( ctx, start, count, flags );
  411.    } else {
  412.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  413.       return;
  414.    }
  415. }
  416.  
  417. static void TAG(render_quad_strip_verts)( struct gl_context *ctx,
  418.                                           GLuint start,
  419.                                           GLuint count,
  420.                                           GLuint flags )
  421. {
  422.    GLuint j, nr;
  423.  
  424.    if (HAVE_QUAD_STRIPS) {
  425.       LOCAL_VARS;
  426.       GLuint j, nr;
  427.       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
  428.       int currentsz;
  429.  
  430.       INIT(GL_QUAD_STRIP);
  431.  
  432.       currentsz = GET_CURRENT_VB_MAX_VERTS();
  433.       if (currentsz < 8) {
  434.          currentsz = dmasz;
  435.       }
  436.  
  437.       dmasz -= (dmasz & 2);
  438.       currentsz -= (currentsz & 2);
  439.  
  440.       for (j = start ; j + 3 < count; j += nr - 2 ) {
  441.          nr = MIN2( currentsz, count - j );
  442.          TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
  443.          currentsz = dmasz;
  444.       }
  445.  
  446.       FLUSH();
  447.  
  448.    } else if (HAVE_TRI_STRIPS &&
  449.               ctx->Light.ShadeModel == GL_FLAT &&
  450.               TNL_CONTEXT(ctx)->vb.AttribPtr[_TNL_ATTRIB_COLOR0]->stride) {
  451.       if (HAVE_ELTS) {
  452.          LOCAL_VARS;
  453.          int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  454.          int currentsz;
  455.          GLuint j, nr;
  456.  
  457.          EMIT_INDEXED_VERTS( ctx, start, count );
  458.  
  459.          /* Simulate flat-shaded quadstrips using indexed vertices:
  460.           */
  461.          ELT_INIT( GL_TRIANGLES );
  462.  
  463.          currentsz = GET_CURRENT_VB_MAX_ELTS();
  464.  
  465.          /* Emit whole number of quads in total, and in each buffer.
  466.           */
  467.          dmasz -= dmasz & 1;
  468.          count -= (count-start) & 1;
  469.          currentsz -= currentsz & 1;
  470.  
  471.          if (currentsz < 12)
  472.             currentsz = dmasz;
  473.  
  474.          currentsz = currentsz/6*2;
  475.          dmasz = dmasz/6*2;
  476.  
  477.          for (j = start; j + 3 < count; j += nr - 2 ) {
  478.             nr = MIN2( currentsz, count - j );
  479.             if (nr >= 4) {
  480.                GLint quads = (nr/2)-1;
  481.                GLint i;
  482.                ELTS_VARS( ALLOC_ELTS( quads*6 ) );
  483.  
  484.                for ( i = j-start ; i < j-start+quads*2 ; i+=2 ) {
  485.                   EMIT_TWO_ELTS( 0, (i+0), (i+1) );
  486.                   EMIT_TWO_ELTS( 2, (i+2), (i+1) );
  487.                   EMIT_TWO_ELTS( 4, (i+3), (i+2) );
  488.                   INCR_ELTS( 6 );
  489.                }
  490.  
  491.                FLUSH();
  492.             }
  493.             currentsz = dmasz;
  494.          }
  495.  
  496.          RELEASE_ELT_VERTS();
  497.          FLUSH();
  498.       }
  499.       else {
  500.          /* Vertices won't fit in a single buffer or elts not
  501.           * available - should never happen.
  502.           */
  503.          fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  504.          return;
  505.       }
  506.    }
  507.    else if (HAVE_TRI_STRIPS) {
  508.       LOCAL_VARS;
  509.       int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
  510.       int currentsz;
  511.  
  512.       /* Emit smooth-shaded quadstrips as tristrips:
  513.        */
  514.       FLUSH();
  515.       INIT( GL_TRIANGLE_STRIP );
  516.  
  517.       /* Emit whole number of quads in total, and in each buffer.
  518.        */
  519.       dmasz -= dmasz & 1;
  520.       currentsz = GET_CURRENT_VB_MAX_VERTS();
  521.       currentsz -= currentsz & 1;
  522.       count -= (count-start) & 1;
  523.  
  524.       if (currentsz < 8) {
  525.          currentsz = dmasz;
  526.       }
  527.  
  528.       for (j = start; j + 3 < count; j += nr - 2 ) {
  529.          nr = MIN2( currentsz, count - j );
  530.          TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
  531.          currentsz = dmasz;
  532.       }
  533.  
  534.       FLUSH();
  535.  
  536.    } else {
  537.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  538.       return;
  539.    }
  540. }
  541.  
  542.  
  543. static void TAG(render_quads_verts)( struct gl_context *ctx,
  544.                                      GLuint start,
  545.                                      GLuint count,
  546.                                      GLuint flags )
  547. {
  548.    if (HAVE_QUADS) {
  549.       LOCAL_VARS;
  550.       int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/4) * 4;
  551.       int currentsz;
  552.       GLuint j, nr;
  553.  
  554.       INIT(GL_QUADS);
  555.  
  556.       /* Emit whole number of quads in total.  dmasz is already a multiple
  557.        * of 4.
  558.        */
  559.       count -= (count-start)%4;
  560.  
  561.       currentsz = (GET_CURRENT_VB_MAX_VERTS()/4) * 4;
  562.       if (currentsz < 8)
  563.          currentsz = dmasz;
  564.  
  565.       for (j = start; j < count; j += nr) {
  566.          nr = MIN2( currentsz, count - j );
  567.          TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
  568.          currentsz = dmasz;
  569.       }
  570.    }
  571.    else if (HAVE_ELTS) {
  572.       /* Hardware doesn't have a quad primitive type -- try to
  573.        * simulate it using indexed vertices and the triangle
  574.        * primitive:
  575.        */
  576.       LOCAL_VARS;
  577.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  578.       int currentsz;
  579.       GLuint j, nr;
  580.  
  581.       EMIT_INDEXED_VERTS( ctx, start, count );
  582.  
  583.       FLUSH();
  584.       ELT_INIT( GL_TRIANGLES );
  585.       currentsz = GET_CURRENT_VB_MAX_ELTS();
  586.  
  587.       /* Emit whole number of quads in total, and in each buffer.
  588.        */
  589.       dmasz -= dmasz & 3;
  590.       count -= (count-start) & 3;
  591.       currentsz -= currentsz & 3;
  592.  
  593.       /* Adjust for rendering as triangles:
  594.        */
  595.       currentsz = currentsz/6*4;
  596.       dmasz = dmasz/6*4;
  597.  
  598.       if (currentsz < 8)
  599.          currentsz = dmasz;
  600.  
  601.       for (j = start; j < count; j += nr ) {
  602.          nr = MIN2( currentsz, count - j );
  603.          if (nr >= 4) {
  604.             GLint quads = nr/4;
  605.             GLint i;
  606.             ELTS_VARS( ALLOC_ELTS( quads*6 ) );
  607.  
  608.             for ( i = j-start ; i < j-start+quads*4 ; i+=4 ) {
  609.                EMIT_TWO_ELTS( 0, (i+0), (i+1) );
  610.                EMIT_TWO_ELTS( 2, (i+3), (i+1) );
  611.                EMIT_TWO_ELTS( 4, (i+2), (i+3) );
  612.                INCR_ELTS( 6 );
  613.             }
  614.  
  615.             FLUSH();
  616.          }
  617.          currentsz = dmasz;
  618.       }
  619.  
  620.       RELEASE_ELT_VERTS();
  621.    }
  622.    else if (HAVE_TRIANGLES) {
  623.       /* Hardware doesn't have a quad primitive type -- try to
  624.        * simulate it using triangle primitive.  This is a win for
  625.        * gears, but is it useful in the broader world?
  626.        */
  627.       LOCAL_VARS;
  628.       GLuint j;
  629.  
  630.       INIT(GL_TRIANGLES);
  631.  
  632.       for (j = start; j < count-3; j += 4) {
  633.          void *tmp = ALLOC_VERTS( 6 );
  634.          /* Send v0, v1, v3
  635.           */
  636.          tmp = EMIT_VERTS(ctx, j,     2, tmp);
  637.          tmp = EMIT_VERTS(ctx, j + 3, 1, tmp);
  638.          /* Send v1, v2, v3
  639.           */
  640.          tmp = EMIT_VERTS(ctx, j + 1, 3, tmp);
  641.          (void) tmp;
  642.       }
  643.    }
  644.    else {
  645.       /* Vertices won't fit in a single buffer, should never happen.
  646.        */
  647.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  648.       return;
  649.    }
  650. }
  651.  
  652. static void TAG(render_noop)( struct gl_context *ctx,
  653.                               GLuint start,
  654.                               GLuint count,
  655.                               GLuint flags )
  656. {
  657. }
  658.  
  659.  
  660.  
  661.  
  662. static tnl_render_func TAG(render_tab_verts)[GL_POLYGON+2] =
  663. {
  664.    TAG(render_points_verts),
  665.    TAG(render_lines_verts),
  666.    TAG(render_line_loop_verts),
  667.    TAG(render_line_strip_verts),
  668.    TAG(render_triangles_verts),
  669.    TAG(render_tri_strip_verts),
  670.    TAG(render_tri_fan_verts),
  671.    TAG(render_quads_verts),
  672.    TAG(render_quad_strip_verts),
  673.    TAG(render_poly_verts),
  674.    TAG(render_noop),
  675. };
  676.  
  677.  
  678. /****************************************************************************
  679.  *                 Render elts using hardware indexed verts                 *
  680.  ****************************************************************************/
  681.  
  682. #if (HAVE_ELTS)
  683. static void TAG(render_points_elts)( struct gl_context *ctx,
  684.                                      GLuint start,
  685.                                      GLuint count,
  686.                                      GLuint flags )
  687. {
  688.    if (HAVE_POINTS) {
  689.       LOCAL_VARS;
  690.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  691.       int currentsz;
  692.       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  693.       GLuint j, nr;
  694.  
  695.       ELT_INIT( GL_POINTS );
  696.  
  697.       currentsz = GET_CURRENT_VB_MAX_ELTS();
  698.       if (currentsz < 8)
  699.          currentsz = dmasz;
  700.  
  701.       for (j = start; j < count; j += nr ) {
  702.          nr = MIN2( currentsz, count - j );
  703.          TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
  704.          FLUSH();
  705.          currentsz = dmasz;
  706.       }
  707.    } else {
  708.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  709.       return;
  710.    }
  711. }
  712.  
  713.  
  714.  
  715. static void TAG(render_lines_elts)( struct gl_context *ctx,
  716.                                     GLuint start,
  717.                                     GLuint count,
  718.                                     GLuint flags )
  719. {
  720.    if (HAVE_LINES) {
  721.       LOCAL_VARS;
  722.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  723.       int currentsz;
  724.       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  725.       GLuint j, nr;
  726.  
  727.       ELT_INIT( GL_LINES );
  728.  
  729.       /* Emit whole number of lines in total and in each buffer:
  730.        */
  731.       count -= (count-start) & 1;
  732.       currentsz -= currentsz & 1;
  733.       dmasz -= dmasz & 1;
  734.  
  735.       currentsz = GET_CURRENT_VB_MAX_ELTS();
  736.       if (currentsz < 8)
  737.          currentsz = dmasz;
  738.  
  739.       for (j = start; j < count; j += nr ) {
  740.          nr = MIN2( currentsz, count - j );
  741.          TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
  742.          FLUSH();
  743.          currentsz = dmasz;
  744.       }
  745.    } else {
  746.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  747.       return;
  748.    }
  749. }
  750.  
  751.  
  752. static void TAG(render_line_strip_elts)( struct gl_context *ctx,
  753.                                          GLuint start,
  754.                                          GLuint count,
  755.                                          GLuint flags )
  756. {
  757.    if (HAVE_LINE_STRIPS) {
  758.       LOCAL_VARS;
  759.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  760.       int currentsz;
  761.       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  762.       GLuint j, nr;
  763.  
  764.       FLUSH(); /* always a new primitive */
  765.       ELT_INIT( GL_LINE_STRIP );
  766.  
  767.       currentsz = GET_CURRENT_VB_MAX_ELTS();
  768.       if (currentsz < 8)
  769.          currentsz = dmasz;
  770.  
  771.       for (j = start; j + 1 < count; j += nr - 1 ) {
  772.          nr = MIN2( currentsz, count - j );
  773.          TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
  774.          FLUSH();
  775.          currentsz = dmasz;
  776.       }
  777.    } else {
  778.       /* TODO: Try to emit as indexed lines.
  779.        */
  780.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  781.       return;
  782.    }
  783. }
  784.  
  785.  
  786. static void TAG(render_line_loop_elts)( struct gl_context *ctx,
  787.                                         GLuint start,
  788.                                         GLuint count,
  789.                                         GLuint flags )
  790. {
  791.    if (HAVE_LINE_STRIPS) {
  792.       LOCAL_VARS;
  793.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  794.       int currentsz;
  795.       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  796.       GLuint j, nr;
  797.  
  798.       FLUSH();
  799.       ELT_INIT( GL_LINE_STRIP );
  800.  
  801.       if (flags & PRIM_BEGIN)
  802.          j = start;
  803.       else
  804.          j = start + 1;
  805.  
  806.       currentsz = GET_CURRENT_VB_MAX_ELTS();
  807.       if (currentsz < 8) {
  808.          currentsz = dmasz;
  809.       }
  810.  
  811.       /* Ensure last vertex doesn't wrap:
  812.        */
  813.       currentsz--;
  814.       dmasz--;
  815.  
  816.       if (j + 1 < count) {
  817.          for ( ; j + 1 < count; j += nr - 1 ) {
  818.             nr = MIN2( currentsz, count - j );
  819.  
  820.             if (j + nr >= count &&
  821.                 start < count - 1 &&
  822.                 (flags & PRIM_END))
  823.             {
  824.                void *tmp;
  825.                tmp = ALLOC_ELTS(nr+1);
  826.                tmp = TAG(emit_elts)( ctx, elts+j, nr, tmp );
  827.                tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
  828.                (void) tmp;
  829.             }
  830.             else {
  831.                TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
  832.                currentsz = dmasz;
  833.             }
  834.          }
  835.  
  836.       }
  837.       else if (start + 1 < count && (flags & PRIM_END)) {
  838.          void *tmp;
  839.          tmp = ALLOC_ELTS(2);
  840.          tmp = TAG(emit_elts)( ctx, elts+start+1, 1, tmp );
  841.          tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
  842.          (void) tmp;
  843.       }
  844.  
  845.       FLUSH();
  846.    } else {
  847.       /* TODO: Try to emit as indexed lines */
  848.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  849.       return;
  850.    }
  851. }
  852.  
  853.  
  854. /* For verts, we still eliminate the copy from main memory to dma
  855.  * buffers.  For elts, this is probably no better (worse?) than the
  856.  * standard path.
  857.  */
  858. static void TAG(render_triangles_elts)( struct gl_context *ctx,
  859.                                         GLuint start,
  860.                                         GLuint count,
  861.                                         GLuint flags )
  862. {
  863.    LOCAL_VARS;
  864.    GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  865.    int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS()/3*3;
  866.    int currentsz;
  867.    GLuint j, nr;
  868.  
  869.    FLUSH();
  870.    ELT_INIT( GL_TRIANGLES );
  871.  
  872.    currentsz = GET_CURRENT_VB_MAX_ELTS();
  873.  
  874.    /* Emit whole number of tris in total.  dmasz is already a multiple
  875.     * of 3.
  876.     */
  877.    count -= (count-start)%3;
  878.    currentsz -= currentsz%3;
  879.    if (currentsz < 8)
  880.       currentsz = dmasz;
  881.  
  882.    for (j = start; j < count; j += nr) {
  883.       nr = MIN2( currentsz, count - j );
  884.       TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
  885.       FLUSH();
  886.       currentsz = dmasz;
  887.    }
  888. }
  889.  
  890.  
  891.  
  892. static void TAG(render_tri_strip_elts)( struct gl_context *ctx,
  893.                                         GLuint start,
  894.                                         GLuint count,
  895.                                         GLuint flags )
  896. {
  897.    if (HAVE_TRI_STRIPS) {
  898.       LOCAL_VARS;
  899.       GLuint j, nr;
  900.       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  901.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  902.       int currentsz;
  903.  
  904.       FLUSH();
  905.       ELT_INIT( GL_TRIANGLE_STRIP );
  906.  
  907.       currentsz = GET_CURRENT_VB_MAX_ELTS();
  908.       if (currentsz < 8) {
  909.          currentsz = dmasz;
  910.       }
  911.  
  912.       /* Keep the same winding over multiple buffers:
  913.        */
  914.       dmasz -= (dmasz & 1);
  915.       currentsz -= (currentsz & 1);
  916.  
  917.       for (j = start ; j + 2 < count; j += nr - 2 ) {
  918.          nr = MIN2( currentsz, count - j );
  919.          TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
  920.          FLUSH();
  921.          currentsz = dmasz;
  922.       }
  923.    } else {
  924.       /* TODO: try to emit as indexed triangles */
  925.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  926.       return;
  927.    }
  928. }
  929.  
  930. static void TAG(render_tri_fan_elts)( struct gl_context *ctx,
  931.                                       GLuint start,
  932.                                       GLuint count,
  933.                                       GLuint flags )
  934. {
  935.    if (HAVE_TRI_FANS) {
  936.       LOCAL_VARS;
  937.       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  938.       GLuint j, nr;
  939.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  940.       int currentsz;
  941.  
  942.       FLUSH();
  943.       ELT_INIT( GL_TRIANGLE_FAN );
  944.  
  945.       currentsz = GET_CURRENT_VB_MAX_ELTS();
  946.       if (currentsz < 8) {
  947.          currentsz = dmasz;
  948.       }
  949.  
  950.       for (j = start + 1 ; j + 1 < count; j += nr - 2 ) {
  951.          void *tmp;
  952.          nr = MIN2( currentsz, count - j + 1 );
  953.          tmp = ALLOC_ELTS( nr );
  954.          tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
  955.          tmp = TAG(emit_elts)( ctx, elts+j, nr - 1, tmp );
  956.          (void) tmp;
  957.          FLUSH();
  958.          currentsz = dmasz;
  959.       }
  960.    } else {
  961.       /* TODO: try to emit as indexed triangles */
  962.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  963.       return;
  964.    }
  965. }
  966.  
  967.  
  968. static void TAG(render_poly_elts)( struct gl_context *ctx,
  969.                                    GLuint start,
  970.                                    GLuint count,
  971.                                    GLuint flags )
  972. {
  973.    if (HAVE_POLYGONS) {
  974.       LOCAL_VARS;
  975.       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  976.       GLuint j, nr;
  977.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  978.       int currentsz;
  979.  
  980.       FLUSH();
  981.       ELT_INIT( GL_POLYGON );
  982.  
  983.       currentsz = GET_CURRENT_VB_MAX_ELTS();
  984.       if (currentsz < 8) {
  985.          currentsz = dmasz;
  986.       }
  987.  
  988.       for (j = start + 1 ; j + 1 < count; j += nr - 2 ) {
  989.          void *tmp;
  990.          nr = MIN2( currentsz, count - j + 1 );
  991.          tmp = ALLOC_ELTS( nr );
  992.          tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
  993.          tmp = TAG(emit_elts)( ctx, elts+j, nr - 1, tmp );
  994.          (void) tmp;
  995.          FLUSH();
  996.          currentsz = dmasz;
  997.       }
  998.    } else if (HAVE_TRI_FANS && ctx->Light.ShadeModel == GL_SMOOTH) {
  999.       TAG(render_tri_fan_verts)( ctx, start, count, flags );
  1000.    } else {
  1001.       fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
  1002.       return;
  1003.    }
  1004. }
  1005.  
  1006. static void TAG(render_quad_strip_elts)( struct gl_context *ctx,
  1007.                                          GLuint start,
  1008.                                          GLuint count,
  1009.                                          GLuint flags )
  1010. {
  1011.    if (HAVE_QUAD_STRIPS && 0) {
  1012.    }
  1013.    else if (HAVE_TRI_STRIPS) {
  1014.       LOCAL_VARS;
  1015.       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  1016.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  1017.       int currentsz;
  1018.       GLuint j, nr;
  1019.  
  1020.       FLUSH();
  1021.       currentsz = GET_CURRENT_VB_MAX_ELTS();
  1022.  
  1023.       /* Emit whole number of quads in total, and in each buffer.
  1024.        */
  1025.       dmasz -= dmasz & 1;
  1026.       count -= (count-start) & 1;
  1027.       currentsz -= currentsz & 1;
  1028.  
  1029.       if (currentsz < 12)
  1030.          currentsz = dmasz;
  1031.  
  1032.       if (ctx->Light.ShadeModel == GL_FLAT) {
  1033.          ELT_INIT( GL_TRIANGLES );
  1034.  
  1035.          currentsz = currentsz/6*2;
  1036.          dmasz = dmasz/6*2;
  1037.  
  1038.          for (j = start; j + 3 < count; j += nr - 2 ) {
  1039.             nr = MIN2( currentsz, count - j );
  1040.  
  1041.             if (nr >= 4)
  1042.             {
  1043.                GLint i;
  1044.                GLint quads = (nr/2)-1;
  1045.                ELTS_VARS( ALLOC_ELTS( quads*6 ) );
  1046.  
  1047.                for ( i = j-start ; i < j-start+quads ; i++, elts += 2 ) {
  1048.                   EMIT_TWO_ELTS( 0, elts[0], elts[1] );
  1049.                   EMIT_TWO_ELTS( 2, elts[2], elts[1] );
  1050.                   EMIT_TWO_ELTS( 4, elts[3], elts[2] );
  1051.                   INCR_ELTS( 6 );
  1052.                }
  1053.  
  1054.                FLUSH();
  1055.             }
  1056.  
  1057.             currentsz = dmasz;
  1058.          }
  1059.       }
  1060.       else {
  1061.          ELT_INIT( GL_TRIANGLE_STRIP );
  1062.  
  1063.          for (j = start; j + 3 < count; j += nr - 2 ) {
  1064.             nr = MIN2( currentsz, count - j );
  1065.             TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
  1066.             FLUSH();
  1067.             currentsz = dmasz;
  1068.          }
  1069.       }
  1070.    }
  1071. }
  1072.  
  1073.  
  1074. static void TAG(render_quads_elts)( struct gl_context *ctx,
  1075.                                     GLuint start,
  1076.                                     GLuint count,
  1077.                                     GLuint flags )
  1078. {
  1079.    if (HAVE_QUADS) {
  1080.       LOCAL_VARS;
  1081.       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  1082.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS()/4*4;
  1083.       int currentsz;
  1084.       GLuint j, nr;
  1085.  
  1086.       FLUSH();
  1087.       ELT_INIT( GL_TRIANGLES );
  1088.  
  1089.       currentsz = GET_CURRENT_VB_MAX_ELTS()/4*4;
  1090.  
  1091.       count -= (count-start)%4;
  1092.  
  1093.       if (currentsz < 8)
  1094.          currentsz = dmasz;
  1095.  
  1096.       for (j = start; j < count; j += nr) {
  1097.          nr = MIN2( currentsz, count - j );
  1098.          TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
  1099.          FLUSH();
  1100.          currentsz = dmasz;
  1101.       }
  1102.    } else {
  1103.       LOCAL_VARS;
  1104.       GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
  1105.       int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
  1106.       int currentsz;
  1107.       GLuint j, nr;
  1108.  
  1109.       ELT_INIT( GL_TRIANGLES );
  1110.       currentsz = GET_CURRENT_VB_MAX_ELTS();
  1111.  
  1112.       /* Emit whole number of quads in total, and in each buffer.
  1113.        */
  1114.       dmasz -= dmasz & 3;
  1115.       count -= (count-start) & 3;
  1116.       currentsz -= currentsz & 3;
  1117.  
  1118.       /* Adjust for rendering as triangles:
  1119.        */
  1120.       currentsz = currentsz/6*4;
  1121.       dmasz = dmasz/6*4;
  1122.  
  1123.       if (currentsz < 8)
  1124.          currentsz = dmasz;
  1125.  
  1126.       for (j = start; j + 3 < count; j += nr - 2 ) {
  1127.          nr = MIN2( currentsz, count - j );
  1128.  
  1129.          if (nr >= 4)
  1130.          {
  1131.             GLint quads = nr/4;
  1132.             GLint i;
  1133.             ELTS_VARS( ALLOC_ELTS( quads * 6 ) );
  1134.  
  1135.             for ( i = j-start ; i < j-start+quads ; i++, elts += 4 ) {
  1136.                EMIT_TWO_ELTS( 0, elts[0], elts[1] );
  1137.                EMIT_TWO_ELTS( 2, elts[3], elts[1] );
  1138.                EMIT_TWO_ELTS( 4, elts[2], elts[3] );
  1139.                INCR_ELTS( 6 );
  1140.             }
  1141.  
  1142.             FLUSH();
  1143.          }
  1144.  
  1145.          currentsz = dmasz;
  1146.       }
  1147.    }
  1148. }
  1149.  
  1150.  
  1151.  
  1152. static tnl_render_func TAG(render_tab_elts)[GL_POLYGON+2] =
  1153. {
  1154.    TAG(render_points_elts),
  1155.    TAG(render_lines_elts),
  1156.    TAG(render_line_loop_elts),
  1157.    TAG(render_line_strip_elts),
  1158.    TAG(render_triangles_elts),
  1159.    TAG(render_tri_strip_elts),
  1160.    TAG(render_tri_fan_elts),
  1161.    TAG(render_quads_elts),
  1162.    TAG(render_quad_strip_elts),
  1163.    TAG(render_poly_elts),
  1164.    TAG(render_noop),
  1165. };
  1166.  
  1167.  
  1168.  
  1169. #endif
  1170.  
  1171.  
  1172.  
  1173. /* Pre-check the primitives in the VB to prevent the need for
  1174.  * fallbacks later on.
  1175.  */
  1176. static GLboolean TAG(validate_render)( struct gl_context *ctx,
  1177.                                        struct vertex_buffer *VB )
  1178. {
  1179.    GLint i;
  1180.  
  1181.    if (VB->ClipOrMask & ~CLIP_CULL_BIT)
  1182.       return GL_FALSE;
  1183.  
  1184.    if (VB->Elts && !HAVE_ELTS)
  1185.       return GL_FALSE;
  1186.  
  1187.    for (i = 0 ; i < VB->PrimitiveCount ; i++) {
  1188.       GLuint prim = VB->Primitive[i].mode;
  1189.       GLuint count = VB->Primitive[i].count;
  1190.       GLboolean ok = GL_FALSE;
  1191.  
  1192.       if (!count)
  1193.          continue;
  1194.  
  1195.       switch (prim & PRIM_MODE_MASK) {
  1196.       case GL_POINTS:
  1197.          ok = HAVE_POINTS;
  1198.          break;
  1199.       case GL_LINES:
  1200.          ok = HAVE_LINES && !ctx->Line.StippleFlag;
  1201.          break;
  1202.       case GL_LINE_STRIP:
  1203.          ok = HAVE_LINE_STRIPS && !ctx->Line.StippleFlag;
  1204.          break;
  1205.       case GL_LINE_LOOP:
  1206.          ok = HAVE_LINE_STRIPS && !ctx->Line.StippleFlag;
  1207.          break;
  1208.       case GL_TRIANGLES:
  1209.          ok = HAVE_TRIANGLES;
  1210.          break;
  1211.       case GL_TRIANGLE_STRIP:
  1212.          ok = HAVE_TRI_STRIPS;
  1213.          break;
  1214.       case GL_TRIANGLE_FAN:
  1215.          ok = HAVE_TRI_FANS;
  1216.          break;
  1217.       case GL_POLYGON:
  1218.          if (HAVE_POLYGONS) {
  1219.             ok = GL_TRUE;
  1220.          }
  1221.          else {
  1222.             ok = (HAVE_TRI_FANS && ctx->Light.ShadeModel == GL_SMOOTH);
  1223.          }
  1224.          break;
  1225.       case GL_QUAD_STRIP:
  1226.          if (VB->Elts) {
  1227.             ok = HAVE_TRI_STRIPS;
  1228.          }
  1229.          else if (HAVE_QUAD_STRIPS) {
  1230.             ok = GL_TRUE;
  1231.          } else if (HAVE_TRI_STRIPS &&
  1232.                     ctx->Light.ShadeModel == GL_FLAT &&
  1233.                     VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride != 0) {
  1234.             if (HAVE_ELTS) {
  1235.                ok = (GLint) count < GET_SUBSEQUENT_VB_MAX_ELTS();
  1236.             }
  1237.             else {
  1238.                ok = GL_FALSE;
  1239.             }
  1240.          }
  1241.          else
  1242.             ok = HAVE_TRI_STRIPS;
  1243.          break;
  1244.       case GL_QUADS:
  1245.          if (HAVE_QUADS) {
  1246.             ok = GL_TRUE;
  1247.          } else if (HAVE_ELTS) {
  1248.             ok = (GLint) count < GET_SUBSEQUENT_VB_MAX_ELTS();
  1249.          }
  1250.          else {
  1251.             ok = HAVE_TRIANGLES; /* flatshading is ok. */
  1252.          }
  1253.          break;
  1254.       default:
  1255.          break;
  1256.       }
  1257.      
  1258.       if (!ok) {
  1259. /*       fprintf(stderr, "not ok %s\n", _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK)); */
  1260.          return GL_FALSE;
  1261.       }
  1262.    }
  1263.  
  1264.    return GL_TRUE;
  1265. }
  1266.  
  1267.