/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */

/*
 * Mesa 3-D graphics library
 * Version:  3.3
 *
 * Copyright (C) 1999  Brian Paul   All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 *
 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
 * terms stated above.
 *
 * Thank you for your contribution, David!
 *
 * Please make note of the above copyright/license statement.  If you
 * contributed code or bug fixes to this code under the previous (GNU
 * Library) license and object to the new license, your code will be
 * removed at your request.  Please see the Mesa docs/COPYRIGHT file
 * for more information.
 *
 * Additional Mesa/3Dfx driver developers:
 *   Daryll Strauss <daryll@precisioninsight.com>
 *   Keith Whitwell <keith@precisioninsight.com>
 *
 * See fxapi.h for more revision/author details.
 */


#ifndef __FX_GLIDE_WARPER__
#define __FX_GLIDE_WARPER__

#include <glide.h>

/*
 * General context:
 */
#if !defined(FX_GLIDE3)
     typedef FxU32       FX_GrContext_t;        /* Not used in Glide2 */
#else
     typedef GrContext_t FX_GrContext_t;
#endif

/*
 * Glide3 emulation on Glide2:
 */
#if !defined(FX_GLIDE3)
        /* Constanst for FX_grGetInteger( ) */
        #define FX_FOG_TABLE_ENTRIES            0x0004    /* The number of entries in the hardware fog table. */
        #define FX_GLIDE_STATE_SIZE             0x0006    /* Size of buffer, in bytes, needed to save Glide state. */
        #define FX_LFB_PIXEL_PIPE               0x0009    /* 1 if LFB writes can go through the 3D pixel pipe. */
        #define FX_PENDING_BUFFERSWAPS          0x0014    /* The number of buffer swaps pending. */
        #define FX_TEXTURE_ALIGN                0x0024    /* The required alignment for textures */
#else
        #define FX_FOG_TABLE_ENTRIES            GR_FOG_TABLE_ENTRIES
        #define FX_GLIDE_STATE_SIZE             GR_GLIDE_STATE_SIZE
        #define FX_LFB_PIXEL_PIPE               GR_LFB_PIXEL_PIPE
        #define FX_PENDING_BUFFERSWAPS          GR_PENDING_BUFFERSWAPS
        #define FX_TEXTURE_ALIGN                GR_TEXTURE_ALIGN
#endif

/*
 * Genral warper functions for Glide2/Glide3:
 */
extern FxI32 FX_grGetInteger(FxU32 pname);
extern FxI32 FX_grGetInteger_NoLock(FxU32 pname);

/*
 * Glide2 emulation on Glide3:
 */
#if defined(FX_GLIDE3)

#define GR_ASPECT_1x1 GR_ASPECT_LOG2_1x1
#define GR_ASPECT_2x1 GR_ASPECT_LOG2_2x1
#define GR_ASPECT_4x1 GR_ASPECT_LOG2_4x1
#define GR_ASPECT_8x1 GR_ASPECT_LOG2_8x1
#define GR_ASPECT_1x2 GR_ASPECT_LOG2_1x2
#define GR_ASPECT_1x4 GR_ASPECT_LOG2_1x4
#define GR_ASPECT_1x8 GR_ASPECT_LOG2_1x8

#define GR_LOD_256      GR_LOD_LOG2_256
#define GR_LOD_128      GR_LOD_LOG2_128
#define GR_LOD_64       GR_LOD_LOG2_64
#define GR_LOD_32       GR_LOD_LOG2_32
#define GR_LOD_16       GR_LOD_LOG2_16
#define GR_LOD_8        GR_LOD_LOG2_8
#define GR_LOD_4        GR_LOD_LOG2_4
#define GR_LOD_2        GR_LOD_LOG2_2
#define GR_LOD_1        GR_LOD_LOG2_1

#define GR_FOG_WITH_TABLE GR_FOG_WITH_TABLE_ON_Q

typedef int GrSstType;

#define MAX_NUM_SST            4

#define GR_SSTTYPE_VOODOO    0
#define GR_SSTTYPE_SST96     1
#define GR_SSTTYPE_AT3D      2
#define GR_SSTTYPE_Voodoo2   3

typedef struct GrTMUConfig_St {
  int    tmuRev;                /* Rev of Texelfx chip */
  int    tmuRam;                /* 1, 2, or 4 MB */
} GrTMUConfig_t;

typedef struct GrVoodooConfig_St {
  int    fbRam;                         /* 1, 2, or 4 MB */
  int    fbiRev;                        /* Rev of Pixelfx chip */
  int    nTexelfx;                      /* How many texelFX chips are there? */
  FxBool sliDetect;                     /* Is it a scan-line interleaved board? */
  GrTMUConfig_t tmuConfig[GLIDE_NUM_TMU];   /* Configuration of the Texelfx chips */
} GrVoodooConfig_t;

typedef struct GrSst96Config_St {
  int   fbRam;                  /* How much? */
  int   nTexelfx;
  GrTMUConfig_t tmuConfig;
} GrSst96Config_t;

typedef GrVoodooConfig_t GrVoodoo2Config_t;

typedef struct GrAT3DConfig_St {
  int   rev;
} GrAT3DConfig_t;

typedef struct {
  int num_sst;                  /* # of HW units in the system */
  struct {
    GrSstType type;             /* Which hardware is it? */
    union SstBoard_u {
      GrVoodooConfig_t  VoodooConfig;
      GrSst96Config_t   SST96Config;
      GrAT3DConfig_t    AT3DConfig;
      GrVoodoo2Config_t Voodoo2Config;
    } sstBoard;
  } SSTs[MAX_NUM_SST];          /* configuration for each board */
} GrHwConfiguration;

typedef FxU32 GrHint_t;
#define GR_HINTTYPE_MIN                 0
#define GR_HINT_STWHINT                 0

typedef FxU32 GrSTWHint_t;
#define GR_STWHINT_W_DIFF_FBI   FXBIT(0)
#define GR_STWHINT_W_DIFF_TMU0  FXBIT(1)
#define GR_STWHINT_ST_DIFF_TMU0 FXBIT(2)
#define GR_STWHINT_W_DIFF_TMU1  FXBIT(3)
#define GR_STWHINT_ST_DIFF_TMU1 FXBIT(4)
#define GR_STWHINT_W_DIFF_TMU2  FXBIT(5)
#define GR_STWHINT_ST_DIFF_TMU2 FXBIT(6)

#define GR_CONTROL_ACTIVATE             1
#define GR_CONTROL_DEACTIVATE           0

#define GrState                         void

/*
** move the vertex layout defintion to application
*/
typedef struct {
  float  sow;                   /* s texture ordinate (s over w) */
  float  tow;                   /* t texture ordinate (t over w) */
  float  oow;                   /* 1/w (used mipmapping - really 0xfff/w) */
}  GrTmuVertex;


#if FX_USE_PARGB

typedef struct
{
  float x, y;         /* X and Y in screen space */
  float ooz;          /* 65535/Z (used for Z-buffering) */
  float oow;          /* 1/W (used for W-buffering, texturing) */
  FxU32 argb;         /* R, G, B, A [0..255.0] */
  GrTmuVertex         tmuvtx[GLIDE_NUM_TMU];
  float z;            /* Z is ignored */
} GrVertex;

#define GR_VERTEX_X_OFFSET              0
#define GR_VERTEX_Y_OFFSET              1
#define GR_VERTEX_OOZ_OFFSET            2
#define GR_VERTEX_OOW_OFFSET            3
#define GR_VERTEX_PARGB_OFFSET          4
#define GR_VERTEX_SOW_TMU0_OFFSET       5
#define GR_VERTEX_TOW_TMU0_OFFSET       6
#define GR_VERTEX_OOW_TMU0_OFFSET       7
#define GR_VERTEX_SOW_TMU1_OFFSET       8
#define GR_VERTEX_TOW_TMU1_OFFSET       9
#define GR_VERTEX_OOW_TMU1_OFFSET       10
#define GR_VERTEX_Z_OFFSET              11

#define GET_PARGB(v)    ((FxU32*)(v))[GR_VERTEX_PARGB_OFFSET]
/* GET_PA: returns the alpha component */
#if GLIDE_ENDIAN == GLIDE_ENDIAN_BIG
   #define GET_PA(v)            ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4]
#else
   #define GET_PA(v)            ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4+3]
#endif
#define MESACOLOR2PARGB(c)      (c[ACOMP] << 24 | c[GCOMP] << 16 | c[GCOMP] << 8 | c[BCOMP])
#define PACK_4F_ARGB(dest,a,r,g,b) {                                                            \
                                             const GLuint cr = (int)r;                          \
                                             const GLuint cg = (int)g;                          \
                                             const GLuint ca = (int)a;                          \
                                             const GLuint cb = (int)b;                          \
                                             dest = ca << 24 | cr << 16 | cg << 8 | cb;         \
                                        }

#else /* FX_USE_PARGB */

typedef struct
{
  float x, y, z;                /* X, Y, and Z of scrn space -- Z is ignored */
  float r, g, b;                /* R, G, B, ([0..255.0]) */
  float ooz;                    /* 65535/Z (used for Z-buffering) */
  float a;                      /* Alpha [0..255.0] */
  float oow;                    /* 1/W (used for W-buffering, texturing) */
  GrTmuVertex  tmuvtx[GLIDE_NUM_TMU];
} GrVertex;

#define GR_VERTEX_X_OFFSET              0
#define GR_VERTEX_Y_OFFSET              1
#define GR_VERTEX_Z_OFFSET              2
#define GR_VERTEX_R_OFFSET              3
#define GR_VERTEX_G_OFFSET              4
#define GR_VERTEX_B_OFFSET              5
#define GR_VERTEX_OOZ_OFFSET            6
#define GR_VERTEX_A_OFFSET              7
#define GR_VERTEX_OOW_OFFSET            8
#define GR_VERTEX_SOW_TMU0_OFFSET       9
#define GR_VERTEX_TOW_TMU0_OFFSET       10
#define GR_VERTEX_OOW_TMU0_OFFSET       11
#define GR_VERTEX_SOW_TMU1_OFFSET       12
#define GR_VERTEX_TOW_TMU1_OFFSET       13
#define GR_VERTEX_OOW_TMU1_OFFSET       14
#endif /* FX_USE_PARGB */

#endif


/*
 * Glide2 functions for Glide3
 */
#if defined(FX_GLIDE3)
#define FX_grTexDownloadTable(TMU,type,data)    \
  do {                                          \
    BEGIN_BOARD_LOCK();                         \
    grTexDownloadTable(type,data);              \
    END_BOARD_LOCK();                           \
  } while (0);
#define FX_grTexDownloadTable_NoLock(TMU,type,data) \
  grTexDownloadTable(type, data)
#else
#define FX_grTexDownloadTable(TMU,type,data)    \
  do {                                          \
    BEGIN_BOARD_LOCK();                         \
    grTexDownloadTable(TMU,type,data);          \
    END_BOARD_LOCK();                           \
  } while (0);
#define FX_grTexDownloadTable_NoLock grTexDownloadTable
#endif

/*
 * Flush
 */
#if defined(FX_GLIDE3)
#define FX_grFlush()    \
  do {                  \
    BEGIN_BOARD_LOCK(); \
    grFlush();          \
    END_BOARD_LOCK();   \
  } while (0)
#else
#define FX_grFlush()    \
  do {                  \
    BEGIN_BOARD_LOCK(); \
    grSstIdle();        \
    END_BOARD_LOCK();   \
  } while (0)
#endif

#define FX_grFinish()   \
  do {                  \
    BEGIN_BOARD_LOCK(); \
    grFinish();         \
    END_BOARD_LOCK();   \
  } while (0)

/*
 * Write region: ToDo possible exploit the PixelPipe parameter.
 */
#if defined(FX_GLIDE3)
#define FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)         \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,FXFALSE,src_stride,src_data);       \
    END_BOARD_LOCK();           \
  } while(0)
#else
#define FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)         \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data);               \
    END_BOARD_LOCK();           \
  } while (0)
#endif

/*
 * Read region
 */
#define FX_grLfbReadRegion(src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data)                     \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grLfbReadRegion(src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data);                           \
    END_BOARD_LOCK();           \
  } while (0);

/*
 * Draw triangle
 */
#define FX_grDrawTriangle(a,b,c)        \
  do {                                  \
    BEGIN_CLIP_LOOP();                  \
    grDrawTriangle(a,b,c);              \
    END_CLIP_LOOP();                    \
  } while (0)

/*
 * For Lod/LodLog2 conversion.
 */
#if defined(FX_GLIDE3)
        #define FX_largeLodLog2(info)           (info).largeLodLog2
#else
        #define FX_largeLodLog2(info)           (info).largeLod
#endif

#if defined(FX_GLIDE3)
        #define FX_aspectRatioLog2(info)                (info).aspectRatioLog2
#else
        #define FX_aspectRatioLog2(info)                (info).aspectRatio
#endif

#if defined(FX_GLIDE3)
        #define FX_smallLodLog2(info)           (info).smallLodLog2
#else
        #define FX_smallLodLog2(info)           (info).smallLod
#endif

#if defined(FX_GLIDE3)
        #define FX_lodToValue(val)              ((int)(GR_LOD_256-val))
#else
        #define FX_lodToValue(val)              ((int)(val))
#endif

#if defined(FX_GLIDE3)
        #define FX_largeLodValue(info)          ((int)(GR_LOD_256-(info).largeLodLog2))
#else
        #define FX_largeLodValue(info)          ((int)(info).largeLod)
#endif
#define FX_largeLodValue_NoLock FX_largeLodValue

#if defined(FX_GLIDE3)
        #define FX_smallLodValue(info)          ((int)(GR_LOD_256-(info).smallLodLog2))
#else
        #define FX_smallLodValue(info)          ((int)(info).smallLod)
#endif
#define FX_smallLodValue_NoLock FX_smallLodValue

#if defined(FX_GLIDE3)
        #define FX_valueToLod(val)              ((GrLOD_t)(GR_LOD_256-val))
#else
        #define FX_valueToLod(val)              ((GrLOD_t)(val))
#endif

/*
 * ScreenWidth/Height stuff.
 */
        extern int FX_grSstScreenWidth(void);
        extern int FX_grSstScreenHeight(void);



/*
 * Version string.
 */
#if defined(FX_GLIDE3)
        extern void FX_grGlideGetVersion(char *buf);
#else
        #define FX_grGlideGetVersion(b) \
        do {                            \
          BEGIN_BOARD_LOCK();           \
          grGlideGetVersion(b);         \
          END_BOARD_LOCK();             \
        } while (0)
#endif
/*
 * Performance statistics
 */
#if defined(FX_GLIDE3)
        extern void FX_grSstPerfStats(GrSstPerfStats_t *st);
#else
        #define FX_grSstPerfStats(s)    \
        do {                            \
          BEGIN_BOARD_LOCK();           \
          grSstPerfStats(s);            \
          END_BOARD_LOCK();             \
        } while (0)
#endif

/*
 * Hardware Query
 */
       extern int FX_grSstQueryHardware(GrHwConfiguration *config);

/*
 * GrHints
 */
#if defined(FX_GLIDE3)
        extern void FX_grHints_NoLock(GrHint_t hintType, FxU32 hintMask);
        extern void FX_grHints(GrHint_t hintType, FxU32 hintMask);
#else
        #define FX_grHints(t,m)         \
        do {                            \
          BEGIN_BOARD_LOCK();           \
          grHints(t, m);                \
          END_BOARD_LOCK();             \
        } while(0)
        #define FX_grHints_NoLock grHints
#endif
/*
 * Antialiashed line+point drawing.
 */
#if defined(FX_GLIDE3)
        extern void FX_grAADrawLine(GrVertex *a,GrVertex *b);
#else
        #define FX_grAADrawLine(a,b)    \
        do {                            \
          BEGIN_CLIP_LOOP();            \
          grAADrawLine(a,b);            \
          END_CLIP_LOOP();              \
        } while (0)
#endif

#if defined(FX_GLIDE3)
        extern void FX_grAADrawPoint(GrVertex *a);
#else
        #define FX_grAADrawPoint(a)     \
        do {                            \
          BEGIN_CLIP_LOOP();            \
          grAADrawPoint(a);             \
          END_CLIP_LOOP();              \
        } while (0)
#endif

/*
 * Needed for Glide3 only, to set up Glide2 compatible vertex layout.
 */
#if defined(FX_GLIDE3)
        extern void FX_setupGrVertexLayout(void);
#else
        #define FX_setupGrVertexLayout()                do {} while (0)
#endif
/*
 * grSstControl stuff
 */
extern FxBool FX_grSstControl(FxU32 code);

/*
 * grGammaCorrectionValue
 */
#if defined(FX_GLIDE3)
      extern void FX_grGammaCorrectionValue(float val);
#else
      #define FX_grGammaCorrectionValue(v)      \
      do {                                      \
        BEGIN_BOARD_LOCK();                     \
        grGammaCorrectionValue(v)               \
        END_BOARD_LOCK();                       \
      } while (0)
#endif

#if defined(FX_GLIDE3)
#define FX_grSstWinClose(w)     \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grSstWinClose(w);           \
    END_BOARD_LOCK();           \
  } while (0)
#else
#define FX_grSstWinClose(w)     \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grSstWinClose();            \
    END_BOARD_LOCK();           \
  } while (0)
#endif


extern FX_GrContext_t FX_grSstWinOpen( FxU32                hWnd,
                                       GrScreenResolution_t screen_resolution,
                                       GrScreenRefresh_t    refresh_rate,
                                       GrColorFormat_t      color_format,
                                       GrOriginLocation_t   origin_location,
                                       int                  nColBuffers,
                                       int                  nAuxBuffers);


#define FX_grDrawLine(v1, v2)   \
  do {                          \
    BEGIN_CLIP_LOOP();          \
    grDrawLine(v1, v2);         \
    END_CLIP_LOOP();            \
  } while (0)

#define FX_grDrawPoint(p)       \
  do {                          \
    BEGIN_CLIP_LOOP();          \
    grDrawPoint(p);             \
    END_CLIP_LOOP();            \
  } while (0)

#if defined(FX_GLIDE3)
extern void FX_grDrawPolygonVertexList(int n, GrVertex *v);
#else
#define FX_grDrawPolygonVertexList(n, v)        \
  do {                                          \
    BEGIN_CLIP_LOOP();                          \
    grDrawPolygonVertexList(n, v);              \
    END_CLIP_LOOP();                            \
  } while (0)
#endif

#define FX_grDitherMode(m)      \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grDitherMode(m);            \
    END_BOARD_LOCK();           \
  } while (0)

#define FX_grRenderBuffer(b)    \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grRenderBuffer(b);          \
    END_BOARD_LOCK();           \
  } while (0)

#define FX_grBufferClear(c, a, d)       \
  do {                                  \
    BEGIN_CLIP_LOOP();                  \
    grBufferClear(c, a, d);             \
    END_CLIP_LOOP();                    \
  } while (0)

#define FX_grDepthMask(m)       \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grDepthMask(m);             \
    END_BOARD_LOCK();           \
  } while (0)

#define FX_grColorMask(c, a)    \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grColorMask(c, a);          \
    END_BOARD_LOCK();           \
  } while (0)

extern FxBool FX_grLfbLock(GrLock_t type, GrBuffer_t buffer,
                           GrLfbWriteMode_t writeMode,
                           GrOriginLocation_t origin, FxBool pixelPipeline,
                           GrLfbInfo_t *info );

#define FX_grLfbUnlock(t, b)    \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grLfbUnlock(t, b);          \
    END_BOARD_LOCK();           \
  } while (0)

#define FX_grConstantColorValue(v)      \
  do {                                  \
    BEGIN_BOARD_LOCK();                 \
    grConstantColorValue(v);            \
    END_BOARD_LOCK();                   \
  } while (0)

#define FX_grConstantColorValue_NoLock grConstantColorValue

#define FX_grAADrawTriangle(a, b, c, ab, bc, ca)        \
  do {                                                  \
    BEGIN_CLIP_LOOP();                                  \
    grAADrawTriangle(a, b, c, ab, bc, ca);              \
    END_CLIP_LOOP();                                    \
  } while (0)

#define FX_grAlphaBlendFunction(rs, rd, as, ad) \
  do {                                          \
    BEGIN_BOARD_LOCK();                         \
    grAlphaBlendFunction(rs, rd, as, ad);       \
    END_BOARD_LOCK();                           \
  } while (0)

#define FX_grAlphaCombine(func, fact, loc, oth, inv)    \
  do {                                                  \
    BEGIN_BOARD_LOCK();                                 \
    grAlphaCombine(func, fact, loc, oth, inv);          \
    END_BOARD_LOCK();                                   \
  } while (0)

#define FX_grAlphaCombine_NoLock grAlphaCombine

#define FX_grAlphaTestFunction(f)       \
  do {                                  \
    BEGIN_BOARD_LOCK();                 \
    grAlphaTestFunction(f);             \
    END_BOARD_LOCK();                   \
  } while (0)

#define FX_grAlphaTestReferenceValue(v) \
  do {                                  \
    BEGIN_BOARD_LOCK();                 \
    grAlphaTestReferenceValue(v);       \
    END_BOARD_LOCK();                   \
  } while (0)

#define FX_grClipWindow(minx, miny, maxx, maxy) \
  do {                                          \
    BEGIN_BOARD_LOCK();                         \
    grClipWindow(minx, miny, maxx, maxy);       \
    END_BOARD_LOCK();                           \
  } while (0)

#define FX_grClipWindow_NoLock grClipWindow

#define FX_grColorCombine(func, fact, loc, oth, inv)    \
  do {                                                  \
    BEGIN_BOARD_LOCK();                                 \
    grColorCombine(func, fact, loc, oth, inv);          \
    END_BOARD_LOCK();                                   \
  } while (0)

#define FX_grColorCombine_NoLock grColorCombine

#define FX_grCullMode(m)        \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grCullMode(m);              \
    END_BOARD_LOCK();           \
  } while (0)

#define FX_grDepthBiasLevel(lev)        \
  do {                                  \
    BEGIN_BOARD_LOCK();                 \
    grDepthBiasLevel(lev);              \
    END_BOARD_LOCK();                   \
  } while (0)

#define FX_grDepthBufferFunction(func)  \
  do {                                  \
    BEGIN_BOARD_LOCK();                 \
    grDepthBufferFunction(func);        \
    END_BOARD_LOCK();                   \
  } while (0)

#define FX_grFogColorValue(c)           \
  do {                                  \
    BEGIN_BOARD_LOCK();                 \
    grFogColorValue(c);                 \
    END_BOARD_LOCK();                   \
  } while (0)

#define FX_grFogMode(m) \
  do {                  \
    BEGIN_BOARD_LOCK(); \
    grFogMode(m);       \
    END_BOARD_LOCK();   \
  } while (0)

#define FX_grFogTable(t)        \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grFogTable(t);              \
    END_BOARD_LOCK();           \
  } while (0)

#define FX_grTexClampMode(t, sc, tc)    \
  do {                                  \
    BEGIN_BOARD_LOCK();                 \
    grTexClampMode(t, sc, tc);          \
    END_BOARD_LOCK();                   \
  } while (0)

#define FX_grTexClampMode_NoLock grTexClampMode

#define FX_grTexCombine(t, rfunc, rfact, afunc, afact, rinv, ainv)      \
  do {                                                                  \
    BEGIN_BOARD_LOCK();                                                 \
    grTexCombine(t, rfunc, rfact, afunc, afact, rinv, ainv);            \
    END_BOARD_LOCK();                                                   \
  } while (0)

#define FX_grTexCombine_NoLock grTexCombine

#define FX_grTexDownloadMipMapLevel(t, sa, tlod, llod, ar, f, eo, d)    \
  do {                                                                  \
    BEGIN_BOARD_LOCK();                                                 \
    grTexDownloadMipMapLevel(t, sa, tlod, llod, ar, f, eo, d);          \
    END_BOARD_LOCK();                                                   \
  } while (0)

#define FX_grTexDownloadMipMapLevel_NoLock grTexDownloadMipMapLevel

#define FX_grTexDownloadMipMapLevelPartial(t, sa, tlod, llod, ar, f, eo, d, s, e);      \
  do {                                                                      \
    BEGIN_BOARD_LOCK();                                                     \
    grTexDownloadMipMapLevelPartial(t, sa, tlod, llod, ar, f, eo, d, s, e); \
    END_BOARD_LOCK();                                                       \
  } while (0)

#define FX_grTexFilterMode(t, minf, magf)       \
  do {                                          \
    BEGIN_BOARD_LOCK();                         \
    grTexFilterMode(t, minf, magf);             \
    END_BOARD_LOCK();                           \
  } while (0)

#define FX_grTexFilterMode_NoLock grTexFilterMode

extern FxU32 FX_grTexMinAddress(GrChipID_t tmu);
extern FxU32 FX_grTexMaxAddress(GrChipID_t tmu);

#define FX_grTexMipMapMode(t, m, lod)   \
  do {                                  \
    BEGIN_BOARD_LOCK();                 \
    grTexMipMapMode(t, m, lod);         \
    END_BOARD_LOCK();                   \
  } while (0)

#define FX_grTexMipMapMode_NoLock grTexMipMapMode

#define FX_grTexSource(t, sa, eo, i)    \
  do {                                  \
    BEGIN_BOARD_LOCK();                 \
    grTexSource(t, sa, eo, i);          \
    END_BOARD_LOCK();                   \
  } while (0)

#define FX_grTexSource_NoLock grTexSource

extern FxU32 FX_grTexTextureMemRequired(FxU32 evenOdd, GrTexInfo *info);
#define FX_grTexTextureMemRequired_NoLock grTexTextureMemRequired

#define FX_grGlideGetState(s)   \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grGlideGetState(s);         \
    END_BOARD_LOCK();           \
  } while (0)
#define FX_grGlideGetState_NoLock(s) grGlideGetState(s);

#define FX_grDRIBufferSwap(i)   \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grDRIBufferSwap(i);         \
    END_BOARD_LOCK();           \
  } while (0)

#define FX_grSstSelect(b)       \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grSstSelect(b);             \
    END_BOARD_LOCK();           \
  } while (0)

#define FX_grSstSelect_NoLock grSstSelect

#define FX_grGlideSetState(s)   \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grGlideSetState(s);         \
    END_BOARD_LOCK();           \
  } while (0)
#define FX_grGlideSetState_NoLock(s) grGlideSetState(s);

#define FX_grDepthBufferMode(m) \
  do {                          \
    BEGIN_BOARD_LOCK();         \
    grDepthBufferMode(m);       \
    END_BOARD_LOCK();           \
  } while (0)

#define FX_grLfbWriteColorFormat(f)     \
  do {                                  \
    BEGIN_BOARD_LOCK();                 \
    grLfbWriteColorFormat(f);           \
    END_BOARD_LOCK();                   \
  } while (0)

#define FX_grDrawVertexArray(m, c, p)   \
  do {                                  \
    BEGIN_CLIP_LOOP();                  \
    grDrawVertexArray(m, c, p);         \
    END_CLIP_LOOP();                    \
  } while (0)

#define FX_grGlideShutdown()            \
  do {                                  \
    BEGIN_CLIP_LOOP();                  \
    grGlideShutdown();                  \
    END_CLIP_LOOP();                    \
  } while (0)

#define FX_grGlideInit_NoLock grGlideInit
#define FX_grSstWinOpen_NoLock grSstWinOpen

extern int FX_getFogTableSize(void);
extern int FX_getGrStateSize(void);

#endif /* __FX_GLIDE_WARPER__ */

