home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src / fxmesa2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  21.2 KB  |  809 lines

  1. /* -*- mode: C; tab-width:8;  -*-
  2.  
  3.              fxmesa2.c - 3Dfx VooDoo vertices setup functions 
  4. */
  5.  
  6. /*
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Library General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Library General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Library General Public
  18.  * License along with this library; if not, write to the Free
  19.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  * See the file fxmesa1.c for more informations about authors
  22.  *
  23.  */
  24.  
  25. #if defined(FX)
  26.  
  27. #include <math.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30.  
  31. #include "fxdrv.h"
  32.  
  33. #define GOURAUD_ENABLED 0x1
  34. #define TEXTURE_ENABLED 0x2
  35. #define FOG_ENABLED     0x4
  36. #define WBUFFER_ENABLED 0x8
  37. #define ZBUFFER_ENABLED 0x10
  38.  
  39. #ifdef __WIN32__
  40.  
  41. /************************************************************************/
  42. /********* The Win32 Version of the asm GrVertex Setup code *************/
  43. /************************************************************************/
  44.  
  45. #define RDTSC    __asm _emit 0x0f __asm _emit 0x31
  46.  
  47. #if 0
  48. #define DATA_PROFILING char *format="Number of Cycles for the GrVertex setup: %u (%u number of GrVertex)\n"; unsigned long numcycl
  49.  
  50. #define START_PROFILING __asm { \
  51.   RDTSC                         \                            
  52.   _asm mov numcycl,eax            \
  53. }
  54.  
  55. #define STOP_PROFILING __asm { \
  56.   RDTSC                       \
  57.   __asm mov ebx,vend           \
  58.   __asm sub ebx,vstart           \
  59.   __asm push ebx           \
  60.   __asm sub eax,numcycl           \
  61.   __asm push eax           \
  62.   __asm mov ecx,format           \
  63.   __asm push ecx           \
  64.   __asm call printf           \
  65.   __asm add esp,12             \
  66. }
  67. #else
  68. #define DATA_PROFILING
  69. #define START_PROFILING
  70. #define STOP_PROFILING
  71. #endif
  72.  
  73. #define NOSNAP(v) __asm {                       \
  74.   __asm mov eax,dword ptr [edx]                    \
  75.   __asm mov ebx,dword ptr [edx+4]               \
  76.   __asm mov dword ptr [ecx]GrVertex.x,eax       \
  77.   __asm mov dword ptr [ecx]GrVertex.y,ebx       \
  78. }
  79.  
  80. #define SNAP(v) __asm {                         \
  81.   /* Snap verticies */                            \
  82.   __asm fld dword ptr [edx]            \
  83.   __asm fadd snapconst                \
  84.   __asm fld dword ptr [edx+4]            \
  85.   __asm fadd snapconst                \
  86.   __asm fxch                    \
  87.   __asm fstp dword ptr [ecx]GrVertex.x        \
  88.   __asm fstp dword ptr [ecx]GrVertex.y        \
  89. }
  90.  
  91. #define GOURAUD(v) __asm {              \
  92.   __asm mov ebx,vcol            \
  93.   __asm mov eax,dword ptr [ebx]        \
  94.   __asm mov vwin,edx            \
  95.   __asm add ebx,4            \
  96.   __asm mov vcol,ebx            \
  97.                                         \
  98.   __asm sub edx,edx            \
  99.   __asm sub ebx,ebx            \
  100.   __asm mov dl,ah            \
  101.   __asm mov bl,al            \
  102.   __asm mov stmp2,dx            \
  103.   __asm shr eax,16            \
  104.   __asm mov stmp1,bx            \
  105.   __asm    fild stmp2            \
  106.   __asm    fild stmp1            \
  107.   __asm mov bl,al            \
  108.   __asm mov dl,ah            \
  109.   __asm mov stmp1,bx            \
  110.   __asm mov stmp2,dx            \
  111.   __asm    fild stmp1            \
  112.   __asm fild stmp2            \
  113.   __asm fstp dword ptr [ecx]GrVertex.a    \
  114.   __asm fstp dword ptr [ecx]GrVertex.b    \
  115.   __asm fstp dword ptr [ecx]GrVertex.r    \
  116.   __asm fstp dword ptr [ecx]GrVertex.g    \
  117.   __asm mov edx,vwin                    \
  118. }
  119.  
  120. #define TEXTURE(v) __asm {              \
  121.   __asm mov eax,vtex                \
  122.   __asm fld sscale            \
  123.   __asm fmul dword ptr [eax]                \
  124.   __asm fmul dword ptr [ecx]GrVertex.oow        \
  125.   __asm fstp dword ptr [ecx]GrVertex.tmuvtx[0].sow    \
  126.   __asm fld tscale            \
  127.   __asm fmul dword ptr [eax+4]            \
  128.   __asm add eax,16            \
  129.   __asm fmul dword ptr [ecx]GrVertex.oow        \
  130.   __asm fstp dword ptr [ecx]GrVertex.tmuvtx[0].tow    \
  131.   __asm mov vtex,eax                \
  132. }
  133.  
  134. #define WBUFFER(v) __asm {      \
  135.   __asm mov ebx,vclip        \
  136.   __asm fld wscale        \
  137.   __asm fdiv dword ptr [ebx]    \
  138.   __asm add ebx,16        \
  139.   __asm mov vclip,ebx        \
  140.   __asm fstp dword ptr [ecx]GrVertex.oow    \
  141. }
  142.  
  143. #define ZBUFFER(v) __asm {                      \
  144.   __asm    mov eax,dword ptr [edx+8]        \
  145.   __asm mov dword ptr [ecx]GrVertex.ooz,eax    \
  146. }
  147.  
  148. #define NOP(v) 
  149.  
  150. #define SETUP(label, snap, gouraud, texture, wdepth, zdepth) {    \
  151.   struct vertex_buffer *VB = ctx->VB;                \
  152.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;        \
  153.   GrVertex *GVB = &fxMesa->gwin[vstart];            \
  154.   GrVertex *GVBlast = &fxMesa->gwin[vend];            \
  155.   float wscale = fxMesa->wscale;                 \
  156.   float sscale;                                                 \
  157.   float tscale;                                                 \
  158.   float snapconst=(float)(3L<<18);                \
  159.   float *vwin=VB->Win[vstart];                    \
  160.   short stmp1,stmp2;                        \
  161.   unsigned char *vcol=VB->Color[vstart];                \
  162.   float *vclip=&VB->Clip[vstart][3];                    \
  163.   float *vtex=VB->TexCoord[vstart];                    \
  164.   DATA_PROFILING;                        \
  165.                                 \
  166.   if(ctx->Texture.Current && ctx->Texture.Current->DriverData) {    \
  167.     sscale=((texinfo *)(ctx->Texture.Current->DriverData))->sscale; \
  168.     tscale=((texinfo *)(ctx->Texture.Current->DriverData))->tscale; \
  169.   }                                                             \
  170.                                                                 \
  171.   __asm    {                            \
  172.     START_PROFILING            \
  173.     /* eax: tmp */            \
  174.     /* ebx: tmp */            \
  175.     /* ecx: GVB */            \
  176.     /* edx: vwin */            \
  177.     __asm mov ecx,GVB            \
  178.     __asm mov edx,vwin                \
  179.                                 \
  180.     __asm align 16            \
  181.     __asm label :            \
  182.     snap(GVB)                \
  183.     gouraud(GVB)            \
  184.     wdepth(GVB)                \
  185.     zdepth(GVB)                \
  186.     texture(GVB)            \
  187.                             \
  188.     __asm add ecx,SIZE GrVertex        \
  189.     __asm add edx,12            \
  190.     __asm cmp ecx,GVBlast            \
  191.     __asm jne label            \
  192.                             \
  193.     STOP_PROFILING            \
  194.   }                    \
  195. }
  196.  
  197.  
  198. #else /******************************************************************/
  199.  
  200.  
  201. #ifdef __linux__
  202.  
  203.  
  204. /************************************************************************/
  205. /*********** The Linux Version of the asm GrVertex Setup code ***********/
  206. /************************************************************************/
  207.  
  208.  
  209. #define NOSNAP(v) "      \
  210.   movl (%%edx),%%eax;    \
  211.   movl 4(%%edx),%%ebx;   \
  212.   movl %%eax,(%%ecx);    \
  213.   movl %%ebx,4(%%ecx);"
  214.  
  215. #define SNAP(v) "               \
  216.   flds (%%edx);                \
  217.   fadds %0;            \
  218.   flds 4(%%edx);        \
  219.   fadds %0;            \
  220.   fxch;                \
  221.   fstps (%%ecx);            \
  222.   fstps 4(%%ecx);" 
  223.  
  224. #define GOURAUD(v) "            \
  225.   movl %2,%%ebx;                \
  226.   movl (%%ebx),%%eax;        \
  227.   movl %%edx,%1;         \
  228.   addl $4,%%ebx;          \
  229.   movl %%ebx,%2;                \
  230.                                 \
  231.   subl %%edx,%%edx;        \
  232.   subl %%ebx,%%ebx;        \
  233.   movb %%ah,%%dl;            \
  234.   movb %%al,%%bl;        \
  235.   movw %%dx,%4;                 \
  236.                      \
  237.   shrl $16,%%eax;          \
  238.   movw %%bx,%3;            \
  239.   fildw %4;            \
  240.   fildw %3;            \
  241.   movb %%al,%%bl;        \
  242.   movb %%ah,%%dl;        \
  243.   movw %%bx,%3;            \
  244.   movw %%dx,%4;            \
  245.   fildw %3;            \
  246.   fildw %4;            \
  247.   fstps 28(%%ecx);             \
  248.   fstps 20(%%ecx);             \
  249.   fstps 12(%%ecx);             \
  250.   fstps 16(%%ecx);             \
  251.   movl %1,%%edx;"
  252.  
  253. #define TEXTURE(v) "            \
  254.   movl %5,%%eax;            \
  255.   flds %6;            \
  256.   fmuls (%%eax);        \
  257.   fmuls 32(%%ecx);        \
  258.   fstps 36(%%ecx);           \
  259.   flds %7;            \
  260.   fmuls 4(%%eax);            \
  261.   addl $16,%%eax;        \
  262.   fmuls 32(%%ecx);        \
  263.   fstps 40(%%ecx);           \
  264.   mov %%eax,%5;"
  265.  
  266. #define WBUFFER(v) "            \
  267.   movl %9,%%ebx;        \
  268.   flds %8;                \
  269.   fdivs (%%ebx);                \
  270.   addl $16,%%ebx;        \
  271.   movl %%ebx,%9;        \
  272.   fstps 32(%%ecx);"
  273.  
  274. #define ZBUFFER(v) "            \
  275.   movl 8(%%edx),%%eax;        \
  276.   movl %%eax,24(%%ecx);"
  277.  
  278. #define NOP(v) ""
  279.  
  280. #define SETUP_ASMLOOP(c)               \
  281.   __asm__ volatile (c                  \
  282.   : /* not correctly filled */         \
  283.   : "m" (GVB), "m" (GVBlast), "m" (vwin), "i" (sizeof(GrVertex)) \
  284.   : "eax", "ebx", "ecx", "edx", "cc", "memory")
  285.  
  286. #define SETUP_ASM(c)                   \
  287.   __asm__ volatile (c                  \
  288.   : /* not correctly filled */         \
  289.   : "m" (snapconst), "m" (vwin),       \
  290.     "m" (vcol), "m" (stmp1), "m" (stmp2), "m" (vtex), "m" (sscale), "m" (tscale),  \
  291.     "m" (wscale), "m" (vclip)                                                      \
  292.   : "eax", "ebx", "ecx", "edx", "cc", "memory")
  293.  
  294. #define SETUP(label, snap, gouraud, texture, wdepth, zdepth) {  \
  295.   struct vertex_buffer *VB = ctx->VB;                \
  296.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;        \
  297.   GrVertex *GVB = &fxMesa->gwin[vstart];            \
  298.   GrVertex *GVBlast = &fxMesa->gwin[vend];            \
  299.   float wscale = fxMesa->wscale;                 \
  300.   float sscale;                                                 \
  301.   float tscale;                                                 \
  302.   float snapconst=(float)(3L<<18);                \
  303.   float *vwin=VB->Win[vstart];                    \
  304.   short stmp1,stmp2;                        \
  305.   unsigned char *vcol=VB->Color[vstart];                \
  306.   float *vclip=&VB->Clip[vstart][3];                    \
  307.   float *vtex=VB->TexCoord[vstart];                    \
  308.                                 \
  309.   if(ctx->Texture.Current && ctx->Texture.Current->DriverData) {    \
  310.     sscale=((texinfo *)(ctx->Texture.Current->DriverData))->sscale; \
  311.     tscale=((texinfo *)(ctx->Texture.Current->DriverData))->tscale; \
  312.   }                                                             \
  313.                                   \
  314.   /* eax: tmp */            \
  315.   /* ebx: tmp */            \
  316.   /* ecx: GVB */            \
  317.   /* edx: vwin */            \
  318.   SETUP_ASMLOOP("                       \
  319.     movl %0,%%ecx;            \
  320.     movl %2,%%edx;                \
  321.                                         \
  322.     .align 16;                        \
  323.     ."#label":;");                    \
  324.                                         \
  325.   SETUP_ASM(snap(GVB));            \
  326.   SETUP_ASM(gouraud(GVB));        \
  327.   SETUP_ASM(wdepth(GVB));        \
  328.   SETUP_ASM(zdepth(GVB));        \
  329.   SETUP_ASM(texture(GVB));        \
  330.                                         \
  331.   SETUP_ASMLOOP("                       \
  332.     addl %3,%%ecx;                      \
  333.     addl $12,%%edx;                     \
  334.     cmpl %1,%%ecx;                      \
  335.     jne ."#label";                      \
  336.   ");                                   \
  337. }
  338.  
  339.  
  340. #else /******************************************************************/
  341.  
  342.  
  343. /************************************************************************/
  344. /********* The generic Version of the asm GrVertex Setup code ***********/
  345. /************************************************************************/
  346.  
  347. #define NOSNAP(v) { \
  348.   (v)->x = VB->Win[i][0];             \
  349.   (v)->y = VB->Win[i][1];             \
  350. }
  351.  
  352. #define SNAP(v) { \
  353.   /* trunc (x,y) to multiple of 1/16 */                \
  354.   (v)->x = ((int)(VB->Win[i][0]*16.0f))*(1.0f/16.0f);    \
  355.   (v)->y = ((int)(VB->Win[i][1]*16.0f))*(1.0f/16.0f);    \
  356. }
  357.  
  358.  
  359. #define GOURAUD(v) { \
  360.   (v)->r = (float) (VB->Color[i][0]); \
  361.   (v)->g = (float) (VB->Color[i][1]); \
  362.   (v)->b = (float) (VB->Color[i][2]); \
  363.   (v)->a = (float) (VB->Color[i][3]); \
  364. }
  365.  
  366. #define TEXTURE(v)  { \
  367.   (v)->tmuvtx[0].sow = sscale*VB->TexCoord[i][0]*(v)->oow; \
  368.   (v)->tmuvtx[0].tow = tscale*VB->TexCoord[i][1]*(v)->oow; \
  369. }
  370.  
  371. #define WBUFFER(v) { (v)->oow = wscale/VB->Clip[i][3]; }
  372.  
  373. #define ZBUFFER(v) { (v)->ooz = VB->Win[i][2]; }
  374.  
  375. #define NOP(v) 
  376.  
  377. #define SETUP(label, snap, gouraud, texture, wdepth, zdepth) { \
  378.   register unsigned int i;                            \
  379.   register struct vertex_buffer *VB = ctx->VB;                    \
  380.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;         \
  381.   register GrVertex *GVB = &fxMesa->gwin[vstart];            \
  382.   register float wscale = fxMesa->wscale;                     \
  383.   register float sscale;                                                \
  384.   register float tscale;                                                \
  385.                                 \
  386.   if(ctx->Texture.Current && ctx->Texture.Current->DriverData) {    \
  387.     sscale=((texinfo *)(ctx->Texture.Current->DriverData))->sscale; \
  388.     tscale=((texinfo *)(ctx->Texture.Current->DriverData))->tscale; \
  389.   }                                                             \
  390.                                   \
  391.   for(i=vstart;i<vend;i++,GVB++) {                              \
  392.     snap(GVB);                                                  \
  393.     gouraud(GVB);                                               \
  394.     wdepth(GVB);                                                \
  395.     zdepth(GVB);                                                \
  396.     texture(GVB);                                               \
  397.   }                                                             \
  398. }
  399.  
  400.  
  401. #endif /********************************************************/
  402. #endif
  403.  
  404.  
  405. static void setup(GLcontext *ctx, GLuint vstart, GLuint vend)
  406. {
  407.   switch (ctx->Primitive) {
  408.   case GL_POINTS:
  409. /*  case GL_LINES:           Lines need vertex snap ?!?!
  410.   case GL_LINE_STRIP:
  411.   case GL_LINE_LOOP:*/
  412.     SETUP(l1, NOSNAP, NOP, NOP, NOP, NOP);
  413.     break;
  414.   default:
  415.     SETUP(l2, SNAP, NOP, NOP, NOP, NOP);
  416.     break;
  417.   }
  418. }
  419.         
  420. static void setupG(GLcontext *ctx, GLuint vstart, GLuint vend)
  421. {
  422.   switch (ctx->Primitive) {
  423.   case GL_POINTS:
  424. /*  case GL_LINES:
  425.   case GL_LINE_STRIP:
  426.   case GL_LINE_LOOP:*/
  427.     SETUP(l3, NOSNAP, GOURAUD, NOP, NOP, NOP);
  428.     break;
  429.   default:
  430.     SETUP(l4, SNAP, GOURAUD, NOP, NOP, NOP);
  431.     break;
  432.   }
  433. }
  434.  
  435. static void setupT(GLcontext *ctx, GLuint vstart, GLuint vend)
  436. {
  437.   switch (ctx->Primitive) {
  438.   case GL_POINTS:
  439. /*  case GL_LINES:
  440.   case GL_LINE_STRIP:
  441.   case GL_LINE_LOOP:*/
  442.     SETUP(l5, NOSNAP, NOP, TEXTURE, WBUFFER, NOP);
  443.     break;
  444.   default:
  445.     SETUP(l6, SNAP, NOP, TEXTURE, WBUFFER, NOP);
  446.     break;
  447.   }
  448. }
  449.  
  450. static void setupGT(GLcontext *ctx, GLuint vstart, GLuint vend)
  451. {
  452.   switch (ctx->Primitive) {
  453.   case GL_POINTS:
  454. /*  case GL_LINES:
  455.   case GL_LINE_STRIP:
  456.   case GL_LINE_LOOP:*/
  457.     SETUP(l7, NOSNAP, GOURAUD, TEXTURE, WBUFFER, NOP);
  458.     break;
  459.   default:
  460.     SETUP(l8, SNAP, GOURAUD, TEXTURE, WBUFFER, NOP);
  461.     break;
  462.   }
  463. }
  464.         
  465. static void setupW(GLcontext *ctx, GLuint vstart, GLuint vend)
  466. {
  467.   switch (ctx->Primitive) {
  468.   case GL_POINTS:
  469. /*  case GL_LINES:
  470.   case GL_LINE_STRIP:
  471.   case GL_LINE_LOOP:*/
  472.     SETUP(l9, NOSNAP, NOP, NOP, WBUFFER, NOP);
  473.     break;
  474.   default:
  475.     SETUP(l10, SNAP, NOP, NOP, WBUFFER, NOP);
  476.     break;
  477.   }
  478. }
  479.         
  480. static void setupGW(GLcontext *ctx, GLuint vstart, GLuint vend)
  481. {
  482.   switch (ctx->Primitive) {
  483.   case GL_POINTS:
  484. /*  case GL_LINES:
  485.   case GL_LINE_STRIP:
  486.   case GL_LINE_LOOP:*/
  487.     SETUP(l11, NOSNAP, GOURAUD, NOP, WBUFFER, NOP);
  488.     break;
  489.   default:
  490.     SETUP(l12, SNAP, GOURAUD, NOP, WBUFFER, NOP);
  491.     break;
  492.   }
  493. }
  494.  
  495. static void setupZ(GLcontext *ctx, GLuint vstart, GLuint vend)
  496. {
  497.   switch (ctx->Primitive) {
  498.   case GL_POINTS:
  499. /*  case GL_LINES:
  500.   case GL_LINE_STRIP:
  501.   case GL_LINE_LOOP:*/
  502.     SETUP(l13, NOSNAP, NOP, NOP, NOP, ZBUFFER);
  503.     break;
  504.   default:
  505.     SETUP(l14, SNAP, NOP, NOP, NOP, ZBUFFER);
  506.     break;
  507.   }
  508. }
  509.         
  510. static void setupGZ(GLcontext *ctx, GLuint vstart, GLuint vend)
  511. {
  512.   switch (ctx->Primitive) {
  513.   case GL_POINTS:
  514. /*  case GL_LINES:
  515.   case GL_LINE_STRIP:
  516.   case GL_LINE_LOOP:*/
  517.     SETUP(l15, NOSNAP, GOURAUD, NOP, NOP, ZBUFFER);
  518.     break;
  519.   default:
  520.     SETUP(l16, SNAP, GOURAUD, NOP, NOP, ZBUFFER);
  521.     break;
  522.   }
  523. }
  524.  
  525. static void setupTZ(GLcontext *ctx, GLuint vstart, GLuint vend)
  526. {
  527.   switch (ctx->Primitive) {
  528.   case GL_POINTS:
  529. /*  case GL_LINES:
  530.   case GL_LINE_STRIP:
  531.   case GL_LINE_LOOP:*/
  532.     SETUP(l17, NOSNAP, NOP, TEXTURE, WBUFFER, ZBUFFER);
  533.     break;
  534.   default:
  535.     SETUP(l18, SNAP, NOP, TEXTURE, WBUFFER, ZBUFFER);
  536.     break;
  537.   }
  538. }
  539.         
  540. static void setupGTZ(GLcontext *ctx, GLuint vstart, GLuint vend)
  541. {
  542.   switch (ctx->Primitive) {
  543.   case GL_POINTS:
  544. /*  case GL_LINES:
  545.   case GL_LINE_STRIP:
  546.   case GL_LINE_LOOP:*/
  547.     SETUP(l19, NOSNAP, GOURAUD, TEXTURE, WBUFFER, ZBUFFER);
  548.     break;
  549.   default:
  550.     SETUP(l20, SNAP, GOURAUD, TEXTURE, WBUFFER, ZBUFFER);
  551.     break;
  552.   }
  553. }
  554.  
  555. setup_func fxSetupFuncs[] = {
  556.   setup,
  557.   setupG,
  558.   setupT,
  559.   setupGT,
  560.   setupW,
  561.   setupGW,
  562.   setupT,
  563.   setupGT,
  564.   setupW,
  565.   setupGW,
  566.   setupT,
  567.   setupGT,
  568.   setupW,
  569.   setupGW,
  570.   setupT,
  571.   setupGT,
  572.   setupZ,
  573.   setupGZ,
  574.   setupTZ,
  575.   setupGTZ,
  576.   setupZ,
  577.   setupGZ,
  578.   setupTZ,
  579.   setupGTZ
  580. };
  581.  
  582. setup_func 
  583. choose_setup_function(GLcontext *ctx)
  584. {
  585.   unsigned int setupIndex = 0;
  586.  
  587.   if (ctx->Light.ShadeModel == GL_SMOOTH && !ctx->Light.Model.TwoSide)
  588.     setupIndex |= GOURAUD_ENABLED;
  589.   if (ctx->Texture.Enabled)
  590.     setupIndex |= TEXTURE_ENABLED;
  591.   if (ctx->Fog.Enabled)
  592.     setupIndex |= FOG_ENABLED;
  593.   if (ctx->Depth.Test) {
  594.     if((ctx->ProjectionMatrix[15]==0.0f) &&
  595.        (ctx->Viewport.Near==0.0) && (ctx->Viewport.Far==1.0))
  596.       setupIndex |= WBUFFER_ENABLED;
  597.     else
  598.       setupIndex |= ZBUFFER_ENABLED;
  599.   }
  600.  
  601. #if defined(DEBUG_FXMESA)
  602.     fprintf(stderr,"fxmesa: vertex setup function %d (%d,%d)\n",
  603.         setupIndex,setupIndex & GOURAUD_ENABLED, setupIndex & TEXTURE_ENABLED);
  604. #endif
  605.  
  606.   return fxSetupFuncs[setupIndex];
  607. }
  608.  
  609. #undef GOURAUD
  610. #define GOURAUD(v) { \
  611.   fxMesa->gwin[(v)].r = (float) VB->Color[(v)][0]; \
  612.   fxMesa->gwin[(v)].g = (float) VB->Color[(v)][1]; \
  613.   fxMesa->gwin[(v)].b = (float) VB->Color[(v)][2]; \
  614.   fxMesa->gwin[(v)].a = (float) VB->Color[(v)][3]; \
  615. }
  616.  
  617. static void 
  618. fxPoint(GLcontext *ctx, GLuint first, GLuint last)
  619. {
  620.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
  621.   unsigned int i;
  622.  
  623.   if(ctx->MonoPixels)
  624.     grConstantColorValue(fxMesa->color);
  625.  
  626.   for (i = first; i < last ; i++)
  627.     grDrawPoint(&fxMesa->gwin[i]);
  628. }
  629.  
  630.  
  631. points_func 
  632. choose_points_function(GLcontext *ctx)
  633. {
  634.   if (ctx->RasterMask & STENCIL_BIT)
  635.     return NULL;
  636.  
  637.   return fxPoint;
  638. }
  639.  
  640. static void 
  641. fxLineSmooth(GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv)
  642. {
  643.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
  644.   grDrawLine(&fxMesa->gwin[v1], &fxMesa->gwin[v2]);
  645. }
  646.  
  647. static void 
  648. fxLineSmoothTwoSide(GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv)
  649. {
  650.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
  651.   struct vertex_buffer *VB = ctx->VB;
  652.   GOURAUD(v1); 
  653.   GOURAUD(v2); 
  654.   grDrawLine(&fxMesa->gwin[v1], &fxMesa->gwin[v2]);
  655. }
  656.  
  657. static void 
  658. fxLineFlat(GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv)
  659. {
  660.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
  661.   GLubyte *Color = ctx->VB->Color[pv];
  662.  
  663.   grConstantColorValue(FXCOLOR(Color[0], Color[1], Color[2], Color[3]));
  664.   grDrawLine(&fxMesa->gwin[v1], &fxMesa->gwin[v2]);
  665. }
  666.  
  667. line_func 
  668. choose_line_function(GLcontext *ctx)
  669. {
  670.   if (ctx->RasterMask & STENCIL_BIT)
  671.     return NULL;
  672.  
  673.   if (ctx->Light.ShadeModel == GL_SMOOTH)
  674.     if (ctx->Light.Model.TwoSide)
  675.       return fxLineSmoothTwoSide;
  676.     else
  677.       return fxLineSmooth;
  678.   else
  679.     return fxLineFlat;
  680. }
  681.  
  682. /************************************************************************/
  683. /*********************** Triangle functions *****************************/
  684. /************************************************************************/
  685.  
  686. static void 
  687. fxTriangleSmooth(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv)
  688. {
  689.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
  690.   grDrawTriangle(&fxMesa->gwin[v1], &fxMesa->gwin[v2], &fxMesa->gwin[v3]);
  691. }
  692.  
  693. static void 
  694. fxTriangleSmoothTwoSide(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv)
  695. {
  696.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
  697.   struct vertex_buffer *VB = ctx->VB;
  698.   GOURAUD(v1); 
  699.   GOURAUD(v2); 
  700.   GOURAUD(v3); 
  701.   grDrawTriangle(&fxMesa->gwin[v1], &fxMesa->gwin[v2], &fxMesa->gwin[v3]);
  702. }
  703.  
  704. static void 
  705. fxTriangleFlat(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv)
  706. {
  707.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
  708.   GLubyte *Color = ctx->VB->Color[pv];
  709.   grConstantColorValue(FXCOLOR(Color[0], Color[1], Color[2], Color[3]));
  710.   grDrawTriangle(&fxMesa->gwin[v1], &fxMesa->gwin[v2], &fxMesa->gwin[v3]);
  711. }
  712.  
  713. triangle_func 
  714. choose_triangle_function(GLcontext *ctx)
  715. {
  716.   if (ctx->RasterMask & STENCIL_BIT)
  717.     return NULL;
  718.  
  719.   if (ctx->Light.ShadeModel == GL_SMOOTH)
  720.     if (ctx->Light.Model.TwoSide)
  721.       return fxTriangleSmoothTwoSide;
  722.     else
  723.       return fxTriangleSmooth;
  724.   else
  725.     return fxTriangleFlat;
  726. }
  727.  
  728. /************************************************************************/
  729. /************************* Quads functions ******************************/
  730. /************************************************************************/
  731.  
  732. static void 
  733. fxQuadSmooth(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4, GLuint pv)
  734. {
  735.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
  736.   GrVertex *grv2,*grv4;
  737.  
  738.   grv2=&fxMesa->gwin[v2];
  739.   grv4=&fxMesa->gwin[v4];
  740.  
  741.   grDrawTriangle(&fxMesa->gwin[v1], grv2, grv4);
  742.   grDrawTriangle(grv2, &fxMesa->gwin[v3], grv4);
  743. }
  744.  
  745. static void 
  746. fxQuadSmoothTwoSide(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4, GLuint pv)
  747. {
  748.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
  749.   struct vertex_buffer *VB = ctx->VB;
  750.   GrVertex *grv2,*grv4;
  751.  
  752.   GOURAUD(v1); 
  753.   GOURAUD(v2); 
  754.   GOURAUD(v3); 
  755.   GOURAUD(v4); 
  756.  
  757.   grv2=&fxMesa->gwin[v2];
  758.   grv4=&fxMesa->gwin[v4];
  759.  
  760.   grDrawTriangle(&fxMesa->gwin[v1], grv2, grv4);
  761.   grDrawTriangle(grv2, &fxMesa->gwin[v3], grv4);
  762. }
  763.  
  764. static void 
  765. fxQuadFlat(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3,GLuint v4, GLuint pv)
  766. {
  767.   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
  768.   GLubyte *Color = ctx->VB->Color[pv];
  769.   GrVertex *grv2,*grv4;
  770.  
  771.   grConstantColorValue(FXCOLOR(Color[0], Color[1], Color[2], Color[3]));
  772.  
  773.   grv2=&fxMesa->gwin[v2];
  774.   grv4=&fxMesa->gwin[v4];
  775.  
  776.   grDrawTriangle(&fxMesa->gwin[v1], grv2, grv4);
  777.   grDrawTriangle(grv2, &fxMesa->gwin[v3], grv4);
  778. }
  779.  
  780. quad_func 
  781. choose_quad_function(GLcontext *ctx)
  782. {
  783.   if (ctx->RasterMask & STENCIL_BIT)
  784.     return NULL;
  785.  
  786.   if(ctx->Light.ShadeModel == GL_SMOOTH)
  787.     if(ctx->Light.Model.TwoSide)
  788.       return fxQuadSmoothTwoSide;
  789.     else
  790.       return fxQuadSmooth;
  791.   else
  792.     return fxQuadFlat;
  793. }
  794.  
  795.  
  796. #else
  797.  
  798.  
  799. /*
  800.  * Need this to provide at least one external definition.
  801.  */
  802.  
  803. int gl_fx_dummy_function2(void)
  804. {
  805.   return 0;
  806. }
  807.  
  808. #endif  /* FX */
  809.