home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / AOS / amesatools.c < prev    next >
C/C++ Source or Header  |  1999-09-23  |  12KB  |  401 lines

  1. /*
  2.  * $Id: $
  3.  */
  4.  
  5. /*
  6.  * Mesa 3-D graphics library
  7.  * Version:  3.1
  8.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  9.  *
  10.  * This library is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU Library General Public
  12.  * License as published by the Free Software Foundation; either
  13.  * version 2 of the License, or (at your option) any later version.
  14.  *
  15.  * This library is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18.  * Library General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU Library General Public
  21.  * License along with this library; if not, write to the Free
  22.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  */
  24.  
  25. #undef    NO_CONTEXT_AVAILABLE
  26. #include <AOS/amigamesa.h>
  27.  
  28. /**********************************************************************/
  29. /*****                  amiga/Mesa Private Functions (RastPort)   *****/
  30. /**********************************************************************/
  31.  
  32. GLboolean allocTempRPort(amigaMesaContext amesa, int flags)
  33. {
  34.   struct RastPort *temprp;
  35.  
  36.   assert(amesa);
  37.  
  38.   DEBUGOUT(1, "allocTempRPort(0x%08x, 0x%02x)\n", amesa, flags);
  39.  
  40.   if ((temprp = AllocVecPooled(amesa->mempool, sizeof(struct RastPort)))) {
  41.     CopyMem(amesa->rp, temprp, sizeof(struct RastPort));
  42.  
  43.     temprp->Layer = NULL;
  44.     if ((temprp->BitMap = AllocBitMap(amesa->FixedWidth, 1, amesa->rp->BitMap->Depth, flags | BMF_MINPLANES, amesa->rp->BitMap))) {
  45. #if 0
  46.       temprp->BytesPerRow = amesa->FixedWidth * 8;
  47. #endif
  48.       amesa->temprp = temprp;
  49.       return GL_TRUE;
  50.     }
  51.     else
  52.       DEBUGOUT(0, "allocTempRPort: failed AllocBitMap()\n");
  53.     FreeVecPooled(amesa->mempool, (ULONG *) temprp);
  54.   }
  55.   else
  56.     DEBUGOUT(0, "allocTempRPort: failed AllocVecPooled()\n");
  57.  
  58.   return GL_FALSE;
  59. }
  60.  
  61. void freeTempRPort(amigaMesaContext amesa)
  62. {
  63.   assert(amesa);
  64.  
  65.   DEBUGOUT(1, "freeTempRPort(0x%08x, 0x%08x)\n", amesa, amesa->temprp);
  66.  
  67.   if (amesa->temprp) {
  68.     if (amesa->temprp->BitMap)
  69.       FreeBitMap(amesa->temprp->BitMap);
  70.     FreeVecPooled(amesa->mempool, (ULONG *) amesa->temprp);
  71.     amesa->temprp = NULL;
  72.   }
  73. }
  74.  
  75. /*
  76.  * Create a new rastport to use as a back buffer.
  77.  * Input:  width, height - size in pixels
  78.  *        depth - number of bitplanes
  79.  */
  80.  
  81. struct RastPort *makeRPort(amigaMesaContext amesa, int width, int height, int depth, int flags, struct BitMap *friendbm)
  82. {
  83.   struct RastPort *rp;
  84.   struct BitMap *bm;
  85.  
  86.   DEBUGOUT(1, "makeRPort(0x%08x, %d, %d, %d, 0x%02x, 0x%08x)\n", amesa, width, height, depth, flags, friendbm);
  87.  
  88.   if ((bm = AllocBitMap(width, height, depth, flags | BMF_CLEAR | BMF_MINPLANES, friendbm))) {
  89.     if ((rp = (struct RastPort *)AllocVecPooled(amesa->mempool, sizeof(struct RastPort)))) {
  90.       bzero(rp, sizeof(struct RastPort));
  91.  
  92.       InitRastPort(rp);
  93.       rp->BitMap = bm;
  94.  
  95.       return rp;
  96.     }
  97.     else
  98.       DEBUGOUT(0, "makeRPort: failed AllocVecPooled()\n");
  99.     FreeBitMap(bm);
  100.   }
  101.   else
  102.     DEBUGOUT(0, "makeRPort: failed AllocBitMap()\n");
  103.  
  104.   return NULL;
  105. }
  106.  
  107. /*
  108.  * Deallocate a rastport.
  109.  */
  110.  
  111. void destroyRPort(amigaMesaContext amesa, struct RastPort *rp)
  112. {
  113.   DEBUGOUT(1, "destroyRPort(0x%08x, 0x%08x)\n", amesa, rp);
  114.  
  115.   if (rp) {
  116.     WaitBlit();
  117.     
  118.     if (rp->BitMap)
  119.       FreeBitMap(rp->BitMap);
  120.     FreeVecPooled(amesa->mempool, (ULONG *)rp);
  121.   }
  122. }
  123.  
  124. /**********************************************************************/
  125. /*****                  amiga/Mesa Private Functions (Raster)     *****/
  126. /**********************************************************************/
  127.  
  128. /*
  129.  * Construct a temporary raster for use by the given rasterport.
  130.  * Temp rasters are used for polygon drawing.
  131.  */
  132.  
  133. GLboolean makeTempRaster(amigaMesaContext amesa, struct RastPort *rp)
  134. {
  135.   GLuint width, height;
  136.   PLANEPTR p;
  137.   struct TmpRas *tmpras;
  138.  
  139.   assert(rp);
  140.   assert(rp->BitMap);
  141.  
  142.   DEBUGOUT(1, "makeTempRaster(0x%08x, 0x%08x)\n", amesa, rp);
  143.  
  144.   width = rp->BitMap->BytesPerRow * 8;
  145.   height = rp->BitMap->Rows;
  146.  
  147.   /* allocate structures */
  148.   if ((p = AllocRaster(width, height))) {
  149.     if ((rp->TmpRas = tmpras = (struct TmpRas *)AllocVecPooled(amesa->mempool, sizeof(struct TmpRas)))) {
  150.       bzero(tmpras, sizeof(struct TmpRas));
  151.  
  152.       InitTmpRas(tmpras, p, ((width + 15) >> 4) * height);
  153.  
  154.       return GL_TRUE;
  155.     }
  156.     else
  157.       DEBUGOUT(0, "makeTempRaster: failed AllocVecPooled()\n");
  158.     FreeRaster(p, width, height);
  159.   }
  160.   else
  161.     DEBUGOUT(0, "makeTempRaster: failed AllocRaster()\n");
  162.  
  163.   return GL_FALSE;
  164. }
  165.  
  166. /*
  167.  * Destroy a temp raster.
  168.  */
  169.  
  170. void destroyTempRaster(amigaMesaContext amesa, struct RastPort *rp)
  171. {
  172.   DEBUGOUT(1, "destroyTempRaster(0x%08x, 0x%08x)\n", amesa, rp);
  173.  
  174.   if (rp) {
  175.     GLuint width = 0, height = 0;
  176.  
  177.     if (rp->BitMap) {
  178.       width = rp->BitMap->BytesPerRow * 8;
  179.       height = rp->BitMap->Rows;
  180.     }
  181.  
  182.     if (rp->TmpRas) {
  183.       if (rp->TmpRas->RasPtr)
  184.         FreeRaster(rp->TmpRas->RasPtr, width, height);
  185.       FreeVecPooled(amesa->mempool, (ULONG *) rp->TmpRas);
  186.       rp->TmpRas = NULL;
  187.     }
  188.   }
  189. }
  190.  
  191. /**********************************************************************/
  192. /*****                  amiga/Mesa Private Functions (PenBack)    *****/
  193. /**********************************************************************/
  194. /*
  195.  * Color_buf is a array of pens equals the drawing area
  196.  * it's for faster dubbelbuffer rendering
  197.  * Whent it's time for bufferswitch just use c2p and copy.
  198.  */
  199.  
  200. GLubyte *allocPenBackArray(amigaMesaContext amesa, int width, int height, int bytes)
  201. {
  202.   GLubyte *PenBackArray;
  203.  
  204.   DEBUGOUT(1, "allocPenBackArray(0x%08x, %d, %d, %d)\n", amesa, width, height, bytes);
  205.  
  206.   if ((PenBackArray = AllocVecPooled(amesa->mempool, width * height * bytes)))
  207. #if 0
  208.     BltClear(PenBackArray, width * height * bytes, 1);
  209. #else
  210.     bzero(PenBackArray, width * height * bytes);
  211. #endif
  212.  
  213.   return PenBackArray;
  214. }
  215.  
  216. void destroyPenBackArray(amigaMesaContext amesa, GLubyte * buf)
  217. {
  218.   assert(amesa);
  219.  
  220.   DEBUGOUT(1, "destroyPenBackArray(0x%08x, 0x%08x)\n", amesa, buf);
  221.  
  222.   if (buf)
  223.     FreeVecPooled(amesa->mempool, (ULONG *) buf);
  224. }
  225.  
  226. /**********************************************************************/
  227. /*****                  amiga/Mesa Private Functions (OneLine)    *****/
  228. /**********************************************************************/
  229.  
  230. void AllocOneLine(amigaMesaContext amesa)
  231. {
  232.   assert(amesa);
  233.  
  234.   DEBUGOUT(1, "AllocOneLine(0x%08x)\n", amesa);
  235.  
  236.   if (!(amesa->imageline = AllocVecPooled(amesa->mempool, amesa->FixedWidth * (amesa->depth <= 8 ? 1 : 4))))
  237.     Error("AllocOneLine: Not enough memory to allocate imageline\n");
  238. }
  239.  
  240. void FreeOneLine(amigaMesaContext amesa)
  241. {
  242.   assert(amesa);
  243.  
  244.   DEBUGOUT(1, "FreeOneLine(0x%08x, 0x%08x)\n", amesa, amesa->imageline);
  245.  
  246.   if (amesa->imageline) {
  247.     FreeVecPooled(amesa->mempool, (ULONG *) amesa->imageline);
  248.     amesa->imageline = 0;
  249.   }
  250. }
  251.  
  252. /**********************************************************************/
  253. /*****                  amiga/Mesa Private Functions (Area)       *****/
  254. /**********************************************************************/
  255.  
  256. GLboolean allocArea(amigaMesaContext amesa, struct RastPort *rp)
  257. {
  258.   struct AreaInfo *areainfo;
  259.   UWORD *pattern;
  260.   APTR vbuffer;
  261.  
  262.   DEBUGOUT(1, "allocArea(0x%08x, 0x%08x)\n", amesa, rp);
  263.  
  264.   if ((areainfo = (struct AreaInfo *)AllocVecPooled(amesa->mempool, sizeof(struct AreaInfo)))) {
  265.     bzero(areainfo, sizeof(struct AreaInfo));
  266.  
  267.     if ((pattern = (UWORD *) AllocVecPooled(amesa->mempool, sizeof(UWORD)))) {
  268.       *pattern = 0xffff;                            /*  @@@ org: 0xffffffff */
  269.  
  270.       if ((vbuffer = (APTR) AllocVecPooled(amesa->mempool, MAX_POLYGON * 5 * sizeof(WORD)))) {
  271.     bzero(vbuffer, MAX_POLYGON * 5 * sizeof(WORD));
  272.  
  273.     /* initialize */
  274.     InitArea(areainfo, vbuffer, MAX_POLYGON);
  275.  
  276.     /* bind to rastport */
  277.     rp->AreaPtrn = pattern;
  278.     rp->AreaInfo = areainfo;
  279.     rp->AreaPtSz = 0;
  280.  
  281.     return GL_TRUE;
  282.       }
  283.       else
  284.         DEBUGOUT(0, "allocArea: failed AllocVecPooled()\n");
  285.       FreeVecPooled(amesa->mempool, (ULONG *) pattern);
  286.     }
  287.     else
  288.       DEBUGOUT(0, "allocArea: failed AllocVecPooled()\n");
  289.     FreeVecPooled(amesa->mempool, (ULONG *) areainfo);
  290.   }
  291.   else
  292.     DEBUGOUT(0, "allocArea: failed AllocVecPooled()\n");
  293.  
  294.   return GL_FALSE;
  295. }
  296.  
  297. void freeArea(amigaMesaContext amesa, struct RastPort *rp)
  298. {
  299.   assert(rp);
  300.  
  301.   DEBUGOUT(1, "freeArea(0x%08x, 0x%08x)\n", amesa, rp);
  302.  
  303.   if (rp->AreaPtrn) {
  304.     FreeVecPooled(amesa->mempool, (ULONG *) rp->AreaPtrn);
  305.     rp->AreaPtrn = NULL;
  306.   }
  307.   if (rp->AreaInfo) {
  308.     if (rp->AreaInfo->VctrTbl)
  309.       FreeVecPooled(amesa->mempool, (ULONG *) rp->AreaInfo->VctrTbl);
  310.     FreeVecPooled(amesa->mempool, (ULONG *) rp->AreaInfo);
  311.     rp->AreaInfo = NULL;
  312.   }
  313. }
  314.  
  315. /**********************************************************************/
  316. /*****                  amiga/Mesa Private Functions (FixedXY)    *****/
  317. /**********************************************************************/
  318.  
  319. GLboolean makeFixedXY(amigaMesaContext amesa)
  320. {
  321.   GLint *FixedXY, **FixedXYdb;
  322.  
  323.   assert(amesa);
  324.  
  325.   amesa->FixedX = amesa->left;
  326.   amesa->FixedY = amesa->FixedHeight - amesa->bottom;
  327.   DEBUGOUT(1, "makeFixedXY(0x%08x, %d, %d, 0x%08x, 0x%08x)\n", amesa, amesa->FixedX, amesa->FixedY, amesa->FixedXY, amesa->FixedXYdb);
  328.  
  329. #if 1
  330.   if ((FixedXY   = amesa->FixedXY  ))
  331.     FreeVecPooled(amesa->mempool, (ULONG *) FixedXY  );
  332.   if ((FixedXYdb = amesa->FixedXYdb))
  333.     FreeVecPooled(amesa->mempool, (ULONG *) FixedXYdb);
  334.  
  335.   if ((FixedXY   = amesa->FixedXY   = AllocVecPooled(amesa->mempool, amesa->FixedHeight * sizeof(GLuint  ))) &&
  336.       (FixedXYdb = amesa->FixedXYdb = AllocVecPooled(amesa->mempool, amesa->FixedHeight * sizeof(GLuint *)))) {
  337.     register GLshort byteshift = amesa->depth <= 8 ? 0 : 2;
  338.     register GLubyte *Array = amesa->BackArray;
  339. #if 1
  340.     register GLint row;
  341.  
  342.     for (row = 0; row < amesa->FixedHeight; row++) {
  343.       FixedXY  [row] =              (amesa->FixedWidth * FIXy(row)) + FIXx(0);
  344. //    DEBUGOUT(5, "makeFixedXY:   [%d] = 0x%08x\n", row,   (amesa->FixedWidth * FIXy(row)) + FIXx(0));
  345.       FixedXYdb[row] = (GLuint *)((((amesa->FixedWidth * FIXy(row)) + FIXx(0)) << byteshift) + Array);
  346. //    DEBUGOUT(5, "makeFixedXY: db[%d] = 0x%08x/%d/0x%08x\n", row, (((amesa->FixedWidth * FIXy(row)) + FIXx(0)) << byteshift) + Array, byteshift, Array);
  347.     }
  348. #else
  349. #if 1
  350.     register GLint row, offset;
  351.  
  352.     for (row = 0, offset = FIXx(0); row < amesa->FixedHeight; row++, offset += (amesa->FixedWidth * FIXy(1))) {
  353.       FixedXY  [row] =  offset;
  354.       FixedXYdb[row] = (offset << byteshift) + Array;
  355.     }
  356. #else
  357.     register GLshort row = amesa->FixedHeight - 1;
  358.     register GLint offset = (amesa->FixedWidth * FIXy(row)) + FIXx(0);
  359.     register GLint offseb = (amesa->FixedWidth * FIXy(row)) + FIXx(0) << byteshift;
  360.     register GLint sut = (amesa->FixedWidth * FIXy(1));
  361.     register GLint sub = (amesa->FixedWidth * FIXy(1)) << byteshift;
  362.     register GLint * FixedXYflow   = FixedXY   + (amesa->FixedHeight * sizeof(GLint));
  363.     register GLint **FixedXYdbflow = FixedXYdb + (amesa->FixedHeight * sizeof(GLint *));
  364.  
  365.     while (--row >= 0) {
  366.       *--FixedXYflow   = offset;
  367.       *--FixedXYdbflow = offseb + Array;
  368.       offset -= sut;
  369.       offseb -= sub;
  370.     }
  371. #endif
  372. #endif
  373.  
  374. #if 0
  375.     srand(time(NULL));
  376.     for (row = 0; row <= 100; row++) {
  377.       GLshort x, y;
  378.       GLubyte *db = (GLubyte *)Array;
  379.       
  380.       x = rand() % amesa->FixedWidth;
  381.       y = rand() % amesa->FixedHeight;
  382.  
  383.       DEBUGOUT(5, " (%d) = FIXx(%d)/FixedX(%d)\n", x, amesa->left + x, amesa->FixedX + x);
  384.       DEBUGOUT(5, " (%d) = FIXy(%d)/FixedY(%d)\n", y, amesa->FixedHeight - amesa->bottom - y, amesa->FixedY - y);
  385.       DEBUGOUT(5, " (%d/%d) = FIXxy(%d)/FixedXY(%d)\n", x, y, (amesa->FixedWidth * FIXy(y)) + FIXx(x), FixedXY[y] + x);
  386.       if (amesa->depth <= 8)
  387.         DEBUGOUT(5, " (%d/%d) = FIXxy(0x%08x)/FixedXY(0x%08x)\n", x, y, (GLubyte *)db + FIXxy(x, y), (GLubyte *)FixedXYdb[y] + x);
  388.       else
  389.         DEBUGOUT(5, " (%d/%d) = FIXxy(0x%08x)/FixedXY(0x%08x)\n", x, y, (GLuint *)db + FIXxy(x, y), (GLuint *)FixedXYdb[y] + x);
  390.     }
  391. #endif
  392.                  
  393.     return GL_TRUE;
  394.   }
  395. #else
  396.   return GL_TRUE;
  397. #endif
  398.  
  399.   return GL_FALSE;
  400. }
  401.