Subversion Repositories Kolibri OS

Rev

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