Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. /*
  3.  * Copyright 2003 Tungsten Graphics, inc.
  4.  * 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.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  10.  * license, and/or sell copies of the Software, and to permit persons to whom
  11.  * the Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the next
  14.  * paragraph) shall be included in all copies or substantial portions of the
  15.  * Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
  20.  * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  21.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  22.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  23.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Keith Whitwell <keithw@tungstengraphics.com>
  27.  */
  28.  
  29. #include "main/glheader.h"
  30. #include "main/context.h"
  31. #include "main/colormac.h"
  32. #include "main/simple_list.h"
  33. #include "t_context.h"
  34. #include "t_vertex.h"
  35.  
  36.  
  37. #if 0
  38. #define DEBUG_INSERT printf("%s\n", __FUNCTION__)
  39. #else
  40. #define DEBUG_INSERT
  41. #endif
  42.  
  43.  
  44. /*
  45.  * These functions take the NDC coordinates pointed to by 'in', apply the
  46.  * NDC->Viewport mapping and store the results at 'v'.
  47.  */
  48.  
  49. static INLINE void insert_4f_viewport_4( const struct tnl_clipspace_attr *a, GLubyte *v,
  50.                       const GLfloat *in )
  51. {
  52.    GLfloat *out = (GLfloat *)v;
  53.    const GLfloat * const vp = a->vp;
  54.    DEBUG_INSERT;
  55.    out[0] = vp[0] * in[0] + vp[12];
  56.    out[1] = vp[5] * in[1] + vp[13];
  57.    out[2] = vp[10] * in[2] + vp[14];
  58.    out[3] = in[3];
  59. }
  60.  
  61. static INLINE void insert_4f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
  62.                                 const GLfloat *in )
  63. {
  64.    GLfloat *out = (GLfloat *)v;
  65.    const GLfloat * const vp = a->vp;
  66.    DEBUG_INSERT;
  67.    out[0] = vp[0] * in[0] + vp[12];
  68.    out[1] = vp[5] * in[1] + vp[13];
  69.    out[2] = vp[10] * in[2] + vp[14];
  70.    out[3] = 1;
  71. }
  72.  
  73. static INLINE void insert_4f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
  74.                                 const GLfloat *in )
  75. {
  76.    GLfloat *out = (GLfloat *)v;
  77.    const GLfloat * const vp = a->vp;
  78.    DEBUG_INSERT;
  79.    out[0] = vp[0] * in[0] + vp[12];
  80.    out[1] = vp[5] * in[1] + vp[13];
  81.    out[2] = vp[14];
  82.    out[3] = 1;
  83. }
  84.  
  85. static INLINE void insert_4f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  86.                                 const GLfloat *in )
  87. {
  88.    GLfloat *out = (GLfloat *)v;
  89.    const GLfloat * const vp = a->vp;
  90.    DEBUG_INSERT;
  91.    out[0] = vp[0] * in[0] + vp[12];
  92.    out[1] = vp[13];
  93.    out[2] = vp[14];
  94.    out[3] = 1;
  95. }
  96.  
  97. static INLINE void insert_3f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
  98.                                 const GLfloat *in )
  99. {
  100.    GLfloat *out = (GLfloat *)v;
  101.    const GLfloat * const vp = a->vp;
  102.    DEBUG_INSERT;
  103.    out[0] = vp[0] * in[0] + vp[12];
  104.    out[1] = vp[5] * in[1] + vp[13];
  105.    out[2] = vp[10] * in[2] + vp[14];
  106. }
  107.  
  108. static INLINE void insert_3f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
  109.                                 const GLfloat *in )
  110. {
  111.    GLfloat *out = (GLfloat *)v;
  112.    const GLfloat * const vp = a->vp;
  113.    DEBUG_INSERT;
  114.    out[0] = vp[0] * in[0] + vp[12];
  115.    out[1] = vp[5] * in[1] + vp[13];
  116.    out[2] = vp[14];
  117. }
  118.  
  119. static INLINE void insert_3f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  120.                                 const GLfloat *in )
  121. {
  122.    GLfloat *out = (GLfloat *)v;
  123.    const GLfloat * const vp = a->vp;
  124.    DEBUG_INSERT;
  125.    out[0] = vp[0] * in[0] + vp[12];
  126.    out[1] = vp[13];
  127.    out[2] = vp[14];
  128. }
  129.  
  130. static INLINE void insert_2f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
  131.                                 const GLfloat *in )
  132. {
  133.    GLfloat *out = (GLfloat *)v;
  134.    const GLfloat * const vp = a->vp;
  135.    DEBUG_INSERT;
  136.    out[0] = vp[0] * in[0] + vp[12];
  137.    out[1] = vp[5] * in[1] + vp[13];
  138. }
  139.  
  140. static INLINE void insert_2f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  141.                                 const GLfloat *in )
  142. {
  143.    GLfloat *out = (GLfloat *)v;
  144.    const GLfloat * const vp = a->vp;
  145.    DEBUG_INSERT;
  146.    out[0] = vp[0] * in[0] + vp[12];
  147.    out[1] = vp[13];
  148. }
  149.  
  150.  
  151. /*
  152.  * These functions do the same as above, except for the viewport mapping.
  153.  */
  154.  
  155. static INLINE void insert_4f_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  156. {
  157.    GLfloat *out = (GLfloat *)(v);
  158.    (void) a;
  159.    DEBUG_INSERT;
  160.    out[0] = in[0];
  161.    out[1] = in[1];
  162.    out[2] = in[2];
  163.    out[3] = in[3];
  164. }
  165.  
  166. static INLINE void insert_4f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  167. {
  168.    GLfloat *out = (GLfloat *)(v);
  169.    (void) a;
  170.    DEBUG_INSERT;
  171.    out[0] = in[0];
  172.    out[1] = in[1];
  173.    out[2] = in[2];
  174.    out[3] = 1;
  175. }
  176.  
  177. static INLINE void insert_4f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  178. {
  179.    GLfloat *out = (GLfloat *)(v);
  180.    (void) a;
  181.    DEBUG_INSERT;
  182.    out[0] = in[0];
  183.    out[1] = in[1];
  184.    out[2] = 0;
  185.    out[3] = 1;
  186. }
  187.  
  188. static INLINE void insert_4f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  189. {
  190.    GLfloat *out = (GLfloat *)(v);
  191.    (void) a;
  192.    DEBUG_INSERT;
  193.    out[0] = in[0];
  194.    out[1] = 0;
  195.    out[2] = 0;
  196.    out[3] = 1;
  197. }
  198.  
  199. static INLINE void insert_3f_xyw_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  200. {
  201.    GLfloat *out = (GLfloat *)(v);
  202.    (void) a;
  203.    DEBUG_INSERT;
  204.    out[0] = in[0];
  205.    out[1] = in[1];
  206.    out[2] = in[3];
  207. }
  208.  
  209. static INLINE void insert_3f_xyw_err( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  210. {
  211.    (void) a; (void) v; (void) in;
  212.    DEBUG_INSERT;
  213.    exit(1);
  214. }
  215.  
  216. static INLINE void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  217. {
  218.    GLfloat *out = (GLfloat *)(v);
  219.    (void) a;
  220.    DEBUG_INSERT;
  221.    out[0] = in[0];
  222.    out[1] = in[1];
  223.    out[2] = in[2];
  224. }
  225.  
  226. static INLINE void insert_3f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  227. {
  228.    GLfloat *out = (GLfloat *)(v);
  229.    (void) a;
  230.    DEBUG_INSERT;
  231.    out[0] = in[0];
  232.    out[1] = in[1];
  233.    out[2] = 0;
  234. }
  235.  
  236. static INLINE void insert_3f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  237. {
  238.    GLfloat *out = (GLfloat *)(v);
  239.    (void) a;
  240.    DEBUG_INSERT;
  241.    out[0] = in[0];
  242.    out[1] = 0;
  243.    out[2] = 0;
  244. }
  245.  
  246.  
  247. static INLINE void insert_2f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  248. {
  249.    GLfloat *out = (GLfloat *)(v);
  250.    (void) a;
  251.    DEBUG_INSERT;
  252.    out[0] = in[0];
  253.    out[1] = in[1];
  254. }
  255.  
  256. static INLINE void insert_2f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  257. {
  258.    GLfloat *out = (GLfloat *)(v);
  259.    (void) a;
  260.    DEBUG_INSERT;
  261.    out[0] = in[0];
  262.    out[1] = 0;
  263. }
  264.  
  265. static INLINE void insert_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  266. {
  267.    GLfloat *out = (GLfloat *)(v);
  268.    (void) a;
  269.    DEBUG_INSERT;
  270.    out[0] = in[0];
  271. }
  272.  
  273. static INLINE void insert_null( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
  274. {
  275.    DEBUG_INSERT;
  276.    (void) a; (void) v; (void) in;
  277. }
  278.  
  279. static INLINE void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
  280.                                   const GLfloat *in )
  281. {
  282.    GLchan *c = (GLchan *)v;
  283.    DEBUG_INSERT;
  284.    (void) a;
  285.    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
  286.    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
  287.    UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
  288.    UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
  289. }
  290.  
  291. static INLINE void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
  292.                                   const GLfloat *in )
  293. {
  294.    GLchan *c = (GLchan *)v;
  295.    DEBUG_INSERT;
  296.    (void) a;
  297.    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
  298.    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
  299.    UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
  300.    c[3] = CHAN_MAX;
  301. }
  302.  
  303. static INLINE void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
  304.                                   const GLfloat *in )
  305. {
  306.    GLchan *c = (GLchan *)v;
  307.    DEBUG_INSERT;
  308.    (void) a;
  309.    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
  310.    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
  311.    c[2] = 0;
  312.    c[3] = CHAN_MAX;
  313. }
  314.  
  315. static INLINE void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  316.                                   const GLfloat *in )
  317. {
  318.    GLchan *c = (GLchan *)v;
  319.    DEBUG_INSERT;
  320.    (void) a;
  321.    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
  322.    c[1] = 0;
  323.    c[2] = 0;
  324.    c[3] = CHAN_MAX;
  325. }
  326.  
  327. static INLINE void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
  328.                                 const GLfloat *in )
  329. {
  330.    DEBUG_INSERT;
  331.    (void) a;
  332.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
  333.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
  334.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
  335.    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
  336. }
  337.  
  338. static INLINE void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
  339.                                 const GLfloat *in )
  340. {
  341.    DEBUG_INSERT;
  342.    (void) a;
  343.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
  344.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
  345.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
  346.    v[3] = 0xff;
  347. }
  348.  
  349. static INLINE void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
  350.                                 const GLfloat *in )
  351. {
  352.    DEBUG_INSERT;
  353.    (void) a;
  354.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
  355.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
  356.    v[2] = 0;
  357.    v[3] = 0xff;
  358. }
  359.  
  360. static INLINE void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  361.                                 const GLfloat *in )
  362. {
  363.    DEBUG_INSERT;
  364.    (void) a;
  365.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
  366.    v[1] = 0;
  367.    v[2] = 0;
  368.    v[3] = 0xff;
  369. }
  370.  
  371. static INLINE void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr *a, GLubyte *v,
  372.                                 const GLfloat *in )
  373. {
  374.    DEBUG_INSERT;
  375.    (void) a;
  376.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
  377.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
  378.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
  379.    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
  380. }
  381.  
  382. static INLINE void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr *a, GLubyte *v,
  383.                                 const GLfloat *in )
  384. {
  385.    DEBUG_INSERT;
  386.    (void) a;
  387.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
  388.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
  389.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
  390.    v[3] = 0xff;
  391. }
  392.  
  393. static INLINE void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr *a, GLubyte *v,
  394.                                 const GLfloat *in )
  395. {
  396.    DEBUG_INSERT;
  397.    (void) a;
  398.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
  399.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
  400.    v[0] = 0;
  401.    v[3] = 0xff;
  402. }
  403.  
  404. static INLINE void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  405.                                 const GLfloat *in )
  406. {
  407.    DEBUG_INSERT;
  408.    (void) a;
  409.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
  410.    v[1] = 0;
  411.    v[0] = 0;
  412.    v[3] = 0xff;
  413. }
  414.  
  415. static INLINE void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr *a, GLubyte *v,
  416.                                 const GLfloat *in )
  417. {
  418.    DEBUG_INSERT;
  419.    (void) a;
  420.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
  421.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
  422.    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
  423.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
  424. }
  425.  
  426. static INLINE void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr *a, GLubyte *v,
  427.                                 const GLfloat *in )
  428. {
  429.    DEBUG_INSERT;
  430.    (void) a;
  431.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
  432.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
  433.    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
  434.    v[0] = 0xff;
  435. }
  436.  
  437. static INLINE void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr *a, GLubyte *v,
  438.                                 const GLfloat *in )
  439. {
  440.    DEBUG_INSERT;
  441.    (void) a;
  442.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
  443.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
  444.    v[3] = 0x00;
  445.    v[0] = 0xff;
  446. }
  447.  
  448. static INLINE void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  449.                                 const GLfloat *in )
  450. {
  451.    DEBUG_INSERT;
  452.    (void) a;
  453.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
  454.    v[2] = 0x00;
  455.    v[3] = 0x00;
  456.    v[0] = 0xff;
  457. }
  458.  
  459. static INLINE void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr *a, GLubyte *v,
  460.                                 const GLfloat *in )
  461. {
  462.    DEBUG_INSERT;
  463.    (void) a;
  464.    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
  465.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
  466.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
  467.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
  468. }
  469.  
  470. static INLINE void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr *a, GLubyte *v,
  471.                                 const GLfloat *in )
  472. {
  473.    DEBUG_INSERT;
  474.    (void) a;
  475.    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
  476.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
  477.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
  478.    v[0] = 0xff;
  479. }
  480.  
  481. static INLINE void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr *a, GLubyte *v,
  482.                                 const GLfloat *in )
  483. {
  484.    DEBUG_INSERT;
  485.    (void) a;
  486.    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
  487.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
  488.    v[1] = 0x00;
  489.    v[0] = 0xff;
  490. }
  491.  
  492. static INLINE void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  493.                                 const GLfloat *in )
  494. {
  495.    DEBUG_INSERT;
  496.    (void) a;
  497.    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
  498.    v[2] = 0x00;
  499.    v[1] = 0x00;
  500.    v[0] = 0xff;
  501. }
  502.  
  503. static INLINE void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr *a, GLubyte *v,
  504.                                const GLfloat *in )
  505. {
  506.    DEBUG_INSERT;
  507.    (void) a;
  508.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
  509.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
  510.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
  511. }
  512.  
  513. static INLINE void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr *a, GLubyte *v,
  514.                                const GLfloat *in )
  515. {
  516.    DEBUG_INSERT;
  517.    (void) a;
  518.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
  519.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
  520.    v[2] = 0;
  521. }
  522.  
  523. static INLINE void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  524.                                const GLfloat *in )
  525. {
  526.    DEBUG_INSERT;
  527.    (void) a;
  528.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
  529.    v[1] = 0;
  530.    v[2] = 0;
  531. }
  532.  
  533. static INLINE void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v,
  534.                                  const GLfloat *in )
  535. {
  536.    DEBUG_INSERT;
  537.    (void) a;
  538.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
  539.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
  540.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
  541. }
  542.  
  543. static INLINE void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v,
  544.                                  const GLfloat *in )
  545. {
  546.    DEBUG_INSERT;
  547.    (void) a;
  548.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
  549.    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
  550.    v[0] = 0;
  551. }
  552.  
  553. static INLINE void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  554.                                  const GLfloat *in )
  555. {
  556.    DEBUG_INSERT;
  557.    (void) a;
  558.    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
  559.    v[1] = 0;
  560.    v[0] = 0;
  561. }
  562.  
  563.  
  564. static INLINE void insert_1ub_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v,
  565.                            const GLfloat *in )
  566. {
  567.    DEBUG_INSERT;
  568.    (void) a;
  569.    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
  570. }
  571.  
  572.  
  573. /***********************************************************************
  574.  * Functions to perform the reverse operations to the above, for
  575.  * swrast translation and clip-interpolation.
  576.  *
  577.  * Currently always extracts a full 4 floats.
  578.  */
  579.  
  580. static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
  581.                                  const GLubyte *v )
  582. {
  583.    const GLfloat *in = (const GLfloat *)v;
  584.    const GLfloat * const vp = a->vp;
  585.    
  586.    /* Although included for completeness, the position coordinate is
  587.     * usually handled differently during clipping.
  588.     */
  589.    DEBUG_INSERT;
  590.    out[0] = (in[0] - vp[12]) / vp[0];
  591.    out[1] = (in[1] - vp[13]) / vp[5];
  592.    out[2] = (in[2] - vp[14]) / vp[10];
  593.    out[3] = in[3];
  594. }
  595.  
  596. static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
  597.                                  const GLubyte *v )
  598. {
  599.    const GLfloat *in = (const GLfloat *)v;
  600.    const GLfloat * const vp = a->vp;
  601.    DEBUG_INSERT;
  602.    out[0] = (in[0] - vp[12]) / vp[0];
  603.    out[1] = (in[1] - vp[13]) / vp[5];
  604.    out[2] = (in[2] - vp[14]) / vp[10];
  605.    out[3] = 1;
  606. }
  607.  
  608.  
  609. static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
  610.                                  const GLubyte *v )
  611. {
  612.    const GLfloat *in = (const GLfloat *)v;
  613.    const GLfloat * const vp = a->vp;
  614.    DEBUG_INSERT;
  615.    out[0] = (in[0] - vp[12]) / vp[0];
  616.    out[1] = (in[1] - vp[13]) / vp[5];
  617.    out[2] = 0;
  618.    out[3] = 1;
  619. }
  620.  
  621.  
  622. static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v  )
  623. {
  624.    const GLfloat *in = (const GLfloat *)v;
  625.    (void) a;
  626.    
  627.    out[0] = in[0];
  628.    out[1] = in[1];
  629.    out[2] = in[2];
  630.    out[3] = in[3];
  631. }
  632.  
  633. static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
  634. {
  635.    const GLfloat *in = (const GLfloat *)v;
  636.    (void) a;
  637.    
  638.    out[0] = in[0];
  639.    out[1] = in[1];
  640.    out[2] = 0;
  641.    out[3] = in[2];
  642. }
  643.  
  644.  
  645. static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
  646. {
  647.    const GLfloat *in = (const GLfloat *)v;
  648.    (void) a;
  649.    
  650.    out[0] = in[0];
  651.    out[1] = in[1];
  652.    out[2] = in[2];
  653.    out[3] = 1;
  654. }
  655.  
  656.  
  657. static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
  658. {
  659.    const GLfloat *in = (const GLfloat *)v;
  660.    (void) a;
  661.    
  662.    out[0] = in[0];
  663.    out[1] = in[1];
  664.    out[2] = 0;
  665.    out[3] = 1;
  666. }
  667.  
  668. static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
  669. {
  670.    const GLfloat *in = (const GLfloat *)v;
  671.    (void) a;
  672.    
  673.    out[0] = in[0];
  674.    out[1] = 0;
  675.    out[2] = 0;
  676.    out[3] = 1;
  677. }
  678.  
  679. static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
  680.                                  const GLubyte *v )
  681. {
  682.    GLchan *c = (GLchan *)v;
  683.    (void) a;
  684.  
  685.    out[0] = CHAN_TO_FLOAT(c[0]);
  686.    out[1] = CHAN_TO_FLOAT(c[1]);
  687.    out[2] = CHAN_TO_FLOAT(c[2]);
  688.    out[3] = CHAN_TO_FLOAT(c[3]);
  689. }
  690.  
  691. static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
  692.                                  const GLubyte *v )
  693. {
  694.    (void) a;
  695.    out[0] = UBYTE_TO_FLOAT(v[0]);
  696.    out[1] = UBYTE_TO_FLOAT(v[1]);
  697.    out[2] = UBYTE_TO_FLOAT(v[2]);
  698.    out[3] = UBYTE_TO_FLOAT(v[3]);
  699. }
  700.  
  701. static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out,
  702.                                  const GLubyte *v )
  703. {
  704.    (void) a;
  705.    out[2] = UBYTE_TO_FLOAT(v[0]);
  706.    out[1] = UBYTE_TO_FLOAT(v[1]);
  707.    out[0] = UBYTE_TO_FLOAT(v[2]);
  708.    out[3] = UBYTE_TO_FLOAT(v[3]);
  709. }
  710.  
  711. static void extract_4ub_4f_argb( const struct tnl_clipspace_attr *a, GLfloat *out,
  712.                                  const GLubyte *v )
  713. {
  714.    (void) a;
  715.    out[3] = UBYTE_TO_FLOAT(v[0]);
  716.    out[0] = UBYTE_TO_FLOAT(v[1]);
  717.    out[1] = UBYTE_TO_FLOAT(v[2]);
  718.    out[2] = UBYTE_TO_FLOAT(v[3]);
  719. }
  720.  
  721. static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr *a, GLfloat *out,
  722.                                  const GLubyte *v )
  723. {
  724.    (void) a;
  725.    out[3] = UBYTE_TO_FLOAT(v[0]);
  726.    out[2] = UBYTE_TO_FLOAT(v[1]);
  727.    out[1] = UBYTE_TO_FLOAT(v[2]);
  728.    out[0] = UBYTE_TO_FLOAT(v[3]);
  729. }
  730.  
  731. static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out,
  732.                                 const GLubyte *v )
  733. {
  734.    (void) a;
  735.    out[0] = UBYTE_TO_FLOAT(v[0]);
  736.    out[1] = UBYTE_TO_FLOAT(v[1]);
  737.    out[2] = UBYTE_TO_FLOAT(v[2]);
  738.    out[3] = 1;
  739. }
  740.  
  741. static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out,
  742.                                 const GLubyte *v )
  743. {
  744.    (void) a;
  745.    out[2] = UBYTE_TO_FLOAT(v[0]);
  746.    out[1] = UBYTE_TO_FLOAT(v[1]);
  747.    out[0] = UBYTE_TO_FLOAT(v[2]);
  748.    out[3] = 1;
  749. }
  750.  
  751. static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
  752. {
  753.    (void) a;
  754.    out[0] = UBYTE_TO_FLOAT(v[0]);
  755.    out[1] = 0;
  756.    out[2] = 0;
  757.    out[3] = 1;
  758. }
  759.  
  760.  
  761. const struct tnl_format_info _tnl_format_info[EMIT_MAX] =
  762. {
  763.    { "1f",
  764.      extract_1f,
  765.      { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
  766.      sizeof(GLfloat) },
  767.  
  768.    { "2f",
  769.      extract_2f,
  770.      { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
  771.      2 * sizeof(GLfloat) },
  772.  
  773.    { "3f",
  774.      extract_3f,
  775.      { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
  776.      3 * sizeof(GLfloat) },
  777.  
  778.    { "4f",
  779.      extract_4f,
  780.      { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
  781.      4 * sizeof(GLfloat) },
  782.  
  783.    { "2f_viewport",
  784.      extract_2f_viewport,
  785.      { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2,
  786.        insert_2f_viewport_2 },
  787.      2 * sizeof(GLfloat) },
  788.  
  789.    { "3f_viewport",
  790.      extract_3f_viewport,
  791.      { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3,
  792.        insert_3f_viewport_3 },
  793.      3 * sizeof(GLfloat) },
  794.  
  795.    { "4f_viewport",
  796.      extract_4f_viewport,
  797.      { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3,
  798.        insert_4f_viewport_4 },
  799.      4 * sizeof(GLfloat) },
  800.  
  801.    { "3f_xyw",
  802.      extract_3f_xyw,
  803.      { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err,
  804.        insert_3f_xyw_4 },
  805.      3 * sizeof(GLfloat) },
  806.  
  807.    { "1ub_1f",
  808.      extract_1ub_1f,
  809.      { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
  810.      sizeof(GLubyte) },
  811.  
  812.    { "3ub_3f_rgb",
  813.      extract_3ub_3f_rgb,
  814.      { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3,
  815.        insert_3ub_3f_rgb_3 },
  816.      3 * sizeof(GLubyte) },
  817.  
  818.    { "3ub_3f_bgr",
  819.      extract_3ub_3f_bgr,
  820.      { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3,
  821.        insert_3ub_3f_bgr_3 },
  822.      3 * sizeof(GLubyte) },
  823.  
  824.    { "4ub_4f_rgba",
  825.      extract_4ub_4f_rgba,
  826.      { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3,
  827.        insert_4ub_4f_rgba_4 },
  828.      4 * sizeof(GLubyte) },
  829.  
  830.    { "4ub_4f_bgra",
  831.      extract_4ub_4f_bgra,
  832.      { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3,
  833.        insert_4ub_4f_bgra_4 },
  834.      4 * sizeof(GLubyte) },
  835.  
  836.    { "4ub_4f_argb",
  837.      extract_4ub_4f_argb,
  838.      { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3,
  839.        insert_4ub_4f_argb_4 },
  840.      4 * sizeof(GLubyte) },
  841.  
  842.    { "4ub_4f_abgr",
  843.      extract_4ub_4f_abgr,
  844.      { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3,
  845.        insert_4ub_4f_abgr_4 },
  846.      4 * sizeof(GLubyte) },
  847.  
  848.    { "4chan_4f_rgba",
  849.      extract_4chan_4f_rgba,
  850.      { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3,
  851.        insert_4chan_4f_rgba_4 },
  852.      4 * sizeof(GLchan) },
  853.  
  854.    { "pad",
  855.      NULL,
  856.      { NULL, NULL, NULL, NULL },
  857.      0 }
  858.  
  859. };
  860.  
  861.  
  862.  
  863.    
  864. /***********************************************************************
  865.  * Hardwired fastpaths for emitting whole vertices or groups of
  866.  * vertices
  867.  */
  868. #define EMIT5(NR, F0, F1, F2, F3, F4, NAME)                             \
  869. static void NAME( struct gl_context *ctx,                                       \
  870.                   GLuint count,                                         \
  871.                   GLubyte *v )                                          \
  872. {                                                                       \
  873.    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);                   \
  874.    struct tnl_clipspace_attr *a = vtx->attr;                            \
  875.    GLuint i;                                                            \
  876.                                                                         \
  877.    for (i = 0 ; i < count ; i++, v += vtx->vertex_size) {               \
  878.       if (NR > 0) {                                                     \
  879.          F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr );    \
  880.          a[0].inputptr += a[0].inputstride;                             \
  881.       }                                                                 \
  882.                                                                         \
  883.       if (NR > 1) {                                                     \
  884.          F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr );    \
  885.          a[1].inputptr += a[1].inputstride;                             \
  886.       }                                                                 \
  887.                                                                         \
  888.       if (NR > 2) {                                                     \
  889.          F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr );    \
  890.          a[2].inputptr += a[2].inputstride;                             \
  891.       }                                                                 \
  892.                                                                         \
  893.       if (NR > 3) {                                                     \
  894.          F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr );    \
  895.          a[3].inputptr += a[3].inputstride;                             \
  896.       }                                                                 \
  897.                                                                         \
  898.       if (NR > 4) {                                                     \
  899.          F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr );    \
  900.          a[4].inputptr += a[4].inputstride;                             \
  901.       }                                                                 \
  902.    }                                                                    \
  903. }
  904.  
  905.    
  906. #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
  907.                                   insert_null, insert_null, NAME)
  908.  
  909. #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
  910.                                       insert_null, NAME)
  911.    
  912. #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
  913.                                           insert_null, NAME)
  914.    
  915.  
  916. EMIT2(insert_3f_viewport_3, insert_4ub_4f_rgba_4, emit_viewport3_rgba4)
  917. EMIT2(insert_3f_viewport_3, insert_4ub_4f_bgra_4, emit_viewport3_bgra4)
  918. EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4)
  919.  
  920. EMIT3(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_viewport4_rgba4_st2)
  921. EMIT3(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2,  emit_viewport4_bgra4_st2)
  922. EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2)
  923.  
  924. EMIT4(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_viewport4_rgba4_st2_st2)
  925. EMIT4(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, insert_2f_2,  emit_viewport4_bgra4_st2_st2)
  926. EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2)
  927.  
  928.  
  929. /* Use the codegen paths to select one of a number of hardwired
  930.  * fastpaths.
  931.  */
  932. void _tnl_generate_hardwired_emit( struct gl_context *ctx )
  933. {
  934.    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
  935.    tnl_emit_func func = NULL;
  936.  
  937.    /* Does it fit a hardwired fastpath?  Help! this is growing out of
  938.     * control!
  939.     */
  940.    switch (vtx->attr_count) {
  941.    case 2:
  942.       if (vtx->attr[0].emit == insert_3f_viewport_3) {
  943.          if (vtx->attr[1].emit == insert_4ub_4f_bgra_4)
  944.             func = emit_viewport3_bgra4;
  945.          else if (vtx->attr[1].emit == insert_4ub_4f_rgba_4)
  946.             func = emit_viewport3_rgba4;
  947.       }
  948.       else if (vtx->attr[0].emit == insert_3f_3 &&
  949.                vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
  950.          func = emit_xyz3_rgba4;
  951.       }
  952.       break;
  953.    case 3:
  954.       if (vtx->attr[2].emit == insert_2f_2) {
  955.          if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
  956.             if (vtx->attr[0].emit == insert_4f_viewport_4)
  957.                func = emit_viewport4_rgba4_st2;
  958.             else if (vtx->attr[0].emit == insert_4f_4)
  959.                func = emit_xyzw4_rgba4_st2;
  960.          }
  961.          else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 &&
  962.                   vtx->attr[0].emit == insert_4f_viewport_4)
  963.             func = emit_viewport4_bgra4_st2;
  964.       }
  965.       break;
  966.    case 4:
  967.       if (vtx->attr[2].emit == insert_2f_2 &&
  968.           vtx->attr[3].emit == insert_2f_2) {
  969.          if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
  970.             if (vtx->attr[0].emit == insert_4f_viewport_4)
  971.                func = emit_viewport4_rgba4_st2_st2;
  972.             else if (vtx->attr[0].emit == insert_4f_4)
  973.                func = emit_xyzw4_rgba4_st2_st2;
  974.          }
  975.          else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 &&
  976.                   vtx->attr[0].emit == insert_4f_viewport_4)
  977.             func = emit_viewport4_bgra4_st2_st2;
  978.       }
  979.       break;
  980.    }
  981.  
  982.    vtx->emit = func;
  983. }
  984.  
  985. /***********************************************************************
  986.  * Generic (non-codegen) functions for whole vertices or groups of
  987.  * vertices
  988.  */
  989.  
  990. void _tnl_generic_emit( struct gl_context *ctx,
  991.                         GLuint count,
  992.                         GLubyte *v )
  993. {
  994.    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
  995.    struct tnl_clipspace_attr *a = vtx->attr;
  996.    const GLuint attr_count = vtx->attr_count;
  997.    const GLuint stride = vtx->vertex_size;
  998.    GLuint i, j;
  999.  
  1000.    for (i = 0 ; i < count ; i++, v += stride) {
  1001.       for (j = 0; j < attr_count; j++) {
  1002.          GLfloat *in = (GLfloat *)a[j].inputptr;
  1003.          a[j].inputptr += a[j].inputstride;
  1004.          a[j].emit( &a[j], v + a[j].vertoffset, in );
  1005.       }
  1006.    }
  1007. }
  1008.  
  1009.  
  1010. void _tnl_generic_interp( struct gl_context *ctx,
  1011.                             GLfloat t,
  1012.                             GLuint edst, GLuint eout, GLuint ein,
  1013.                             GLboolean force_boundary )
  1014. {
  1015.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  1016.    struct vertex_buffer *VB = &tnl->vb;
  1017.    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
  1018.    const GLubyte *vin  = vtx->vertex_buf + ein  * vtx->vertex_size;
  1019.    const GLubyte *vout = vtx->vertex_buf + eout * vtx->vertex_size;
  1020.    GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
  1021.    const struct tnl_clipspace_attr *a = vtx->attr;
  1022.    const GLuint attr_count = vtx->attr_count;
  1023.    GLuint j;
  1024.    (void) force_boundary;
  1025.  
  1026.    if (tnl->NeedNdcCoords) {
  1027.       const GLfloat *dstclip = VB->ClipPtr->data[edst];
  1028.       if (dstclip[3] != 0.0) {
  1029.          const GLfloat w = 1.0f / dstclip[3];
  1030.          GLfloat pos[4];
  1031.  
  1032.          pos[0] = dstclip[0] * w;
  1033.          pos[1] = dstclip[1] * w;
  1034.          pos[2] = dstclip[2] * w;
  1035.          pos[3] = w;
  1036.  
  1037.          a[0].insert[4-1]( &a[0], vdst, pos );
  1038.       }
  1039.    }
  1040.    else {
  1041.       a[0].insert[4-1]( &a[0], vdst, VB->ClipPtr->data[edst] );
  1042.    }
  1043.  
  1044.  
  1045.    for (j = 1; j < attr_count; j++) {
  1046.       GLfloat fin[4], fout[4], fdst[4];
  1047.          
  1048.       a[j].extract( &a[j], fin, vin + a[j].vertoffset );
  1049.       a[j].extract( &a[j], fout, vout + a[j].vertoffset );
  1050.  
  1051.       INTERP_F( t, fdst[3], fout[3], fin[3] );
  1052.       INTERP_F( t, fdst[2], fout[2], fin[2] );
  1053.       INTERP_F( t, fdst[1], fout[1], fin[1] );
  1054.       INTERP_F( t, fdst[0], fout[0], fin[0] );
  1055.  
  1056.       a[j].insert[4-1]( &a[j], vdst + a[j].vertoffset, fdst );
  1057.    }
  1058. }
  1059.  
  1060.  
  1061. /* Extract color attributes from one vertex and insert them into
  1062.  * another.  (Shortcircuit extract/insert with memcpy).
  1063.  */
  1064. void _tnl_generic_copy_pv( struct gl_context *ctx, GLuint edst, GLuint esrc )
  1065. {
  1066.    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
  1067.    GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size;
  1068.    GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
  1069.    const struct tnl_clipspace_attr *a = vtx->attr;
  1070.    const GLuint attr_count = vtx->attr_count;
  1071.    GLuint j;
  1072.  
  1073.    for (j = 0; j < attr_count; j++) {
  1074.       if (a[j].attrib == VERT_ATTRIB_COLOR0 ||
  1075.           a[j].attrib == VERT_ATTRIB_COLOR1) {
  1076.  
  1077.          memcpy( vdst + a[j].vertoffset,
  1078.                  vsrc + a[j].vertoffset,
  1079.                  a[j].vertattrsize );
  1080.       }
  1081.    }
  1082. }
  1083.  
  1084.  
  1085. /* Helper functions for hardware which doesn't put back colors and/or
  1086.  * edgeflags into vertices.
  1087.  */
  1088. void _tnl_generic_interp_extras( struct gl_context *ctx,
  1089.                                    GLfloat t,
  1090.                                    GLuint dst, GLuint out, GLuint in,
  1091.                                    GLboolean force_boundary )
  1092. {
  1093.    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
  1094.  
  1095.    /* If stride is zero, BackfaceColorPtr is constant across the VB, so
  1096.     * there is no point interpolating between two values as they will
  1097.     * be identical.  In all other cases, this value is generated by
  1098.     * t_vb_lighttmp.h and has a stride of 4 dwords.
  1099.     */
  1100.    if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
  1101.       assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat));
  1102.  
  1103.       INTERP_4F( t,
  1104.                  VB->BackfaceColorPtr->data[dst],
  1105.                  VB->BackfaceColorPtr->data[out],
  1106.                  VB->BackfaceColorPtr->data[in] );
  1107.    }
  1108.  
  1109.    if (VB->BackfaceSecondaryColorPtr) {
  1110.       assert(VB->BackfaceSecondaryColorPtr->stride == 4 * sizeof(GLfloat));
  1111.      
  1112.       INTERP_3F( t,
  1113.                  VB->BackfaceSecondaryColorPtr->data[dst],
  1114.                  VB->BackfaceSecondaryColorPtr->data[out],
  1115.                  VB->BackfaceSecondaryColorPtr->data[in] );
  1116.    }
  1117.    
  1118.    if (VB->BackfaceIndexPtr) {
  1119.       VB->BackfaceIndexPtr->data[dst][0] = LINTERP( t,
  1120.                                                VB->BackfaceIndexPtr->data[out][0],
  1121.                                                VB->BackfaceIndexPtr->data[in][0] );
  1122.    }
  1123.  
  1124.    if (VB->EdgeFlag) {
  1125.       VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
  1126.    }
  1127.  
  1128.    _tnl_generic_interp(ctx, t, dst, out, in, force_boundary);
  1129. }
  1130.  
  1131. void _tnl_generic_copy_pv_extras( struct gl_context *ctx,
  1132.                                   GLuint dst, GLuint src )
  1133. {
  1134.    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
  1135.  
  1136.    /* See above comment:
  1137.     */
  1138.    if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
  1139.       COPY_4FV( VB->BackfaceColorPtr->data[dst],
  1140.                 VB->BackfaceColorPtr->data[src] );
  1141.    }
  1142.  
  1143.    if (VB->BackfaceSecondaryColorPtr) {
  1144.       COPY_4FV( VB->BackfaceSecondaryColorPtr->data[dst],
  1145.                 VB->BackfaceSecondaryColorPtr->data[src] );
  1146.    }
  1147.  
  1148.    if (VB->BackfaceIndexPtr) {
  1149.       VB->BackfaceIndexPtr->data[dst][0] = VB->BackfaceIndexPtr->data[src][0];
  1150.    }
  1151.  
  1152.    _tnl_generic_copy_pv(ctx, dst, src);
  1153. }
  1154.  
  1155.  
  1156.