Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2519 lines
97 KiB

/******************************Module*Header**********************************\
*
* *******************
* * GDI SAMPLE CODE *
* *******************
*
* Module Name: glint.h
*
* Content: Defines and macros for interfacing to the GLINT hardware.
*
* Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#ifndef _GLINT_H_
#define _GLINT_H_
#include <gtag.h>
//#include "glintmsg.h"
#include <glintdef.h>
// USE_SYNC_FUNCTION must be set at the moment for error free builds. The macro
// version requires #including <pxrx.h> which would make re-builds a nightmare.
// On more important issues, there is nomeasurable loss of speed but the driver
// is a fair bit smaller.
#define USE_SYNC_FUNCTION 1
// when enabled, most of the DDI entrypoints in THUNK.C check whether the base viewable scanline
// variables in DEBUG4.C have been modified, allowing the scanline view to be updated
#define SET_VIEW_MEMORY_ENABLED 0
#if DBG && SET_VIEW_MEMORY_ENABLED
extern void DebugCheckMemoryView(PPDEV ppdev);
#define CHECK_MEMORY_VIEW(ppdev)
#else
#define CHECK_MEMORY_VIEW(ppdev)
#endif
#define COLLECT_TEXT_STATS 0
#if COLLECT_TEXT_STATS
struct TextStats
{
ULONG aGlyphWidthBytesCached[9]; // [0] = 1 byte, [1] = 2 bytes, ... [7] = 8 bytes, [8] > 8 bytes
ULONG cCacheableStrings;
ULONG cUncacheableStrings;
ULONG cGlyphsCached;
ULONG cGlyphTotalBytesCached;
ULONG meanGlyphBytesCached;
ULONG cProportionalGlyphs;
ULONG cProportionalStrings;
ULONG meanProportionalGlyphsPerString;
ULONG cFixedGlyphs;
ULONG cFixedStrings;
ULONG meanFixedGlyphsPerString;
ULONG cClippedGlyphs;
ULONG cClippedStrings;
ULONG meanClippedGlyphsPerString;
ULONG cAllocedFonts;
ULONG cFreedFonts;
ULONG cBlownCaches;
};
extern struct TextStats gts;
#define STAT_CACHEABLE_STRING ++gts.cCacheableStrings
#define STAT_UNCACHEABLE_STRING ++gts.cUncacheableStrings
#define STAT_CACHING_GLYPH(cxGlyphAligned, cyGlyph) \
do \
{ \
++gts.cGlyphsCached; \
gts.cGlyphTotalBytesCached += (cxGlyphAligned >> 3) * cyGlyph; \
gts.meanGlyphBytesCached = gts.cGlyphTotalBytesCached / gts.cGlyphsCached; \
++gts.aGlyphWidthBytesCached[(cxGlyphAligned >> 3) > 8 ? 8 : (cxGlyphAligned >> 3) - 1]; \
} \
while(0)
#define STAT_PROPORTIONAL_TEXT(cGlyph) \
do \
{ \
gts.cProportionalGlyphs += cGlyph; \
++gts.cProportionalStrings; \
gts.meanProportionalGlyphsPerString = gts.cProportionalGlyphs / gts.cProportionalStrings; \
} \
while(0)
#define STAT_FIXED_TEXT(cGlyph) \
do \
{ \
gts.cFixedGlyphs += cGlyph; \
++gts.cFixedStrings; \
gts.meanFixedGlyphsPerString = gts.cFixedGlyphs / gts.cFixedStrings; \
} \
while(0)
#define STAT_CLIPPED_TEXT(cGlyph) \
do \
{ \
gts.cClippedGlyphs += cGlyph; \
++gts.cClippedStrings; \
gts.meanClippedGlyphsPerString = gts.cClippedGlyphs / gts.cClippedStrings; \
} \
while(0)
#define STAT_ALLOC_FONT ++gts.cAllocedFonts
#define STAT_FREE_FONT ++gts.cFreedFonts
#define STAT_BLOW_CACHE ++gts.cBlownCaches
#else
#define STAT_CACHEABLE_STRING
#define STAT_UNCACHEABLE_STRING
#define STAT_CACHING_GLYPH(cxGlyphAligned, cyGlyph)
#define STAT_PROPORTIONAL_TEXT(cGlyph)
#define STAT_FIXED_TEXT(cGlyph)
#define STAT_CLIPPED_TEXT(cGlyph)
#define STAT_ALLOC_FONT
#define STAT_FREE_FONT
#define STAT_BLOW_CACHE
#endif
#define DMA_DRIVEN_2D 0
#define GLINT_LOCKUP_TIMEOUT 0
#define GAMMA_CORRECTION 1
#define COLORIFIC_GAMMA_CORRECTION 1
/*
* USE_PCI_DISC_PERM
* -----------------
*
* Set USE_PCI_DISC_PERM to 1 for PCI disconnect on permanently or set to 0 for
* disconnect off permanently. ( Set to 1 to try and speed things up , set to 0
* on Alphas which are sensitive ).
*/
#if defined(_X86_)
#define USE_PCI_DISC_PERM 1
#else // _X86_
#define USE_PCI_DISC_PERM 0
#endif // _X86_
// DMA text rendering gives me a 1 winmark improvement on my P6 200 at 8 & 15bpp, but gives
// no improvement at these depths on a Pentium II 300 and might actually be 1 winmark slower
// at 32bpp
#define ENABLE_DMA_TEXT_RENDERING 0
/********************************************************************************/
// Texture memory allocation macros and structures are in 3DPrivTx.h
// definition of handle to a memory region
typedef LONG HMEMREGION;
typedef LONG HMEMCACHE;
typedef enum {RESIDENCY_NOTLOADED, RESIDENCY_PERMANENT, RESIDENCY_TRANSIENT, RESIDENCY_HOST, RESIDENCY_PERMANENT2} MEM_MGR_RESIDENCY;
/********************************************************************************/
/*** DrvEscape commands ***/
#define GLINT_SET_SCANLINE 6000 // Temporary define for setting the displayed scanline (Permedia specific)
#define GLINT_GET_RAMDAC_LUT 6001 // Temporary define for getting the RAMDACs LUT
#define GLINT_SET_RAMDAC_LUT 6002 // Temporary define for getting the RAMDACs LUT
#define GLINT_SET_SAME_VIDEO_MODE 6003 // Temporary define for getting the RAMDACs LUT
// Monitor DDC support:
#define GLINT_QUERY_MONITOR_INFO 6004
#define GLINT_MULTIMON_CMD 6007
#define GLINT_GET_SOFT_ENGINE_INFO 6009
// Debug only escapes:
#define GLINT_DBG_GET_FRAMEBUFFER 6008
#define GLINT_DBG_TEST_PXRX_DMA 6010
/*** DrvDrawEscape commands ***/
#define GLINT_DBG_SEND_TAGS 10238
#define GLINT_DBG_SET_DEBUG 10239
//
// various GLINT devices and revisions
//
#define VENDOR_ID_3DLABS 0x3D3D
#define VENDOR_ID_TI 0x104C
#define GLINT_300SX_ID 0x0001
#define GLINT_500TX_ID 0x0002
#define GLINT_DELTA_ID 0x0003
#define PERMEDIA_ID 0x0004
#define PERMEDIA_P1_ID 0x3D04
#define GLINT_MX_ID 0x0006
#define PERMEDIA2_ID 0x0007 // 3Dlabs Permedia 2
#define PERMEDIA_P2_ID 0x3D07 // TI Permedia 2
#define GLINT_GAMMA_ID 0x0008
#define PERMEDIA_P2S_ID 0x0009 // 3Dlabs Permedia 2ST
#define PERMEDIA3_ID 0x000A
#define GLINT_R3_ID 0x000B
#define PERMEDIA4_ID 0x000C
#define GLINT_R4_ID 0x000D
#define DEVICE_FAMILY_ID(id) ((id) & 0xff)
#define GLINT_DEVICE_SX GLINT_300SX_ID
#define GLINT_DEVICE_TX GLINT_500TX_ID
#define GLINT_DEVICE_MX GLINT_MX_ID
#define GLINT_DEVICE_FX PERMEDIA_ID
#define GLINT_DEVICE_P2 PERMEDIA2_ID
#define GLINT_DEVICE_P2S PERMEDIA_P2S_ID
#define GLINT_DEVICE_P3 PERMEDIA3_ID
#define GLINT_DEVICE_P4 PERMEDIA4_ID
#define GLINT_DEVICE_R3 GLINT_R3_ID
#define GLINT_DEVICE_R4 GLINT_R4_ID
#define GLINT_300SX_REV_1 0x0000
#define GLINT_300SX_REV_2 0x0002
#define GLINT_500TX_REV_1 0x0001
#define GLINT_DELTA_REV_1 0x0001
#define GLINT_PERMEDIA_REV_1 0x0001
#define GLINT_REVISION_SX_1 GLINT_300SX_REV_1
#define GLINT_REVISION_SX_2 GLINT_300SX_REV_2
#define GLINT_REVISION_TX_1 GLINT_500TX_REV_1
#define GLINT_REVISION_1 GLINT_REVISION_SX_1
#define GLINT_REVISION_2 GLINT_REVISION_SX_2
//
// Supported board definitions. Must be the same as in the miniport
//
typedef enum _GLINT_BOARDS {
GLINT_MONTSERRAT = 0,
GLINT_RACER,
DENSAN_300SX,
ACCELR8_BOARD,
ACCELPRO_BOARD,
OMNICOMP_SX88,
PERMEDIA_BOARD,
PERMEDIA_NT_BOARD,
PERMEDIA_LC_BOARD,
DUALTX_MENTOR_BOARD,
DUALTX_SYMMETRIC_BOARD,
ELSA_GLORIA,
PERMEDIA2_BOARD,
OMNICOMP_3DEMONPRO,
GEO_TWIN_BOARD,
GLINT_RACER_PRO,
ELSA_GLORIA_XL,
PERMEDIA3_BOARD,
MAX_GLINT_BOARD
} GLINT_BOARDS;
//
// Supported RAMDAC definitions. Must be the same as in the miniport
//
typedef enum _GLINT_RAMDACS {
RGB525_RAMDAC = 0,
RGB526_RAMDAC,
RGB526DB_RAMDAC,
RGB528_RAMDAC,
RGB528A_RAMDAC,
RGB624_RAMDAC,
RGB624DB_RAMDAC,
RGB640_RAMDAC,
TVP3026_RAMDAC,
TVP3030_RAMDAC,
RGB524_RAMDAC,
RGB524A_RAMDAC,
TVP4020_RAMDAC,
P2RD_RAMDAC,
P3RD_RAMDAC,
MAX_GLINT_RAMDAC
} GLINT_RAMDACS;
// extern declarations
extern DWORD GlintLogicOpsFromR2[]; // translates GDI rop2 to GLINT logic op mode word
extern DWORD LogicopReadDest[]; // indicates which logic ops need dest read turned on
// values for flags in GlintDataRec
//
typedef enum {
GLICAP_NT_CONFORMANT_LINES = 0x00000001, // draw NT conformant lines
GLICAP_HW_WRITE_MASK = 0x00000002, // hardware planemasking
GLICAP_COLOR_SPACE_DBL_BUF = 0x00000004, // interleaved nibbles
GLICAP_BITBLT_DBL_BUF = 0x00000008, // dbl buf by bitblt
GLICAP_FULL_SCREEN_DBL_BUF = 0x00000010, // hardware can dbl buf
GLICAP_FIX_FAST_FILLS = 0x00000020, // workaround fast fill bug
GLICAP_INTERRUPT_DMA = 0x00000080, // interrupt driven DMA
GLICAP_RACER_BANK_SELECT = 0x00000100, // FS dbl buf uses Racer h/w
GLICAP_FIX_4MB_FAST_FILLS = 0x00000200, // fix blk fill above 4MB
GLICAP_RACER_DOUBLE_WRITE = 0x00000400, // Can double write
GLICAP_ENHANCED_TX_BANK_SELECT = 0x00000800, // Enhanced TX FS dbl buf
GLICAP_HW_WRITE_MASK_BYTES = 0x00001000, // hardware planemasking is bytewise only
GLICAP_STEREO_BUFFERS = 0x00002000, // stereo buffers allocated
} GLINT_CAPS;
//@@BEGIN_DDKSPLIT
// TMM: In the good old days we used to leave the screen scissor enabled
// as a safety-net, however, the screen scissor doesn't work when uploading
// data at 1280 or 1170 screen widths, so I've disabled it.
//@@END_DDKSPLIT
#define SCREEN_SCISSOR_DEFAULT (0 << 1)
// Currently we support the main display and up to 3 off-screen buffers.
//
#define GLINT_NUM_SCREEN_BUFFERS 4
// currently we support software cursors up to this width and height. This is
// to ensure that we have enough off-screen memory to save the shapes and save
// unders.
//
#define SOFTWARE_POINTER_SIZE 32
// this structure contains the addresses of all the GLINT registers that we
// want to write to. It is used by any macro/functions which needs to talk to
// the GLINT chip. We precompute these addresses so that we get faster access
// on DEC Alpha machines.
//
typedef struct _glint_reg_addrs {
// Most commonly used non-FIFO registers
ULONG * InFIFOSpace;
ULONG * OutFIFOWords;
ULONG * OutFIFOWordsOdd;
ULONG * DMAControl;
ULONG * OutDMAAddress; // P2 only
ULONG * OutDMACount; // P2 only
ULONG * ByDMAAddress; // P2 only
ULONG * ByDMAStride; // P2 only
ULONG * ByDMAMemAddr; // P2 only
ULONG * ByDMASize; // P2 only
ULONG * ByDMAByteMask; // P2 only
ULONG * ByDMAControl; // P2 only
ULONG * ByDMAComplete; // P2 only
ULONG * DMAAddress;
ULONG * DMACount;
ULONG * InFIFOInterface;
ULONG * OutFIFOInterface;
ULONG * OutFIFOInterfaceOdd;
ULONG * FBModeSel;
ULONG * FBModeSelOdd;
ULONG * IntFlags;
ULONG * DeltaIntFlags;
// PERMEDIA
ULONG * ScreenBase;
ULONG * ScreenBaseRight;
ULONG * LineCount;
ULONG * VbEnd;
ULONG * VideoControl;
ULONG * MemControl;
// GAMMA
ULONG * GammaChipConfig;
ULONG * GammaCommandMode;
ULONG * GammaCommandIntEnable;
ULONG * GammaCommandIntFlags;
ULONG * GammaCommandErrorFlags;
ULONG * GammaCommandStatus;
ULONG * GammaFeedbackSelectCount;
ULONG * GammaProcessorMode;
ULONG * GammaMultiGLINTAperture;
// Core FIFO registers
ULONG * tagwr[__MaximumGlintTagValue+1];
ULONG * tagrd[__MaximumGlintTagValue+1];
// Other control registers
ULONG * VTGHLimit;
ULONG * VTGHSyncStart;
ULONG * VTGHSyncEnd;
ULONG * VTGHBlankEnd;
ULONG * VTGHGateStart;
ULONG * VTGHGateEnd;
ULONG * VTGVLimit;
ULONG * VTGVSyncStart;
ULONG * VTGVSyncEnd;
ULONG * VTGVBlankEnd;
ULONG * VTGVGateStart;
ULONG * VTGVGateEnd;
ULONG * VTGPolarity;
ULONG * VTGVLineNumber;
ULONG * VTGFrameRowAddr;
ULONG * VTGFrameRowAddrOdd;
ULONG * LBMemoryCtl;
ULONG * LBMemoryEDO;
ULONG * FBMemoryCtl;
ULONG * IntEnable;
ULONG * DeltaIntEnable;
ULONG * ResetStatus;
ULONG * DisconnectControl;
ULONG * ErrorFlags;
ULONG * DeltaErrorFlags;
ULONG * VTGSerialClk;
ULONG * VTGSerialClkOdd;
ULONG * VClkCtl;
// Racer board has these extra registers external to GLINT
ULONG * RacerDoubleWrite;
ULONG * RacerBankSelect;
ULONG * VSConfiguration; // P2 only
// Omnicomp 3demonPro16 board has these extra registers external to GLINT
ULONG * DemonProDWAndStatus; // Pro 5000
ULONG * DemonProUBufB; // Pro 7000
// split framebuffer needs scanline ownership, FBWindowBase and LBWindowBase
// to be context switched.
ULONG * OddGlintScanlineOwnRd;
ULONG * OddGlintFBWindowBaseRd;
ULONG * OddGlintLBWindowBaseRd;
// Dual-TX needs area stipple to be different on both chips
ULONG * OddTXAreaStippleRd[32];
// PXRX
ULONG * TextureDownloadControl;
ULONG * AGPControl;
ULONG *LocalMemCaps;
ULONG *MemScratch;
ULONG *LocalMemProfileMask0;
ULONG *LocalMemProfileMask1;
ULONG *LocalMemProfileCount0;
ULONG *LocalMemProfileCount1;
ULONG *PXRXByAperture1Mode; // 0300h
ULONG *PXRXByAperture1Stride; // 0308h
// ULONG *PXRXByAperture1YStart; // 0310h
// ULONG *PXRXByAperture1UStart; // 0318h
// ULONG *PXRXByAperture1VStart; // 0320h
ULONG *PXRXByAperture2Mode; // 0328h
ULONG *PXRXByAperture2Stride; // 0330h
// ULONG *PXRXByAperture2YStart; // 0338h
// ULONG *PXRXByAperture2UStart; // 0340h
// ULONG *PXRXByAperture2VStart; // 0348h
ULONG *PXRXByDMAReadMode; // 0350h
ULONG *PXRXByDMAReadStride; // 0358h
// ULONG *PXRXByDMAReadYStart; // 0360h
// ULONG *PXRXByDMAReadUStart; // 0368h
// ULONG *PXRXByDMAReadVStart; // 0370h
ULONG *PXRXByDMAReadCommandBase; // 0378h
ULONG *PXRXByDMAReadCommandCount; // 0380h
// ULONG *PXRXByDMAWriteMode; // 0388h
// ULONG *PXRXByDMAWriteStride; // 0390h
// ULONG *PXRXByDMAWriteYStart; // 0398h
// ULONG *PXRXByDMAWriteUStart; // 03A0h
// ULONG *PXRXByDMAWriteVStart; // 03A8h
// ULONG *PXRXByDMAWriteCommandBase; // 03B0h
// ULONG *PXRXByDMAWriteCommandCount; // 03B8h
// Used for P3 for debug purposes, to examine fifo stages.
ULONG *TestOutputRdy;
ULONG *TestInputRdy;
} GlintRegAddrRec;
typedef struct _glint_packing_str {
DWORD readMode;
DWORD modeSel;
DWORD dxOffset;
} GlintPackingRec;
// Framebuffer Aperture Information: currently only of interest to GeoTwin
// boards to allow for upload DMA directly from FB0 to FB1 and vice versa
typedef struct FrameBuffer_Aperture_Info
{
LARGE_INTEGER pphysBaseAddr;
ULONG cjLength;
}
FBAPI;
// PCI device information. Used in an IOCTL return. Ensure this is the same
// as in the miniport drivers glint.h
typedef struct _Glint_Device_Info {
ULONG SubsystemId;
ULONG SubsystemVendorId;
ULONG VendorId;
ULONG DeviceId;
ULONG RevisionId;
ULONG DeltaRevId;
ULONG GammaRevId;
ULONG BoardId;
ULONG LocalbufferLength;
LONG LocalbufferWidth;
ULONG ActualDacId;
FBAPI FBAperture[2]; // Physical addresses for geo twin framebuffers
PVOID FBApertureVirtual [2]; // Virtual addresses for geo twin framebuffers
PVOID FBApertureMapped [2]; // Mapped physical/logical addresses for geo twin framebuffers
PUCHAR pCNB20;
LARGE_INTEGER pphysFrameBuffer; // physical address of the framebuffer (use FBAperture instead for geo twins)
} Glint_Device_Info;
#define GLINT_DELTA_PRESENT (glintInfo->deviceInfo.DeltaRevId != 0)
#define GLINT_GAMMA_PRESENT (glintInfo->deviceInfo.GammaRevId != 0)
// before we get Gamma we won't be able to test all the fancy new features,
// after Gamma arrives we'll enable them one at a time; this define allows us
// to do just that
#define USE_MINIMAL_GAMMA_FEATURES 1
typedef struct _Glint_SwPointer_Info {
LONG xOff[5], yOff[5]; // offsets into screen of the caches.
LONG PixelOffset; // pixel offsets into screen of the caches.
LONG x, y; // x, y position
LONG xHot, yHot; // Hotspot position
LONG width, height;
BOOL onScreen; // True if pointer is on screen
LONG saveCache; // The current saveunder cache
BOOL duplicateSaveCache; // Flag to indicate that save cache should be duplicated.
ULONG writeMask; // The write mask to use when saving and restoring.
DWORD *pDMA; // Pointer to a DMA buffer
ULONG windowBase; // Window base
DSURF* pdsurf; // Surface descriptors for caches
HSURF hsurf;
// Cached position of the pointer on the screen
ULONG scrXDom, scrXSub, scrY, scrCnt;
// Cached position of the save under cache
LONG cacheXDom[5], cacheXSub[5], cacheY[5], cacheCnt[5];
// Cached position of the visible pars of the save caches
LONG scrToCacheXDom[2], scrToCacheXSub[2], scrToCacheY[2], scrToCacheCnt[2];
// Cached offsets from the various caches.
LONG saveOffset[2], constructOffset, maskOffset, shapeOffset;
} Glint_SwPointer_Info;
// Definition of the IOCTL_VIDEO_QUERY_DMA_BUFFER
#define MAX_LINE_SIZE 8192 // No of bytes required to hold 1 complete scanline (i.e.,
// 6400 for 1600x1200x32).
#define DMA_LINEBUF_SIZE (MAX_LINE_SIZE * 2) // Size in bytes of 'pvTmpBuffer'.
// This has to be big enough to store 2 entire
// scan lines. I have increased the size from 1 line
// to 2 lines so that P2 can double buffer
// it's line uploads.
typedef struct GENERAL_DMA_BUFFER {
LARGE_INTEGER physAddr; // physical address of DMA buffer
PVOID virtAddr; // mapped virtual address
ULONG size; // size in bytes
BOOL cacheEnabled; // Whether buffer is cached
} GENERAL_DMA_BUFFER, *PGENERAL_DMA_BUFFER;
/*** NB: The PXRXdmaInfo structure is shared with the Miniport ***/
typedef struct PXRXdmaInfo_Tag {
ULONG scheme; // Used by the interrupt handler only
volatile ULONG hostInId; // Current internal HostIn id, used by the HIid DMA scheme
volatile ULONG fifoCount; // Current internal FIFO count, used by various DMA schemes
ULONG NTbuff; // Current buffer number (0 or 1)
ULONG *NTptr; // 32/64 bit ptr Last address written to by NT (but not necesserily the end of a completed buffer)
ULONG *NTdone; // 32/64 bit ptr Last address NT has finished with (end of a buffer, but not necessarily sent to P3 yet)
volatile ULONG *P3at; // 32/64 bit ptr Last address sent to the P3
volatile BOOL bFlushRequired; // Is a flush required to empty the FBwrite unit's cache?
ULONG *DMAaddrL[2]; // 32/64 bit ptr Linear address of the start of each DMA buffer
ULONG *DMAaddrEndL[2]; // 32/64 bit ptr Linear address of the end of each DMA buffer
ULONG DMAaddrP[2]; // 32 bit ptr Physical address of the start of each DMA buffer
ULONG DMAaddrEndP[2]; // 32 bit ptr Physical address of the end of each DMA buffer
} PXRXdmaInfo;
/*** NB: The PXRXdmaInfo structure is shared with the Miniport ***/
typedef struct _glint_data {
DWORD renderBits; // saved render bits set by setup routines
DWORD FBReadMode; // software copy of FBReadMode register
DWORD FBWriteMode; // software copy of FBWriteMode register
DWORD RasterizerMode; // software copy of the rasterizer mode
DWORD FBPacking; // software copy of FBModeSel
DWORD FBBlockColor; // software copy of FBBlockColor (P1 only)
DWORD TextureAddressMode; // software copy of TextureAddressMode (P2 only)
DWORD TextureReadMode; // software copy of TextureReadMode (P2 & MX only)
DWORD dSdx; // software copy of dSdx (MX only)
DWORD dTdyDom; // software copy of dTdyDom (MX only)
BOOL bGlintCoreBusy; // 2D flag: TRUE if core not synced
LONG currentPelSize; // Currently loaded frame store depth
ULONG currentCSbuffer;// color space buffer being displayed
GLINT_CAPS flags; // various flags
GlintRegAddrRec regs; // precomputed register addresses
GlintPackingRec packing[5]; // values to load for 4 packing formats (plus one unused)
LONG ddCtxtId; // id of the display drivers context
LONG fastFillBlockSz;// number of pixels per fast fill block
DWORD fastFillSupport;// render bits for rev 1 fast fill
DWORD renderFastFill; // render bits for rev 2+ fast fill
LONG PixelOffset; // last DFB pixel offset
ULONG MaxInFifoEntries;// maximum reported free entries FIFO download
ULONG CheckFIFO; // Non-zero if the FIFO has to be checked before loading it
ULONG PCIDiscEnabled; // Non-zero if PCI disconnect is enabled
ULONG BroadcastMask2D;// Primary chip broadcast mask
ULONG BroadcastMask3D;// broadcast mask to use for 3D contexts
LONG vtgvLimit; // copy of VTGVLimit register
LONG scanFudge; // how much to add onto VTGVLineNumber to
// get the current video scanline
OH * backBufferPoh; // heap handle for allocated back-buffer
OH * savedPoh; // handle to saved off-screen heap
ULONG GMX2KLastLine; // Last+1 line to be allocated
BOOLEAN offscreenEnabledOK; // Set to TRUE if off-screen enabled
ULONG bufferOffset[GLINT_NUM_SCREEN_BUFFERS];
// offset in pixels to the supported bufs
ULONG bufferRow[GLINT_NUM_SCREEN_BUFFERS];
// VTGFrameRowAddr for supported buffers
ULONG PerfScaleShift;
//ContextDumpData GammaContextMask;
ULONG HostOutBroadcastMask; // for Gamma output DMA
ULONG HostOutChipNumber; // for Gamma output DMA
#if GAMMA_CORRECTION
union {
UCHAR _clutBuffer[MAX_CLUT_SIZE];
VIDEO_CLUT gammaLUT; // saved gamma LUT contents
};
#endif
// interrupt command block.
struct _glint_interrupt_control *pInterruptCommandBlock;
// maximum number of sub buffers per DMA buffer.
ULONG MaxDMASubBuffers;
// Overlay support: WriteMask can be set around primitives so that
// they temporarily render thru this mask. Normally it must be set to -1.
// DefaultWriteMask is the write mask that should be used by the DD
// context by default, it takes into account overlay planes.
//
ULONG OverlayMode;
ULONG WriteMask;
ULONG TransparentColor; // pre-shifted so color is in top 8 bits
ULONG DefaultWriteMask;
// Indicates whether GDI is allowed to access the frame buffer. Always true
// on MIPS and ALPHA and true on all architectures in overlay mode.
ULONG GdiCantAccessFramebuffer;
ULONG OGLOverlaySavedGCAF;
// Configuration for texture and Z buffers
ULONG ZBufferWidth; // bits per pel
ULONG ZBufferOffset; // offset in pels
ULONG ZBufferSize; // size in pels
ULONG FontMemoryOffset; // offset in dwords
ULONG FontMemorySize; // size in dwords
ULONG TextureMemoryOffset; // offset in dwords
ULONG TextureMemorySize; // size in dwords
// On P3 due to patching restrictions the Z width
// may not match the framebuffer screen width.
ULONG P3RXLocalBufferWidth;
// PCI configuration id information
Glint_Device_Info deviceInfo;
// Software cursor information
Glint_SwPointer_Info swPointer;
// Line DMA buffer information
GENERAL_DMA_BUFFER LineDMABuffer;
GENERAL_DMA_BUFFER PXRXDMABuffer;
// Current input FIFO count from 0 to 1023
ULONG FifoCnt;
// PXRX specific stuff:
ULONG foregroundColour; // Software copies of various registers
ULONG backgroundColour; // Ditto
ULONG config2D; // Ditto
ULONG fbDestMode; // Ditto
ULONG fbDestAddr[4]; // Ditto
ULONG fbDestOffset[4]; // Ditto
ULONG fbDestWidth[4]; // Ditto
ULONG fbWriteMode; // Ditto
ULONG fbWriteAddr[4]; // Ditto
ULONG fbWriteWidth[4]; // ottiD
ULONG fbWriteOffset[4]; // Ditto
ULONG fbSourceAddr; // Ditto
ULONG fbSourceWidth; // ottiD
ULONG fbSourceOffset; // Ditto
ULONG lutMode; // Ditto
ULONG pxrxByDMAReadMode; // Ditto
ULONG lastLine; // Delta LineCoord0/1
ULONG savedConfig2D; // Config2D value that we use for integer lines
ULONG savedLOP; // LogicOp value that we use for lines
ULONG savedCol; // Colour value that we use for lines
RECTL * savedClip; // Clip rectangle that we use for lines
ULONG pxrxFlags; // General flags, see below
ULONG backBufferXY; // Offset to add to front buffer to get to the back buffer (for FBWriteBufferOffsetX)
ULONG frontRightBufferXY; // Offset to the stereo front buffer
ULONG backRightBufferXY; // Offset to the stereo back buffer
ULONG fbWriteModeDualWrite; // FBWriteMode for single writes
ULONG fbWriteModeSingleWrite; // FBWriteMode for dual writes
ULONG fbWriteModeDualWriteStereo; // FBWriteMode for stereo mode single writes
ULONG fbWriteModeSingleWriteStereo;// FBWriteMode for stereo mode dual writes
ULONG render2Dpatching; // Value to stuff into Render2D to set the required patch mode
ULONG usePXRXdma;
PXRXdmaInfo *pxrxDMA;
PXRXdmaInfo pxrxDMAnonInterrupt;
//#if PXRX_DMA_BUFFER_CHECK
// These should be '#if PXRX_DMA_BUFFER_CHECK' really but the
// hassle with include dependancies and such like means it ain't
// worth it.
ULONG *pxrxDMA_bufferBase; // Start of the allocated DMA buffer (inc. guard bands)
ULONG *pxrxDMA_bufferTop; // End of the allocated DMA buffer (inc. guard bands)
ULONG *NTwait; // Last address up to which NT did a wait for space
//#endif
} GlintDataRec, *GlintDataPtr;
#define PXRX_FLAGS_DUAL_WRITE (1 << 0) /* Are we in dual write mode */
#define PXRX_FLAGS_DUAL_WRITING (1 << 1) /* Are dual writes currently active */
#define PXRX_FLAGS_PATCHING_FRONT (1 << 2) /* Is the front buffer running patched */
#define PXRX_FLAGS_PATCHING_BACK (1 << 3) /* Is the back buffer running patched */
#define PXRX_FLAGS_READ_BACK_BUFFER (1 << 4) /* Do we want to read from the back buffer */
#define PXRX_FLAGS_STEREO_WRITE (1 << 5) /* Are we in OpenGL stereo mode */
#define PXRX_FLAGS_STEREO_WRITING (1 << 6) /* Are stereo writes currently active */
#if defined(_PPC_)
// on PPC need this even if not using PERFMON
ULONG GetCycleCount(VOID);
#endif
// bit definitions for the status words in ppdev->g_GlintBoardStatus[]:
// Currently used to indicate sync and DMA status. We have the following rules:
// synced means no outstanding DMA as well as synced. DMA_COMPLETE means n
// outstanding DMA but not necessarily synced. Thus when we do a wait on DMA
// complete we turn off the synced bit.
// XXX for the moment we don't use the synced bit as it's awkward to see where
// to unset it - doing so for every access to the chip is too expensive. We
// probably need a "I'm about to start downloading to the FIFO" macro which
// gets put at the start of any routine which writes to the FIFO.
//
#define GLINT_SYNCED 0x01
#define GLINT_DMA_COMPLETE 0x02 // set when there is no outstanding DMA
#define GLINT_INTR_COMPLETE 0x04
#define GLINT_INTR_CONTEXT 0x08 // set if the current context is interrupt enabled
#define GLINT_DUAL_CONTEXT 0x10 // set if the current context uses both TXs
// these macros were taken out on NT 4 so define them
#define READ_FAST_ULONG(a) READ_REGISTER_ULONG((PULONG)(a))
#define WRITE_FAST_ULONG(a, d) WRITE_REGISTER_ULONG((PULONG)(a), (d))
#define TRANSLATE_ADDR(a) ((ULONG *)a)
//azn #define INVALID_HANDLE_VALUE NULL
#define DebugBreak EngDebugBreak
typedef PVOID PGLINT_COUNTER_DATA;
// This will pause the processor whilst using as little
// system bandwidth (either memory or DMA) as possible
#if defined(_X86_)
# define BUSY_WAIT(c) \
do { \
__asm nop \
} while( c-- >= 0 )
#else
# define BUSY_WAIT(c) \
do { \
_temp_volatile_i = c; \
do { \
; \
} while( _temp_volatile_i-- >= 0 ); \
} while(0)
#endif
// If we have a sparsely mapped framebuffer then we use the xx_REGISTER_ULONG()
// macros, otherwise we just access the framebuffer.
#define READ_SCREEN_ULONG(a) ((ppdev->flCaps & CAPS_SPARSE_SPACE) ? (READ_REGISTER_ULONG(a)) : *((volatile PULONG)(a)))
#define WRITE_SCREEN_ULONG(a,d) \
{ \
if(ppdev->flCaps & CAPS_SPARSE_SPACE) \
{ \
WRITE_REGISTER_ULONG((a),d); \
} \
else \
{ \
*(volatile PULONG)(a) = d; \
} \
}
// generic macros to access GLINT FIFO and non-FIFO control registers.
// We do nothing sophisticated for the Alpha (yet). We just MEMORY_BARRIER
// everything.
//
#define READ_GLINT_CTRL_REG(r, d) \
((d) = READ_FAST_ULONG(glintInfo->regs. r))
#define WRITE_GLINT_CTRL_REG(r, v) \
{ \
MEMORY_BARRIER(); \
WRITE_FAST_ULONG(glintInfo->regs. r, (ULONG)(v)); \
DISPDBG((150, "WRITE_GLINT_CTRL_REG(%-20s:0x%08X) <-- 0x%08X", #r, glintInfo->regs.r, v)); \
MEMORY_BARRIER(); \
}
#define READ_GLINT_FIFO_REG_CHIP(r, d) \
((d) = READ_FAST_ULONG(glintInfo->regs.tagrd[r]))
#define READ_GLINT_FIFO_REG(r, d) READ_GLINT_FIFO_REG_CHIP(r, d)
#define WRITE_GLINT_FIFO_REG(r, v) \
{ \
MEMORY_BARRIER(); \
WRITE_FAST_ULONG(glintInfo->regs.tagwr[r], (ULONG)(v)); \
MEMORY_BARRIER(); \
}
#define READ_ODD_TX_AREA_STIPPLE(r, d) \
((d) = READ_FAST_ULONG(glintInfo->regs.OddTXAreaStippleRd[r]))
#define READ_ODD_GLINT_SCANLINE_OWNERSHIP(d) \
((d) = READ_FAST_ULONG(glintInfo->regs.OddGlintScanlineOwnRd))
#define READ_ODD_GLINT_FBWINDOWBASE(d) \
((d) = READ_FAST_ULONG(glintInfo->regs.OddGlintFBWindowBaseRd))
#define READ_ODD_GLINT_LBWINDOWBASE(d) \
((d) = READ_FAST_ULONG(glintInfo->regs.OddGlintLBWindowBaseRd))
//
// macros to access the output FIFO
//
#define READ_OUTPUT_FIFO(d) \
READ_GLINT_CTRL_REG(OutFIFOInterface, d)
#define READ_OUTPUT_FIFO_ODD(d) \
READ_GLINT_CTRL_REG(OutFIFOInterfaceOdd, d)
#define OUTPUT_FIFO_COUNT(n) \
READ_GLINT_CTRL_REG(OutFIFOWords, n)
#define OUTPUT_FIFO_COUNT_ODD(n) \
READ_GLINT_CTRL_REG(OutFIFOWordsOdd, n)
#define WAIT_OUTPUT_FIFO_COUNT(n) \
{ \
int i; \
do \
{ \
OUTPUT_FIFO_COUNT(i); \
} \
while(i < (int)n); \
}
#define DUAL_GLINT_WAIT_OUTPUT_FIFO_NOT_EMPTY(nGlint, cWordsOutFifo) \
{ \
if(nGlint) \
{ \
WAIT_OUTPUT_FIFO_NOT_EMPTY_ODD(cWordsOutFifo); \
} \
else \
{ \
WAIT_OUTPUT_FIFO_NOT_EMPTY(cWordsOutFifo); \
} \
}
#define DUAL_GLINT_READ_OUTPUT_FIFO(nGlint, ul) \
{ \
if(nGlint) \
{ \
READ_OUTPUT_FIFO_ODD(ul); \
} \
else \
{ \
READ_OUTPUT_FIFO(ul); \
} \
}
#define DUAL_GLINT_OUTPUT_FIFO_COUNT(nGlint, ul) \
{ \
if(nGlint) \
{ \
OUTPUT_FIFO_COUNT_ODD(ul); \
} \
else \
{ \
OUTPUT_FIFO_COUNT(ul); \
} \
}
//
// macros to access specific GLINT control registers
//
// We decrease the value of InFIFOSpace by 1 because of a bug in Gamma chip
#define GET_INPUT_FIFO_SPACE(n) ( READ_GLINT_CTRL_REG(InFIFOSpace, n) > 120 ? (n=120) : (n>0? n=n-1:n) )
#define GET_DMA_COUNT(c) READ_GLINT_CTRL_REG(DMACount, c)
#define GET_OUTDMA_COUNT(c) READ_GLINT_CTRL_REG(OutDMACount, c)
#define SET_DMA_ADDRESS(aPhys, aVirt) { \
WRITE_GLINT_CTRL_REG(DMAAddress, aPhys); \
}
#define SET_DMA_COUNT(c) { \
WRITE_GLINT_CTRL_REG(DMACount, c); \
}
#define SET_OUTDMA_ADDRESS(aPhys, aVirt) { \
WAIT_GLINT_FIFO(2); \
LD_GLINT_FIFO(GammaTagDMAOutputAddress, aPhys);
#define SET_OUTDMA_COUNT(c) { \
LD_GLINT_FIFO(GammaTagDMAOutputCount, c);
// Macros to perform logical DMA on a Gamma
//
#define START_QUEUED_DMA(P, C) { \
WAIT_GLINT_FIFO(2); \
LD_GLINT_FIFO(GammaTagDMAAddr, P); \
LD_GLINT_FIFO(GammaTagDMACount, C); \
}
#define WAIT_QUEUED_DMA_COMPLETE { \
READ_GLINT_CTRL_REG(GammaCommandIntFlags, _temp_volatile_ul); \
READ_GLINT_CTRL_REG(GammaCommandStatus, _temp_volatile_ul); \
if (_temp_volatile_ul & GAMMA_STATUS_COMMAND_DMA_BUSY) { \
do { \
for (_temp_volatile_ul = 10; _temp_volatile_ul > 0; --_temp_volatile_ul); \
READ_GLINT_CTRL_REG(GammaCommandStatus, _temp_volatile_ul); \
} while (_temp_volatile_ul & GAMMA_STATUS_COMMAND_DMA_BUSY); \
} \
}
#define VERT_RETRACE_FLAG (0x10)
#define P2_BYPASS_FLAG (1 << 7)
#define P2_BUFSWAPCTL_FLAG (3 << 9)
#define RESET_VERT_RETRACE WRITE_GLINT_CTRL_REG(IntFlags, VERT_RETRACE_FLAG)
#define LD_GLINT_FIFO_DBG(tag, d) \
{ \
DISPDBG((100, "tag 0x%03x <-- 0x%08x [%s]", tag, d, GET_TAG_STR(tag))); \
\
WRITE_GLINT_FIFO_REG(tag, d); \
READ_GLINT_CTRL_REG(ErrorFlags, _temp_ul); \
if (GLINT_DELTA_PRESENT) { \
READ_GLINT_CTRL_REG(DeltaErrorFlags, _temp_ul2); \
_temp_ul |= _temp_ul2; \
} \
_temp_ul &= ~0x2; /* we're not interested in output fifo errors */ \
_temp_ul &= ~0x10; /* ingore any Video FIFO underrun errors on P2 */ \
_temp_ul &= ~0x2000; /* ingore any HostIn DMA errors on P3 */ \
if (_temp_ul != 0) { \
DISPDBG((-1000, "LD_GLINT_FIFO(%s, 0x%X) error 0x%X", GET_TAG_STR(tag), d, _temp_ul)); \
/*if( _temp_ul & ~0x2000 ) /* ignore, but report, HostIn DMA errors */ \
/*DebugBreak();*/ \
WRITE_GLINT_CTRL_REG(ErrorFlags, _temp_ul); \
if (GLINT_DELTA_PRESENT) \
WRITE_GLINT_CTRL_REG(DeltaErrorFlags, _temp_ul); \
} \
}
#define LD_GLINT_FIFO_FREE(tag, d) WRITE_GLINT_FIFO_REG(tag, d)
#if DBG
#define LD_GLINT_FIFO(tag, d) LD_GLINT_FIFO_DBG(tag,d)
#else //DBG
#define LD_GLINT_FIFO(tag, d) LD_GLINT_FIFO_FREE(tag,d)
#endif //DBG
#define LD_FIFO_INTERFACE_DBG(d) \
{ \
WRITE_GLINT_CTRL_REG(InFIFOInterface, d); \
READ_GLINT_CTRL_REG(ErrorFlags, _temp_ul); \
if (GLINT_DELTA_PRESENT) { \
READ_GLINT_CTRL_REG(DeltaErrorFlags, _temp_ul2); \
_temp_ul |= _temp_ul2; \
} \
_temp_ul &= ~0x2; /* we're not interested in output fifo errors */ \
_temp_ul &= ~0x10; /* ingore any Video FIFO underrun errors on P2 */ \
if (_temp_ul != 0) { \
DISPDBG((-1000, "LD_FIFO_INTERFACE(0x%x) error 0x%x", d, _temp_ul)); \
DebugBreak(); \
WRITE_GLINT_CTRL_REG(ErrorFlags, _temp_ul); \
if (GLINT_DELTA_PRESENT) \
WRITE_GLINT_CTRL_REG(DeltaErrorFlags, _temp_ul); \
} \
}
#define LD_FIFO_INTERFACE_FREE(d) WRITE_GLINT_CTRL_REG(InFIFOInterface, d)
#if DBG
#define LD_FIFO_INTERFACE(d) LD_FIFO_INTERFACE_DBG(d)
#else //DBG
#define LD_FIFO_INTERFACE(d) LD_FIFO_INTERFACE_FREE(d)
#endif //DBG
// local variables for all functions that access GLINT. Generally we use GLINT_DECL. Sometimes we have to split it
// up if ppdev isn't passed into the routine.
// NB. Temporary variables:-
// These are necessary because VC5 doesn't account for the scope of variables within macros, i.e. each
// time a macro with (a variable declaration within it's statement block) is used, the stack of the function
// referencing the macro grows
#define TEMP_MACRO_VARS \
ULONG _temp_ul; \
ULONG _temp_ul2; \
LONG _temp_i; \
volatile int _temp_volatile_i; \
volatile ULONG _temp_volatile_ul; \
volatile PULONG _temp_volatile_pul
#define GLINT_DECL_VARS \
TEMP_MACRO_VARS; \
GlintDataPtr glintInfo
#define GLINT_DECL_INIT \
glintInfo = (GlintDataPtr)(ppdev->glintInfo)
#define GLINT_DECL \
GLINT_DECL_VARS; \
GLINT_DECL_INIT
//@@BEGIN_DDKSPLIT
// Macro that determines whether the chipset supports RAMDAC overlays
//#define RAMDAC_OVERLAYS_AVAILABLE (ppdev->pgfnRamdacSetOverlayMode != NULL)
//@@END_DDKSPLIT
#if(_X86_)
#define SYNCHRONOUS_WRITE_ULONG(var, value) \
{ \
ULONG *pul = (ULONG *)&var; \
ULONG ul = (ULONG)value; \
__asm push ecx \
__asm mov ecx, ul \
__asm mov edx, pul \
__asm xchg ecx, [edx] \
__asm pop ecx \
}
#define SYNCHRONOUS_WRITE_INDIRECT_ULONG(pvar, value) \
{ \
ULONG *pul = (ULONG *)pvar; \
ULONG ul = (ULONG)value; \
__asm push ecx \
__asm mov ecx, ul \
__asm mov edx, pul \
__asm xchg ecx, [edx] \
__asm pop ecx \
}
#else
// to be defined properly
#define SYNCHRONOUS_WRITE_ULONG(memory, value) {(*(PULONG) &memory) = value;}
#endif
#define GET_INTR_CMD_BLOCK_MUTEX(pBlock)\
do { \
if(glintInfo->pInterruptCommandBlock) \
{ \
DISPDBG((20, "display driver waiting for interrupt command block mutex")); \
ASSERTDD(!(pBlock)->bDisplayDriverHasAccess, "Aquiring mutex when it is already aquired!"); \
SYNCHRONOUS_WRITE_ULONG((pBlock)->bDisplayDriverHasAccess, TRUE); \
while((pBlock)->bMiniportHasAccess); \
} \
} while(0)
#define RELEASE_INTR_CMD_BLOCK_MUTEX(pBlock) \
do { \
if(glintInfo->pInterruptCommandBlock) \
{ \
DISPDBG((20, "display driver releasing interrupt command block mutex")); \
SYNCHRONOUS_WRITE_ULONG((pBlock)->bDisplayDriverHasAccess, FALSE); \
} \
} while(0)
//
// FIFO functions
//
#define MAX_GLINT_FIFO_ENTRIES 16
#define MAX_PERMEDIA_FIFO_ENTRIES 32
#define MAX_P2_FIFO_ENTRIES 258
#define MAX_GAMMA_FIFO_ENTRIES 32
#define MAX_P3_FIFO_ENTRIES 120
#if DBG
// wait for n entries to become free in the input FIFO
#define WAIT_GLINT_FIFO(n) \
{ \
if (glintInfo->CheckFIFO) \
{ \
GET_DMA_COUNT(_temp_volatile_ul); \
if (_temp_volatile_ul != 0) { \
DISPDBG((-999, "WAIT_GLINT_FIFO: DMACount = %d, glintInfo = 0x%x", _temp_volatile_ul, glintInfo)); \
ASSERTDD(_temp_volatile_ul == 0, "Break."); \
} \
while ((GET_INPUT_FIFO_SPACE(_temp_volatile_ul)) < (ULONG)(n)); \
} \
}
#else
// WAIT_GLINT_FIFO() - wait for n entries to become free in the input FIFO.
// If PCI disconnect is on permanently then this function is a no-op.
#define WAIT_GLINT_FIFO(n) /* Do the wait */ \
{ \
if (glintInfo->CheckFIFO) \
{ \
while ((GET_INPUT_FIFO_SPACE(_temp_volatile_ul)) < (ULONG)(n)); \
} \
}
#endif
// WAIT_FIFO_NOT_FULL() waits for any entries to become free in
// the input FIFO and returns this number. If PCI disconnect is switched
// on then we simply return 16 free entries (an empty FIFO).
#define WAIT_FIFO_NOT_FULL(nFifo) /* Return FIFO state */ \
{ \
ASSERTDD(GET_DMA_COUNT(nFifo) == 0, "WAIT_FIFO_NOT_FULL: DMACount != 0"); \
nFifo = glintInfo->MaxInFifoEntries; \
if (glintInfo->CheckFIFO) \
{ \
while ((GET_INPUT_FIFO_SPACE(nFifo)) == 0); \
} \
}
// Wait for DMA to complete (DMACount becomes zero). So as not to kill the
// PCI bus bandwidth for the DMA put in a backoff based on the amount of data
// still left to DMA. Also set the timer going if at any time, the count we
// read is the same as the previous count.
// New for Gamma: if queued DMA is configured then wait till the CommandStatus
// indicates DMA is not busy and the FIFO empty. We do this test twice
// because there is a possibility that the input FIFO will become empty one
// clock before the DMA busy flag is set.
//
#define WAIT_DMA_COMPLETE \
{ \
if (!(ppdev->g_GlintBoardStatus & GLINT_DMA_COMPLETE)) { \
{ \
if (ppdev->g_GlintBoardStatus & GLINT_INTR_CONTEXT) { \
/* do any VBLANK wait, wait Q to empty and last DMA to complete */ \
PINTERRUPT_CONTROL_BLOCK pBlock = glintInfo->pInterruptCommandBlock; \
while (pBlock->Control & SUSPEND_DMA_TILL_VBLANK); \
while (pBlock->frontIndex != pBlock->backIndex); \
} \
if ((GET_DMA_COUNT(_temp_volatile_i)) > 0) { \
do { \
while (--_temp_volatile_i > 0); \
} while ((GET_DMA_COUNT(_temp_volatile_i)) > 0); \
} \
} \
ppdev->g_GlintBoardStatus |= GLINT_DMA_COMPLETE; \
} \
if (ppdev->currentCtxt == glintInfo->ddCtxtId) \
SEND_PXRX_DMA; \
}
// Simple version which explicitly waits for the DMA to finish ignoring
// interrupt driven DMA and overriding the DMA_COMPLETE flag. This is used
// where code kicks off a DMA but wants to immediately wait for it to
// finish.
//
#define WAIT_IMMEDIATE_DMA_COMPLETE \
{ \
if ((GET_DMA_COUNT(_temp_volatile_i)) > 0) { \
do { \
while (--_temp_volatile_i > 0); \
} while ((GET_DMA_COUNT(_temp_volatile_i)) > 0); \
} \
}
#define WAIT_OUTDMA_COMPLETE \
{ \
if ((GET_OUTDMA_COUNT(_temp_volatile_i)) > 0) { \
do { \
while (--_temp_volatile_i > 0); \
} while ((GET_OUTDMA_COUNT(_temp_volatile_i)) > 0); \
} \
}
// IS_FIFO_EMPTY() XX
#define IS_FIFO_EMPTY(c) ((glintInfo->CheckFIFO) ? TRUE : \
(GET_INPUT_FIFO_SPACE(c) == glintInfo->MaxInFifoEntries))
// wait for the input FIFO to become empty
#define WAIT_INPUT_FIFO_EMPTY \
{ \
WAIT_GLINT_FIFO(glintInfo->MaxInFifoEntries); \
}
#define WAIT_GLINT_FIFO_AND_DMA(n) \
{ \
WAIT_DMA_COMPLETE; \
WAIT_GLINT_FIFO(n); \
}
// wait till the ouput FIFO has some data to be read and return the count
#define WAIT_OUTPUT_FIFO_NOT_EMPTY(n) \
{ \
do \
{ \
OUTPUT_FIFO_COUNT(n); \
} \
while (n == 0); \
}
#define WAIT_OUTPUT_FIFO_NOT_EMPTY_ODD(n) \
{ \
do \
{ \
OUTPUT_FIFO_COUNT_ODD(n); \
} \
while (n == 0); \
}
// wait for any data to appear in the output FIFO
#define WAIT_OUTPUT_FIFO_READY \
{ \
WAIT_OUTPUT_FIFO_NOT_EMPTY(_temp_ul); \
}
#define WAIT_OUTPUT_FIFO_READY_ODD \
{ \
WAIT_OUTPUT_FIFO_NOT_EMPTY_ODD(_temp_ul); \
}
#define SYNC_WITH_GLINT SYNC_WITH_GLINT_CHIP
#define CTXT_SYNC_WITH_GLINT SYNC_WITH_GLINT
#define GLINT_CORE_BUSY glintInfo->bGlintCoreBusy = TRUE
#define GLINT_CORE_IDLE glintInfo->bGlintCoreBusy = FALSE
#define TEST_GLINT_CORE_BUSY (glintInfo->bGlintCoreBusy)
#define SYNC_IF_CORE_BUSY \
{ \
if(glintInfo->bGlintCoreBusy) \
{ \
SYNC_WITH_GLINT; \
} \
}
//
// PCI Disconnect enable, disable and sync macros
//
// PCI_DISCONNECT_FASTSYNC()
// turn on disconnect for the input FIFO. We could do a SYNC here but it's quite
// expensive. Instead, add RasterizerMode(0) into the FIFO and when the register
// is set we know the FIFO is empty so turn on disconnect and reset RasterizerMode
// to a sensible value. PCI disconnect means we don't wait for FIFO space.
#define P2_BUSY (1 << 31)
#define PCI_DISCONNECT_FASTSYNC() \
{ \
WAIT_GLINT_FIFO(1); \
LD_GLINT_FIFO(__GlintTagRasterizerMode, 0); \
/* when we see RasterizerMode set to zero */ \
/*we know we've flushed the FIFO and can enable disconnect */ \
do { \
READ_GLINT_FIFO_REG(__GlintTagRasterizerMode, _temp_volatile_ul); \
} while(_temp_volatile_ul); \
LD_GLINT_FIFO(__GlintTagRasterizerMode, glintInfo->RasterizerMode); \
// PCI_DISCONNECT_ENABLE()
// If disconnect is not already enabled then enable it and optionally do a fast
// sync.
#define PCI_DISCONNECT_ENABLE(prevDiscState,quickEnable) \
{ \
prevDiscState = glintInfo->PCIDiscEnabled; \
if (!glintInfo->PCIDiscEnabled) \
{ \
DISPDBG((7, "PCI_DISCONNECT_ENABLE()")); \
if (!quickEnable) \
{ \
PCI_DISCONNECT_FASTSYNC(); \
} \
WRITE_GLINT_CTRL_REG(DisconnectControl, DISCONNECT_INPUT_FIFO_ENABLE); \
glintInfo->CheckFIFO = FALSE; \
glintInfo->PCIDiscEnabled = TRUE; \
} \
}
// PCI_DISCONNECT_DISABLE()
// If disconnect is not already disabled then disable it and optionally do a fast
// sync.
#define PCI_DISCONNECT_DISABLE(prevDiscState, quickDisable) \
{ \
prevDiscState = glintInfo->PCIDiscEnabled; \
if (glintInfo->PCIDiscEnabled) \
{ \
DISPDBG((7, "PCI_DISCONNECT_DISABLE()")); \
if (!quickDisable) \
{ \
PCI_DISCONNECT_FASTSYNC(); \
} \
WRITE_GLINT_CTRL_REG(DisconnectControl, DISCONNECT_INOUT_DISABLE); \
glintInfo->CheckFIFO = TRUE; \
glintInfo->PCIDiscEnabled = FALSE; \
} \
}
// macros to set and get the framebuffer packing mode
//
#define GLINT_GET_PACKING_MODE(mode) \
READ_GLINT_CTRL_REG (FBModeSel, mode)
#define GLINT_SET_PACKING_MODE(mode) { \
DISPDBG((7, "setting FBModeSel to 0x%x", mode)); \
WRITE_GLINT_CTRL_REG(FBModeSel, mode); \
/* READ_GLINT_CTRL_REG (FBModeSel, mode); */ \
}
//
// macro to change the framebuffer packing.
//
#define GLINT_SET_FB_DEPTH(cps) \
{ \
if (glintInfo->currentPelSize != cps) \
vGlintChangeFBDepth(ppdev, cps); \
}
#define GLINT_DEFAULT_FB_DEPTH GLINT_SET_FB_DEPTH(ppdev->cPelSize)
#define GLINTDEPTH8 0
#define GLINTDEPTH16 1
#define GLINTDEPTH32 2
#define GLINTDEPTH24 4
// macro to check and reload FBWindowBase if the target DFB changes
//
#define CHECK_PIXEL_ORIGIN(PixOrg) \
{ \
if ((LONG)(PixOrg) != glintInfo->PixelOffset) \
{ \
glintInfo->PixelOffset = (PixOrg); \
WAIT_GLINT_FIFO(1); \
LD_GLINT_FIFO(__GlintTagFBWindowBase, glintInfo->PixelOffset); \
DISPDBG((7, "New bitmap origin at offset %d", glintInfo->PixelOffset)); \
} \
}
#define GET_GAMMA_FEEDBACK_COMPLETED_COUNT(cEntriesWritten) \
{ \
READ_GLINT_CTRL_REG(GammaFeedbackSelectCount, cEntriesWritten); \
}
#define PREPARE_GAMMA_OUTPUT_DMA \
{ \
WRITE_GLINT_CTRL_REG(GammaCommandIntFlags, INTR_CLEAR_GAMMA_OUTPUT_DMA); \
}
#define WAIT_GAMMA_OUTPUT_DMA_COMPLETED \
{ \
READ_GLINT_CTRL_REG(GammaCommandIntFlags, _temp_ul); \
if (!(_temp_ul & INTR_GAMMA_OUTPUT_DMA_SET)) \
{ \
do \
{ \
for(_temp_volatile_i = 100; --_temp_volatile_i;); \
READ_GLINT_CTRL_REG(GammaCommandIntFlags, _temp_ul); \
} \
while(!(_temp_ul & INTR_GAMMA_OUTPUT_DMA_SET)); \
} \
}
// Bitfield definition for IntFlags register
#define PXRX_HOSTIN_COMMAND_DMA_BIT 0x4000
#define PREPARE_PXRX_OUTPUT_DMA \
{ \
WRITE_GLINT_CTRL_REG(IntFlags, PXRX_HOSTIN_COMMAND_DMA_BIT); \
}
#define SEND_PXRX_COMMAND_INTERRUPT \
{ \
WAIT_GLINT_FIFO(1); \
LD_GLINT_FIFO( CommandInterrupt_Tag, 1); \
}
#define WAIT_PXRX_OUTPUT_DMA_COMPLETED \
{ \
READ_GLINT_CTRL_REG(IntFlags, _temp_ul); \
if (!(_temp_ul & PXRX_HOSTIN_COMMAND_DMA_BIT)) \
{ \
do \
{ \
for(_temp_volatile_i = 100; --_temp_volatile_i;); \
READ_GLINT_CTRL_REG(IntFlags, _temp_ul); \
} \
while(!(_temp_ul & PXRX_HOSTIN_COMMAND_DMA_BIT)); \
} \
}
#define WAIT_GAMMA_INPUT_DMA_COMPLETED \
{ \
CommandStatusData CmdSts; \
READ_GLINT_CTRL_REG(GammaCommandStatus, _temp_ul); \
CmdSts = *(CommandStatusData *)&_temp_ul; \
if(CmdSts.CommandDMABusy) \
{ \
do \
{ \
for(_temp_volatile_i = 100; --_temp_volatile_i;); \
READ_GLINT_CTRL_REG(GammaCommandStatus, _temp_ul); \
CmdSts = *(CommandStatusData *)&_temp_ul; \
} \
while(CmdSts.CommandDMABusy); \
} \
}
// Macro to set the delta unit broadcast mask.
// We sync when changing the mask to a anything other than both chips
// in order to avoid hitting a problem on some Gamma boards.
#define SET_BROADCAST_MASK(m) \
{ \
WAIT_GLINT_FIFO(1); \
LD_GLINT_FIFO(__DeltaTagBroadcastMask, m); \
}
// Macros for the different types of double buffering supported and buffer
// offsets (in pixels). These are mostly required by 3D extension.
//
#define GLINT_CS_DBL_BUF (glintInfo->flags & GLICAP_COLOR_SPACE_DBL_BUF)
#define GLINT_FS_DBL_BUF (glintInfo->flags & GLICAP_FULL_SCREEN_DBL_BUF)
#define GLINT_BLT_DBL_BUF (glintInfo->flags & GLICAP_BITBLT_DBL_BUF)
#define GLINT_FIX_FAST_FILL (glintInfo->flags & GLICAP_FIX_FAST_FILLS)
#define GLINT_HW_WRITE_MASK (glintInfo->flags & GLICAP_HW_WRITE_MASK)
#define GLINT_HW_WRITE_MASK_BYTES (glintInfo->flags & GLICAP_HW_WRITE_MASK_BYTES)
#define GLINT_INTERRUPT_DMA (glintInfo->flags & GLICAP_INTERRUPT_DMA)
#define GLINT_FAST_FILL_SIZE (glintInfo->fastFillBlockSz)
#define GLINT_BUFFER_OFFSET(n) (glintInfo->bufferOffset[n])
// these are generic for both GLINT and PERMEDIA
#define LOCALBUFFER_PIXEL_WIDTH (glintInfo->ZBufferWidth)
#define LOCALBUFFER_PIXEL_OFFSET (glintInfo->ZBufferOffset)
#define LOCALBUFFER_PIXEL_COUNT (glintInfo->ZBufferSize)
#define FONT_MEMORY_OFFSET (glintInfo->FontMemoryOffset)
#define FONT_MEMORY_SIZE (glintInfo->FontMemorySize)
#define TEXTURE_MEMORY_OFFSET (glintInfo->TextureMemoryOffset)
#define TEXTURE_MEMORY_SIZE (glintInfo->TextureMemorySize)
// Minimum height of off-screen surface we need to allocate for texture map.
// Use this to work out whether we have enough room to allocate permanent
// things like the brush cache and software cursor caches.
//
#define TEXTURE_OH_MIN_HEIGHT \
((((2*4*64*64) >> ppdev->cPelSize) + (ppdev->cxMemory-1)) / ppdev->cxMemory)
// macro to poll for VBLANK. Can be called by any routine which defines
// glintInfo (i.e. use GLINT_DECL at the start of a routine if ppdev
// is available). Technically, VBLANK starts at line 1, but we consider
// any line <= VBLANK_LINE_NUMBER as a valid start.
//
#define VBLANK_LINE_NUMBER 2
#define GLINT_WAIT_FOR_VBLANK \
{ \
ULONG lineNo; \
do { \
READ_GLINT_CTRL_REG (VTGVLineNumber, lineNo); \
} while (lineNo > VBLANK_LINE_NUMBER); \
}
// macro to return the current video scanline. This can be used to better time
// when to perform bitblt'ed double buffering.
//
#define GLINT_GET_VIDEO_SCANLINE(lineNo) \
{ \
READ_GLINT_CTRL_REG (VTGVLineNumber, lineNo); \
if (((lineNo) -= glintInfo->scanFudge) < 0) \
(lineNo) += glintInfo->vtgvLimit; \
}
//
// external interface to the context switching code. The caller can allocate and
// free a context or ask for a switch to a new context. vGlintSwitchContext
// should not be called except through the given macro. The macro assumes
// that ppdev has been defined.
//
typedef enum ContextType_Tag {
ContextType_None, // No context information to save for this context
ContextType_Fixed, // Restore sets the chip into a fixed state
ContextType_RegisterList, // Save/restore a given set of registers
} ContextType;
typedef void (* ContextFixedFunc)(PPDEV ppdev, BOOL switchingIn);
/*
To create a new context:
id = GlintAllocateNewContext(ppdev, pTags, nTags, NumSubBuffs, Private, ContextType_RegisterList );
id = GlintAllocateNewContext(ppdev, (ULONG *) ContextRestoreFunction, 0, 0, NULL, ContextType_Fixed );
*/
extern LONG GlintAllocateNewContext(PPDEV, DWORD *, LONG, ULONG, PVOID, ContextType);
extern VOID vGlintFreeContext(PPDEV, LONG);
extern VOID vGlintSwitchContext(PPDEV, LONG);
#define NON_GLINT_CONTEXT_ID 0x7fffffff
#define GLINT_VALIDATE_CONTEXT(id) \
if (((ppdev)->currentCtxt) != (id)) \
vGlintSwitchContext(ppdev, (id))
#define GLINT_VALIDATE_CONTEXT_AND_SYNC(id) { \
if (((ppdev)->currentCtxt) != (id)) \
vGlintSwitchContext(ppdev, (id)); \
else \
SYNC_WITH_GLINT; \
}
#define USE_INTERRUPTS_FOR_2D_DMA 1
#if USE_INTERRUPTS_FOR_2D_DMA
#define INTERRUPTS_ENABLED ((ppdev->flCaps & CAPS_INTERRUPTS) && glintInfo->pInterruptCommandBlock)
#else // USE_INTERRUPTS_FOR_2D_DMA
#define INTERRUPTS_ENABLED (FALSE)
#endif // USE_INTERRUPTS_FOR_2D_DMA
// macro used by display driver to validate its context
#if ENABLE_DMA_TEXT_RENDERING
#define VALIDATE_DD_CONTEXT \
{ \
if(DD_DMA_XFER_IN_PROGRESS) \
{ \
DISPDBG((9, "######## Waiting for DMA to complete ########")); \
WAIT_DD_DMA_COMPLETE; \
} \
else \
{ \
DISPDBG((9, "######## No DMA in progress ########")); \
} \
GLINT_VALIDATE_CONTEXT(glintInfo->ddCtxtId); \
}
#else //ENABLE_DMA_TEXT_RENDERING
#define VALIDATE_DD_CONTEXT \
{ \
GLINT_VALIDATE_CONTEXT(glintInfo->ddCtxtId); \
}
#endif //ENABLE_DMA_TEXT_RENDERING
//
// useful macros not defined in standard GLINT header files. Generally, for
// speed we don't want to use the bitfield structures so we define the bit
// shifts to get at the various fields.
//
#define INTtoFIXED(i) ((i) << 16) // int to 16.16 fixed format
#define FIXEDtoINT(i) ((i) >> 16) // 16.16 fixed format to int
#define INTofFIXED(i) ((i) & 0xffff0000) // int part of 16.16
#define FRACTofFIXED(i) ((i) & 0xffff) // fractional part of 16.16
#define FIXtoFIXED(i) ((i) << 12) // 12.4 to 16.16
#define FIXtoINT(i) ((i) >> 4) // 28.4 to 28
#define INT16(i) ((i) & 0xFFFF)
#define __GLINT_CONSTANT_FB_WRITE (1 << (4+1))
#define __COLOR_DDA_FLAT_SHADE (__PERMEDIA_ENABLE | \
(__GLINT_FLAT_SHADE_MODE << 1))
#define __COLOR_DDA_GOURAUD_SHADE (__PERMEDIA_ENABLE | \
(__GLINT_GOURAUD_SHADE_MODE << 1))
#define MIRROR_BITMASK (1 << 0)
#define INVERT_BITMASK_BITS (1 << 1)
#define BYTESWAP_BITMASK (3 << 7)
#define FORCE_BACKGROUND_COLOR (1 << 6) // Permedia only
#define MULTI_GLINT (1 << 17)
// bits in the Render command
#define __RENDER_INCREASE_Y (1 << 22)
#define __RENDER_INCREASE_X (1 << 21)
#define __RENDER_VARIABLE_SPANS (1 << 18)
#define __RENDER_REUSE_BIT_MASK (1 << 17)
#define __RENDER_TEXTURE_ENABLE (1 << 13)
#define __RENDER_SYNC_ON_HOST_DATA (1 << 12)
#define __RENDER_SYNC_ON_BIT_MASK (1 << 11)
#define __RENDER_TRAPEZOID_PRIMITIVE (__GLINT_TRAPEZOID_PRIMITIVE << 6)
#define __RENDER_LINE_PRIMITIVE (__GLINT_LINE_PRIMITIVE << 6)
#define __RENDER_POINT_PRIMITIVE (__GLINT_POINT_PRIMITIVE << 6)
#define __RENDER_FAST_FILL_INC(n) (((n) >> 4) << 4) // n = 8, 16 or 32
#define __RENDER_FAST_FILL_ENABLE (1 << 3)
#define __RENDER_RESET_LINE_STIPPLE (1 << 2)
#define __RENDER_LINE_STIPPLE_ENABLE (1 << 1)
#define __RENDER_AREA_STIPPLE_ENABLE (1 << 0)
// bits in the ScissorMode register
#define USER_SCISSOR_ENABLE (1 << 0)
#define SCREEN_SCISSOR_ENABLE (1 << 1)
#define SCISSOR_XOFFSET 0
#define SCISSOR_YOFFSET 16
// bits in the FBReadMode register
#define __FB_READ_SOURCE (1 << 9)
#define __FB_READ_DESTINATION (1 << 10)
#define __FB_COLOR (1 << 15)
#define __FB_WINDOW_ORIGIN (1 << 16)
#define __FB_PACKED_DATA (1 << 19)
#define __FB_SCAN_INTERVAL_2 (1 << 23)
// extra bits in PERMEDIA FBReadMode
#define __FB_RELATIVE_OFFSET 20
// P2 also provides a version of Relative Offset in the PackedDataLimits register
#define __PDL_RELATIVE_OFFSET 29
// bits in the LBReadMode register
#define __LB_READ_SOURCE (1 << 9)
#define __LB_READ_DESTINATION (1 << 10)
#define __LB_STENCIL (1 << 16)
#define __LB_DEPTH (1 << 17)
#define __LB_WINDOW_ORIGIN (1 << 18)
#define __LB_READMODE_PATCH (1 << 19)
#define __LB_SCAN_INTERVAL_2 (1 << 20)
// bits in the DepthMode register
#define __DEPTH_ENABLE 1
#define __DEPTH_WRITE_ENABLE (1<<1)
#define __DEPTH_REGISTER_SOURCE (2<<2)
#define __DEPTH_MSG_SOURCE (3<<2)
#define __DEPTH_ALWAYS (7<<4)
// bits in the LBReadFormat/LBWriteFormat registers
#define __LB_FORMAT_DEPTH32 2
// macros to load indexed tags more efficiently than using __GlintDMATag struct
#define GLINT_TAG_MAJOR(x) ((x) & 0xff0)
#define GLINT_TAG_MINOR(x) ((x) & 0x00f)
// macro to take a GLINT logical op and return the enabled LogcialOpMode bits
#define GLINT_ENABLED_LOGICALOP(op) (((op) << 1) | __PERMEDIA_ENABLE)
#define RECTORIGIN_YX(y,x) (((y) << 16) | ((x) & 0xFFFF))
#define MAKEDWORD_XY(x, y) (INT16(x) | (INT16(y) << 16))
// area stipple shifts and bit defines
#define AREA_STIPPLE_XSEL(x) ((x) << 1)
#define AREA_STIPPLE_YSEL(y) ((y) << 4)
#define AREA_STIPPLE_XOFF(x) ((x) << 7)
#define AREA_STIPPLE_YOFF(y) ((y) << 12)
#define AREA_STIPPLE_INVERT_PAT (1 << 17)
#define AREA_STIPPLE_MIRROR_X (1 << 18)
#define AREA_STIPPLE_MIRROR_Y (1 << 19)
// Some constants
#define ONE 0x00010000
#define MINUS_ONE 0xFFFF0000
#define PLUS_ONE ONE
#define NEARLY_ONE 0x0000FFFF
#define HALF 0x00008000
#define NEARLY_HALF 0x00007FFF
// max length of GIQ conformant lines that GLINT can draw
//
#if 0
#define MAX_LENGTH_CONFORMANT_NONINTEGER_LINES 16
#define MAX_LENGTH_CONFORMANT_INTEGER_LINES 194
#else
// Permedia has only 15 bits of fraction so reduce the lengths.
#define MAX_LENGTH_CONFORMANT_NONINTEGER_LINES (16/2)
#define MAX_LENGTH_CONFORMANT_INTEGER_LINES (194/2)
#endif
#define MAX_LENGTH_CONFORMANT_P3_INTEGER_LINES_P 194
#define MAX_LENGTH_CONFORMANT_P3_INTEGER_LINES_N 175
#define P3_LINES_BIAS_P 0x3EFFFFFF
#define P3_LINES_BIAS_N 0x3EFEB600
//
// GLINT DMA definitions
//
#define IOCTL_VIDEO_QUERY_NUM_DMA_BUFFERS \
CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD0, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_QUERY_DMA_BUFFERS \
CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD1, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_QUERY_DEVICE_INFO \
CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD2, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_MAP_INTERRUPT_CMD_BUF \
CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD3, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_QUERY_REGISTRY_DWORD \
CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD5, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_REG_SAVE_GAMMA_LUT \
CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD7, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_REG_RETRIEVE_GAMMA_LUT \
CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD8, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_QUERY_GENERAL_DMA_BUFFER \
CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD9, METHOD_BUFFERED, FILE_ANY_ACCESS)
// structure definitions passed in by the application for mapping and
// unmapping DMA buffers.
//
typedef struct _DMA_NUM_BUFFERS {
ULONG NumBuffers;
ULONG BufferInformationLength;
} DMA_NUM_BUFFERS, *PDMA_NUM_BUFFERS;
typedef struct _QUERY_DMA_BUFFERS {
LARGE_INTEGER physAddr; // physical address of DMA buffer
PVOID virtAddr; // mapped virtual address
ULONG size; // size in bytes
ULONG flags;
} QUERY_DMA_BUFFERS, *PQUERY_DMA_BUFFERS;
// values for flags word
#define DMA_BUFFER_INUSE 0x1
// functions to get and free DMA buffers
VOID FreeDMABuffer(PVOID physAddr);
LONG GetFreeDMABuffer(PQUERY_DMA_BUFFERS dmaBuf);
// Generic locling structure/interface that enables arbitrary buffers
// to be locked/unlocked for accessing.
typedef struct _glint_lockedmem_ {
struct _MDL *pMdl;
ULONG sizeBytes;
PVOID bufferPtr;
ULONG accessType;
ULONG physicalAddress;
ULONG result;
} GLINT_LOCKMEM_REC, *PGLINT_LOCKMEM_PTR;
// Routine to support the obtaining of a physical address from a virtual
// address
typedef struct _glint_physaddr_ {
PVOID virtualAddress;
ULONG physicalAddress;
} GLINT_PHYSADDR_REC, *PGLINT_PHYSADDR_PTR;
// definitions for DMA transfers
#define INPUT_DMA 0
#define OUTPUT_DMA 1
typedef struct DMA_Transfer_Buffer
{
VOID *pv;
ULONG cb;
ULONG DmaDirection;
}
DMAXFERBFRINFO;
// structure definitions for the file handle mapping ioctl
//
typedef struct _GLINT_MAP_FILE_HANDLE {
ULONG Size;
HANDLE fHandle;
} GLINT_MAP_FILE_HANDLE, *PGLINT_MAP_FILE_HANDLE;
typedef struct _GLINT_UNMAP_FILE_HANDLE {
HANDLE fHandle;
PVOID pv;
} GLINT_UNMAP_FILE_HANDLE, *PGLINT_UNMAP_FILE_HANDLE;
// structure for the user memory locking ioctls
typedef struct
{
void *pvBfr;
ULONG cbBfr;
ULONG hMem;
}
LOCKEDUSERMEM;
//
// registry variable names
//
#define REG_NUMBER_OF_SCREEN_BUFFERS L"DoubleBuffer.NumberOfBuffers"
extern GFNXCOPYD vGlintCopyBltBypassDownloadXlate8bpp;
// function declarations
//
extern BOOL bInitializeGlint(PPDEV);
extern BOOL bAllocateGlintInfo(PPDEV ppdev);
extern VOID vDisableGlint(PPDEV);
extern VOID vAssertModeGlint(PPDEV, BOOL);
extern BOOL bGlintQueryRegistryValueUlong(PPDEV, LPWSTR, PULONG);
extern VOID vGlintChangeFBDepth(PPDEV, ULONG);
extern VOID vGlintInitializeDMA(PPDEV);
extern VOID vSetNewGammaValue(PPDEV ppdev, ULONG ulgvFIX16_16, BOOL waitVBlank);
extern BOOL bInstallGammaLUT(PPDEV ppdev, PVIDEO_CLUT pScreenClut, BOOL waitVBlank);
#define GLINT_ENABLE_OVERLAY 1
#define GLINT_DISABLE_OVERLAY 0
//
// Externs/Defines from Pointer.c
// ==============================
//
// Hardware pointer caching functions/macros.
//
extern VOID HWPointerCacheInit (HWPointerCache * ptrCache);
extern VOID HWPointerCacheInvalidate (HWPointerCache * ptrCache);
#define HWPointerCacheInvalidate(ptrCache) (ptrCache)->ptrCacheInUseCount = 0
extern LONG HWPointerCacheCheckAndAdd (HWPointerCache * ptrCache, ULONG cx,
ULONG cy, LONG lDelta, BYTE * scan0, BOOL * isCached);
extern BYTE gajMask[];
//
// The following structures and macros define the memory map for the GLINT
// control registers. We don't use this memory map to access GLINT registers
// since on Alpha machines we want to precompute the addresses. So we do
// a TRANSLATE_ADDR_ULONG on all the addresses here and save them into a
// GlintRegAddrRec. We use that to obtain the addresses for the different
// registers.
typedef struct {
ULONG reg;
ULONG pad;
} RAMDAC_REG;
// macros to add padding words to the structures. For the core registers we use
// the tag ids when specifying the pad. So we must multiply by 8 to get a byte
// pad. We need to add an id to make each pad field in the struct unique. The id
// is irrelevant as long as it's different from every other id used in the same
// struct. It's a pity pad##__LINE__ doesn't work.
//
#define PAD(id, n) UCHAR pad##id[n]
#define PADRANGE(id, n) PAD(id, (n)-sizeof(GLINT_REG))
#define PADCORERANGE(id, n) PADRANGE(id, (n)<<3)
// GLINT registers are 32 bits wide and live on 64-bit boundaries.
typedef struct {
ULONG reg;
ULONG pad;
} GLINT_REG;
//
// Map of the Core FIFO registers.
//
typedef struct _glint_core_regs {
// Major Group 0
GLINT_REG tag[__MaximumGlintTagValue+1];
} GlintCoreRegMap, *pGlintCoreRegMap;
//
// GLINT PCI Region 0 Address MAP:
//
// All registers are on 64-bit boundaries so we have to define a number of
// padding words. The number given in the coments are offsets from the start
// of the PCI region.
//
typedef struct _glint_region0_map {
// Control Status Registers:
GLINT_REG ResetStatus; // 0000h
GLINT_REG IntEnable; // 0008h
GLINT_REG IntFlags; // 0010h
GLINT_REG InFIFOSpace; // 0018h
GLINT_REG OutFIFOWords; // 0020h
GLINT_REG DMAAddress; // 0028h
GLINT_REG DMACount; // 0030h
GLINT_REG ErrorFlags; // 0038h
GLINT_REG VClkCtl; // 0040h
GLINT_REG TestRegister; // 0048h
union a0 {
// GLINT
struct b0 {
GLINT_REG Aperture0; // 0050h
GLINT_REG Aperture1; // 0058h
};
// PERMEDIA
struct b1 {
GLINT_REG ApertureOne; // 0050h
GLINT_REG ApertureTwo; // 0058h
};
};
GLINT_REG DMAControl; // 0060h
GLINT_REG DisconnectControl; // 0068h
// PERMEDIA only
GLINT_REG ChipConfig; // 0070h
// P2 only
GLINT_REG AGPControl; // 0078h
GLINT_REG OutDMAAddress; // 0080h
GLINT_REG OutDMACount; // 0088h // P3: FeedbackCount
PADRANGE(2, 0xA0-0x88);
GLINT_REG ByDMAAddress; // 00A0h
PADRANGE(201, 0xB8-0xA0);
GLINT_REG ByDMAStride; // 00B8h
GLINT_REG ByDMAMemAddr; // 00C0h
GLINT_REG ByDMASize; // 00C8h
GLINT_REG ByDMAByteMask; // 00D0h
GLINT_REG ByDMAControl; // 00D8h
PADRANGE(202, 0xE8-0xD8);
GLINT_REG ByDMAComplete; // 00E8h
PADRANGE(203, 0x108-0xE8);
GLINT_REG TextureDownloadControl; // 0108h
PADRANGE(204, 0x200-0x108);
GLINT_REG TestInputControl; // 0200h
GLINT_REG TestInputRdy; // 0208h
GLINT_REG TestOutputControl; // 0210h
GLINT_REG TestOutputRdy; // 0218h
PADRANGE(205, 0x300-0x218);
GLINT_REG PXRXByAperture1Mode; // 0300h
GLINT_REG PXRXByAperture1Stride; // 0308h
GLINT_REG PXRXByAperture1YStart; // 0310h
GLINT_REG PXRXByAperture1UStart; // 0318h
GLINT_REG PXRXByAperture1VStart; // 0320h
GLINT_REG PXRXByAperture2Mode; // 0328h
GLINT_REG PXRXByAperture2Stride; // 0330h
GLINT_REG PXRXByAperture2YStart; // 0338h
GLINT_REG PXRXByAperture2UStart; // 0340h
GLINT_REG PXRXByAperture2VStart; // 0348h
GLINT_REG PXRXByDMAReadMode; // 0350h
GLINT_REG PXRXByDMAReadStride; // 0358h
GLINT_REG PXRXByDMAReadYStart; // 0360h
GLINT_REG PXRXByDMAReadUStart; // 0368h
GLINT_REG PXRXByDMAReadVStart; // 0370h
GLINT_REG PXRXByDMAReadCommandBase; // 0378h
GLINT_REG PXRXByDMAReadCommandCount; // 0380h
GLINT_REG PXRXByDMAWriteMode; // 0388h
GLINT_REG PXRXByDMAWriteStride; // 0390h
GLINT_REG PXRXByDMAWriteYStart; // 0398h
GLINT_REG PXRXByDMAWriteUStart; // 03A0h
GLINT_REG PXRXByDMAWriteVStart; // 03A8h
GLINT_REG PXRXByDMAWriteCommandBase; // 03B0h
GLINT_REG PXRXByDMAWriteCommandCount; // 03B8h
PADRANGE(206, 0x800-0x3B8);
// GLINTdelta registers. Registers with the same functionality as on GLINT
// are at the same offset. XXX are not real registers.
// NB. all non-XXX registers are also Gamma registers
//
GLINT_REG DeltaReset; // 0800h
GLINT_REG DeltaIntEnable; // 0808h
GLINT_REG DeltaIntFlags; // 0810h
GLINT_REG DeltaInFIFOSpaceXXX; // 0818h
GLINT_REG DeltaOutFIFOWordsXXX; // 0820h
GLINT_REG DeltaDMAAddressXXX; // 0828h
GLINT_REG DeltaDMACountXXX; // 0830h
GLINT_REG DeltaErrorFlags; // 0838h
GLINT_REG DeltaVClkCtlXXX; // 0840h
GLINT_REG DeltaTestRegister; // 0848h
GLINT_REG DeltaAperture0XXX; // 0850h
GLINT_REG DeltaAperture1XXX; // 0858h
GLINT_REG DeltaDMAControlXXX; // 0860h
GLINT_REG DeltaDisconnectControl; // 0868h
// GLINTgamma registers
//
GLINT_REG GammaChipConfig; // 0870h
GLINT_REG GammaCSRAperture; // 0878h
PADRANGE(3, 0x0c00-0x878);
GLINT_REG GammaPageTableAddr; // 0c00h
GLINT_REG GammaPageTableLength; // 0c08h
PADRANGE(301, 0x0c38-0x0c08);
GLINT_REG GammaDelayTimer; // 0c38h
GLINT_REG GammaCommandMode; // 0c40h
GLINT_REG GammaCommandIntEnable; // 0c48h
GLINT_REG GammaCommandIntFlags; // 0c50h
GLINT_REG GammaCommandErrorFlags; // 0c58h
GLINT_REG GammaCommandStatus; // 0c60h
GLINT_REG GammaCommandFaultingAddr; // 0c68h
GLINT_REG GammaVertexFaultingAddr; // 0c70h
PADRANGE(302, 0x0c88-0x0c70);
GLINT_REG GammaWriteFaultingAddr; // 0c88h
PADRANGE(303, 0x0c98-0x0c88);
GLINT_REG GammaFeedbackSelectCount; // 0c98h
PADRANGE(304, 0x0cb8-0x0c98);
GLINT_REG GammaProcessorMode; // 0cb8h
PADRANGE(305, 0x0d00-0x0cb8);
GLINT_REG GammaVGAShadow; // 0d00h
GLINT_REG GammaMultiGLINTAperture; // 0d08h
GLINT_REG GammaMultiGLINT1; // 0d10h
GLINT_REG GammaMultiGLINT2; // 0d18h
PADRANGE(306, 0x0f00-0x0d18);
GLINT_REG GammaSerialAccess; // 0f00h
PADRANGE(307, 0x1000-0x0f00);
// Localbuffer Registers
union x0 { // 1000h
GLINT_REG LBMemoryCtl; // GLINT
GLINT_REG Reboot; // PERMEDIA
};
GLINT_REG LBMemoryEDO; // 1008h
// PXRX Memory control registers
GLINT_REG MemScratch; // 1010h
GLINT_REG LocalMemCaps; // 1018h
GLINT_REG LocalMemTiming; // 1020h
GLINT_REG LocalMemControl; // 1028h
GLINT_REG LocalMemRefresh; // 1030h
GLINT_REG LocalMemPowerDown; // 1038h
// PERMEDIA only
GLINT_REG MemControl; // 1040h
PADRANGE(5, 0x1068-0x1040);
GLINT_REG LocalMemProfileMask0; // 1068h
GLINT_REG LocalMemProfileCount0; // 1070h
GLINT_REG LocalMemProfileMask1; // 1078h
GLINT_REG BootAddress; // 1080h // [= LocalMemProfileCount1 on PxRx]
PADRANGE(6, 0x10C0-0x1080);
GLINT_REG MemConfig; // 10C0h
PADRANGE(7, 0x1100-0x10C0);
GLINT_REG BypassWriteMask; // 1100h
PADRANGE(8, 0x1140-0x1100);
GLINT_REG FramebufferWriteMask; // 1140h
PADRANGE(9, 0x1180-0x1140);
GLINT_REG Count; // 1180h
PADRANGE(10, 0x1800-0x1180);
// Framebuffer Registers
GLINT_REG FBMemoryCtl; // 1800h
GLINT_REG FBModeSel; // 1808h
GLINT_REG FBGCWrMask; // 1810h
GLINT_REG FBGCColorMask; // 1818h
PADRANGE(11, 0x2000-0x1818);
// Graphics Core FIFO Interface
GLINT_REG FIFOInterface; // 2000h
PADRANGE(12, 0x3000-0x2000);
// Internal Video Registers
union x1 {
// GLINT
struct s1 {
GLINT_REG VTGHLimit; // 3000h
GLINT_REG VTGHSyncStart; // 3008h
GLINT_REG VTGHSyncEnd; // 3010h
GLINT_REG VTGHBlankEnd; // 3018h
GLINT_REG VTGVLimit; // 3020h
GLINT_REG VTGVSyncStart; // 3028h
GLINT_REG VTGVSyncEnd; // 3030h
GLINT_REG VTGVBlankEnd; // 3038h
GLINT_REG VTGHGateStart; // 3040h
GLINT_REG VTGHGateEnd; // 3048h
GLINT_REG VTGVGateStart; // 3050h
GLINT_REG VTGVGateEnd; // 3058h
GLINT_REG VTGPolarity; // 3060h
GLINT_REG VTGFrameRowAddr; // 3068h
GLINT_REG VTGVLineNumber; // 3070h
GLINT_REG VTGSerialClk; // 3078h
GLINT_REG VTGModeCtl; // 3080h
};
// PERMEDIA
struct s2 {
GLINT_REG ScreenBase; // 3000h
GLINT_REG ScreenStride; // 3008h
GLINT_REG HTotal; // 3010h
GLINT_REG HgEnd; // 3018h
GLINT_REG HbEnd; // 3020h
GLINT_REG HsStart; // 3028h
GLINT_REG HsEnd; // 3030h
GLINT_REG VTotal; // 3038h
GLINT_REG VbEnd; // 3040h
GLINT_REG VsStart; // 3048h
GLINT_REG VsEnd; // 3050h
GLINT_REG VideoControl; // 3058h
GLINT_REG InterruptLine; // 3060h
GLINT_REG DDCData; // 3068h
GLINT_REG LineCount; // 3070h
GLINT_REG FifoControl ; // 3078h
GLINT_REG ScreenBaseRight; // 3080h
};
};
PADRANGE(13, 0x4000-0x3080);
// External Video Control Registers
// Need to cast this to a struct for a particular video generator
GLINT_REG ExternalVideo; // 4000h
PADRANGE(14, 0x5000-0x4000);
// P2 specific registers
union x11 {
GLINT_REG ExternalP2Ramdac; // 5000h
GLINT_REG DemonProDWAndStatus; // 5000h - Pro
};
PADRANGE(15, 0x5800-0x5000);
GLINT_REG VSConfiguration; // 5800h
PADRANGE(16, 0x6000-0x5800);
union x2 {
struct s3 {
GLINT_REG RacerDoubleWrite; // 6000h
GLINT_REG RacerBankSelect; // 6008h
};
struct s4 {
// the following array is actually 1024 bytes long
UCHAR PermediaVgaCtrl[2*sizeof(GLINT_REG)];
};
};
PADRANGE(17, 0x7000-0x6008);
GLINT_REG DemonProUBufB; // 7000h - Pro
PADRANGE(18, 0x8000-0x7000);
// Graphics Core Registers
GlintCoreRegMap coreRegs; // 8000h
} GlintControlRegMap, *pGlintControlRegMap;
//
// DisconnectControl bits
//
#define DISCONNECT_INPUT_FIFO_ENABLE 0x1
#define DISCONNECT_OUTPUT_FIFO_ENABLE 0x2
#define DISCONNECT_INOUT_ENABLE (DISCONNECT_INPUT_FIFO_ENABLE | \
DISCONNECT_OUTPUT_FIFO_ENABLE)
#define DISCONNECT_INOUT_DISABLE 0x0
//
// Delta bit definitions
//
#define DELTA_BROADCAST_TO_CHIP(n) (1 << (n))
#define DELTA_BROADCAST_TO_BOTH_CHIPS (DELTA_BROADCAST_TO_CHIP(0) | \
DELTA_BROADCAST_TO_CHIP(1))
//
// Multi TX
//
#define GLINT_OWN_SCANLINE_0 (0 << 2)
#define GLINT_OWN_SCANLINE_1 (1 << 2)
#define GLINT_OWN_SCANLINE_2 (2 << 2)
#define GLINT_OWN_SCANLINE_3 (3 << 2)
#define GLINT_SCANLINE_INTERVAL_1 (0 << 0)
#define GLINT_SCANLINE_INTERVAL_2 (1 << 0)
#define GLINT_SCANLINE_INTERVAL_4 (2 << 0)
#define GLINT_SCANLINE_INTERVAL_8 (3 << 0)
#define SCANLINE_OWNERSHIP_EVEN_SCANLINES (GLINT_OWN_SCANLINE_0 | GLINT_SCANLINE_INTERVAL_2)
#define SCANLINE_OWNERSHIP_ODD_SCANLINES (GLINT_OWN_SCANLINE_1 | GLINT_SCANLINE_INTERVAL_2)
// Glint Interrupt Control Bits
//
// InterruptEnable register
#define INTR_DISABLE_ALL 0x00
#define INTR_ENABLE_DMA 0x01
#define INTR_ENABLE_SYNC 0x02
#define INTR_ENABLE_EXTERNAL 0x04
#define INTR_ENABLE_ERROR 0x08
#define INTR_ENABLE_VBLANK 0x10
#define INTR_ENABLE_TEXTURE_FAULT (1 << 6)
// InterruptFlags register
#define INTR_DMA_SET 0x01
#define INTR_SYNC_SET 0x02
#define INTR_EXTERNAL_SET 0x04
#define INTR_ERROR_SET 0x08
#define INTR_VBLANK_SET 0x10
#define INTR_TEXTURE_FAULT_SET (1 << 6)
#define INTR_CLEAR_ALL 0x1f
#define INTR_CLEAR_DMA 0x01
#define INTR_CLEAR_SYNC 0x02
#define INTR_CLEAR_EXTERNAL 0x04
#define INTR_CLEAR_ERROR 0x08
#define INTR_CLEAR_VBLANK 0x10
// Gamma Interrupt Control Bits
//
// CommandIntEnable register
#define GAMMA_INTR_DISABLE_ALL 0x0000
#define GAMMA_INTR_QUEUED_DMA 0x0001
#define GAMMA_INTR_OUTPUT_DMA 0x0002
#define GAMMA_INTR_COMMAND 0x0004
#define GAMMA_INTR_TIMER 0x0008
#define GAMMA_INTR_ERROR 0x0010
#define GAMMA_INTR_CBFR_TIMEOUT 0x0020
#define GAMMA_INTR_CBFR_SUSPEND 0x0040
#define GAMMA_INTR_TEXDOWNLD 0x0080
#define GAMMA_INTR_PF_COMMAND 0x0100
#define GAMMA_INTR_PF_VERTEX 0x0200
#define GAMMA_INTR_PF_FACENORM 0x0400
#define GAMMA_INTR_PF_INDEX 0x0800
#define GAMMA_INTR_PF_WRITE 0x1000
#define GAMMA_INTR_PF_TEXTURE 0x2000
// CommandIntFlags register - uses the same defines as CommandIntEnable
#define GAMMA_INTR_CLEAR_ALL 0x3fff
// Gamma Command Interrupts
#define INTR_DISABLE_GAMMA_ALL 0
#define INTR_ENABLE_GAMMA_QUEUED_DMA (1 << 0)
#define INTR_ENABLE_GAMMA_OUTPUT_DMA (1 << 1)
#define INTR_ENABLE_GAMMA_COMMAND (1 << 2)
#define INTR_ENABLE_GAMMA_TIMER (1 << 3)
#define INTR_ENABLE_GAMMA_COMMAND_ERROR (1 << 4)
#define INTR_ENABLE_GAMMA_PAGE_FAULT (1 << 8)
#define INTR_ENABLE_GAMMA_VERTEX_FAULT (1 << 9)
#define INTR_ENABLE_GAMMA_WRITE_FAULT (1 << 12)
#define INTR_GAMMA_QUEUED_DMA_SET (1 << 0)
#define INTR_GAMMA_OUTPUT_DMA_SET (1 << 1)
#define INTR_GAMMA_COMMAND_SET (1 << 2)
#define INTR_GAMMA_TIMER_SET (1 << 3)
#define INTR_GAMMA_COMMAND_ERROR_SET (1 << 4)
#define INTR_GAMMA_PAGE_FAULT_SET (1 << 8)
#define INTR_GAMMA_VERTEX_FAULT_SET (1 << 9)
#define INTR_GAMMA_WRITE_FAULT_SET (1 << 12)
#define INTR_CLEAR_GAMMA_QUEUED_DMA (1 << 0)
#define INTR_CLEAR_GAMMA_OUTPUT_DMA (1 << 1)
#define INTR_CLEAR_GAMMA_COMMAND (1 << 2)
#define INTR_CLEAR_GAMMA_TIMER (1 << 3)
#define INTR_CLEAR_GAMMA_COMMAND_ERROR (1 << 4)
#define INTR_CLEAR_GAMMA_PAGE_FAULT (1 << 8)
#define INTR_CLEAR_GAMMA_VERTEX_FAULT (1 << 9)
#define INTR_CLEAR_GAMMA_WRITE_FAULT (1 << 12)
// Gamma Command Status
#define GAMMA_STATUS_COMMAND_DMA_BUSY (1 << 0)
#define GAMMA_STATUS_OUTPUT_DMA_BUSY (1 << 1)
#define GAMMA_STATUS_INPUT_FIFO_EMPTY (1 << 2)
// Gamma Command Mode
#define GAMMA_COMMAND_MODE_QUEUED_DMA (1 << 0)
#define GAMMA_COMMAND_MODE_LOGICAL_ADDRESSING (1 << 2)
#define GAMMA_COMMAND_MODE_ABORT_OUTPUT_DMA (1 << 3)
#define GAMMA_COMMAND_MODE_ABORT_INPUT_DMA (1 << 6)
// interrupt status bits
typedef enum {
DMA_INTERRUPT_AVAILABLE = 0x01, // can use DMA interrupts
VBLANK_INTERRUPT_AVAILABLE = 0x02, // can use VBLANK interrupts
SUSPEND_DMA_TILL_VBLANK = 0x04, // Stop doing DMA till after next VBLANK
DIRECTDRAW_VBLANK_ENABLED = 0x08, // Set flag for DirectDraw on VBLANK
PXRX_SEND_ON_VBLANK_ENABLED = 0x10, // Set flag for PXRX DMA on VBLANK
PXRX_CHECK_VFIFO_IN_VBLANK = 0x20, // Set flag to check VFIFO underruns in VBLANK (vblanks must be permanently enabled)
} INTERRUPT_CONTROL;
// commands to the interrupt controller on the next VBLANK
typedef enum {
NO_COMMAND = 0,
COLOR_SPACE_BUFFER_0,
COLOR_SPACE_BUFFER_1,
GLINT_RACER_BUFFER_0,
GLINT_RACER_BUFFER_1
} VBLANK_CONTROL_COMMAND;
// we manage a queue of DMA buffers that are to be loaded under interrupt control
// each entry has a physical address and a count to be loaded into GLINT.
//
typedef struct _glint_dma_queue {
ULONG command;
ULONG address;
ULONG count;
} DMABufferQueue;
// Display driver structure for 'general use'.
typedef struct _pointer_interrupt_control
{
volatile ULONG bDisplayDriverHasAccess;
volatile ULONG bMiniportHasAccess;
volatile ULONG bInterruptPending;
volatile ULONG bHidden;
volatile ULONG CursorMode;
volatile ULONG x, y;
} PTR_INTR_CTL;
// Display driver structure for 'pointer use'.
typedef struct _general_interrupt_control
{
volatile ULONG bDisplayDriverHasAccess;
volatile ULONG bMiniportHasAccess;
} GEN_INTR_CTL;
//
// The volatile fields are the ones that the interrupt handler can change
// under our feet. But, for example, note that the frontIndex is not
// volatile since the ISR can only read this.
//
typedef struct _glint_interrupt_control {
// contains various status bits. ** MUST BE THE FIRST FIELD **
volatile INTERRUPT_CONTROL Control;
// profiling counters for GLINT busy time
ULONG PerfCounterShift;
ULONG BusyTime; // at DMA interrupt add (TimeNow-StartTime) to this
ULONG StartTime; // set this when DMACount is loaded
ULONG IdleTime;
ULONG IdleStart;
// commands to perform on the next VBLANK
volatile VBLANK_CONTROL_COMMAND VBCommand;
// flag to indicate whether we expect another DMA interrupt
volatile ULONG InterruptPending;
volatile ULONG DDRAW_VBLANK; // flag for DirectDraw to indicate that a VBLANK occured.
volatile ULONG bOverlayEnabled; // TRUE if the overlay is on at all
volatile ULONG bVBLANKUpdateOverlay; // TRUE if the overlay needs to be updated by the VBLANK routine.
volatile ULONG VBLANKUpdateOverlayWidth; // overlay width (updated in vblank)
volatile ULONG VBLANKUpdateOverlayHeight; // overlay height (updated in vblank)
// Volatile structures are required to enforce single-threading
// We need 1 for general display use and 1 for pointer use, because
// the pointer is synchronous.
volatile PTR_INTR_CTL Pointer;
volatile GEN_INTR_CTL General;
// dummy DMA buffer to cause an interrupt but transfer no data
ULONG dummyDMAAddress;
ULONG dummyDMACount;
// index offsets into the queue for the front, back and end. Using separate
// front and back offsets allows the display driver to add and the interrupt
// controller to remove entries without a need for locking code.
ULONG frontIndex;
volatile ULONG backIndex;
ULONG endIndex;
ULONG maximumIndex;
// For PXRX 2D DMA:
volatile ULONG lastAddr;
PXRXdmaInfo pxrxDMA;
// array to contain the DMA queue
DMABufferQueue dmaQueue[1];
// DO NOT PUT ANYTHING AFTER THIS
} INTERRUPT_CONTROL_BLOCK, *PINTERRUPT_CONTROL_BLOCK;
/***** RACER FULL SCREEN DOUBLE BUFFERING MACROS ***********
*
* These macros were invented because some boards, such as
* Omnicomp ones, have their bank-switch registers in different places.
*
* The macros are:
*
* SET_RACER_BANKSELECT() - Sets the bank select register to be bank 0 or 1.
* GET_RACER_DOUBLEWRITE() - Returns 1 if double writes are enabled, else returns 0.
* SET_RACER_DOUBLEWRITE() - Sets the double write register to 0 or 1.
* IS_RACER_VARIANT_PRO16() - Returns TRUE if the board is an Omnicomp 3DemonPro16, RevC board.
*/
// We define an Omnicomp 3Demon Pro 16 to be a card that has a 16MB framebuffer.
#define SIXTEEN_MEG (16*1024*1024)
#define IS_RACER_VARIANT_PRO16(ppdev) (glintInfo->deviceInfo.BoardId == OMNICOMP_3DEMONPRO)
//
// the following defines the offset to the External Video register which allows
// switching of the memory banks on a Glint Racer card.
//
#ifndef FIELD_OFFSET
#define FIELD_OFFSET(a, b) ((LONG)&(((a *)0)->b))
#endif
// The Omnicomp 3Demon Pro 16 board uses different registers to do it's bank switching.
#define DEMON_BANK_SELECT_OFFSET \
((FIELD_OFFSET (GlintControlRegMap, DemonProUBufB)) - \
(FIELD_OFFSET (GlintControlRegMap, ExternalVideo)))
#define REAL_RACER_BANK_SELECT_OFFSET \
((FIELD_OFFSET (GlintControlRegMap, RacerBankSelect)) - \
(FIELD_OFFSET (GlintControlRegMap, ExternalVideo)))
#define RACER_BANK_SELECT_OFFSET \
(IS_RACER_VARIANT_PRO16(ppdev) ? (DEMON_BANK_SELECT_OFFSET) : (REAL_RACER_BANK_SELECT_OFFSET))
#define SET_RACER_BANKSELECT(bufNo) { \
if (IS_RACER_VARIANT_PRO16(ppdev)) \
{WRITE_GLINT_CTRL_REG (DemonProUBufB, bufNo);} \
else \
{WRITE_GLINT_CTRL_REG (RacerBankSelect, bufNo);}\
}
#define GET_RACER_DOUBLEWRITE(onOffVal) { \
if (IS_RACER_VARIANT_PRO16(ppdev)) { \
READ_GLINT_CTRL_REG (DemonProDWAndStatus, onOffVal); \
} \
else \
{READ_GLINT_CTRL_REG (RacerDoubleWrite, onOffVal);} \
onOffVal &= 1 ; \
}
#define SET_RACER_DOUBLEWRITE(onOffVal) { \
if (IS_RACER_VARIANT_PRO16(ppdev)) \
{WRITE_GLINT_CTRL_REG (DemonProDWAndStatus, (onOffVal & 1));} \
else \
{WRITE_GLINT_CTRL_REG (RacerDoubleWrite, (onOffVal & 1));} \
}
/***** END OF RACER MACROS ***********/
#define MX_EXTRA_WAIT 1
#define GLINT_MX_SYNC \
{ \
if (GLINT_MX) \
/*LD_GLINT_FIFO(__GlintTagFBBlockColor, glintInfo->FBBlockColor); */\
LD_GLINT_FIFO(__GlintTagSync, 0); \
}
// DMAControl register setup, when using AGP DMA (p32 of Gamma HRM).
#define DMA_CONTROL_USE_AGP 0xE
#define DMA_CONTROL_USE_PCI 0x0
#if USE_LD_GLINT_FIFO_FUNCTION
# undef LD_GLINT_FIFO
# define LD_GLINT_FIFO(t, d) do { loadGlintFIFO( glintInfo, (ULONG) t, (ULONG) d ); } while(0)
typedef void (* LoadGlintFIFO)( GlintDataPtr, ULONG, ULONG );
extern LoadGlintFIFO loadGlintFIFO;
#endif
#if USE_SYNC_FUNCTION
# undef SYNC_WITH_GLINT_CHIP
# undef WAIT_DMA_COMPLETE
# define SYNC_WITH_GLINT_CHIP do { syncWithGlint(ppdev, glintInfo); } while(0)
# define WAIT_DMA_COMPLETE do { waitDMAcomplete(ppdev, glintInfo); } while(0)
void syncWithGlint( PPDEV ppdev, GlintDataPtr glintInfo );
void waitDMAcomplete( PPDEV ppdev, GlintDataPtr glintInfo );
#endif
#define SETUP_PPDEV_OFFSETS(ppdev, pdsurf) \
do \
{ \
ppdev->DstPixelOrigin = pdsurf->poh->pixOffset; \
ppdev->DstPixelDelta = pdsurf->poh->lPixDelta; \
ppdev->xyOffsetDst = MAKEDWORD_XY(pdsurf->poh->x, pdsurf->poh->y); \
ppdev->xOffset = (pdsurf->poh->bDXManaged) ? 0 : pdsurf->poh->x; \
ppdev->bDstOffScreen = pdsurf->bOffScreen; \
\
if (glintInfo->currentCSbuffer != 0) { \
ULONG xAdjust = GLINT_BUFFER_OFFSET(1) % ppdev->cxMemory; \
ppdev->DstPixelOrigin += GLINT_BUFFER_OFFSET(1) - xAdjust; \
ppdev->xOffset += xAdjust; \
} \
} while(0);
#define SETUP_PPDEV_SRC_OFFSETS(ppdev, pdsurfSrc) \
do \
{ \
ppdev->SrcPixelOrigin = pdsurfSrc->poh->pixOffset; \
ppdev->SrcPixelDelta = pdsurfSrc->poh->lPixDelta; \
ppdev->xyOffsetSrc = MAKEDWORD_XY(pdsurfSrc->poh->x, pdsurfSrc->poh->y); \
\
if (glintInfo->currentCSbuffer != 0) { \
ULONG xAdjust = GLINT_BUFFER_OFFSET(1) % ppdev->cxMemory; \
ppdev->SrcPixelOrigin += GLINT_BUFFER_OFFSET(1) - xAdjust; \
} \
} while(0)
#define SETUP_PPDEV_SRC_AND_DST_OFFSETS(ppdev, pdsurfSrc, pdsurfDst) \
do \
{ \
ppdev->SrcPixelOrigin = pdsurfSrc->poh->pixOffset; \
ppdev->SrcPixelDelta = pdsurfSrc->poh->lPixDelta; \
ppdev->xyOffsetSrc = MAKEDWORD_XY(pdsurfSrc->poh->x, pdsurfSrc->poh->y); \
\
ppdev->DstPixelOrigin = pdsurfDst->poh->pixOffset; \
ppdev->DstPixelDelta = pdsurfDst->poh->lPixDelta; \
ppdev->xyOffsetDst = MAKEDWORD_XY(pdsurfDst->poh->x, pdsurfDst->poh->y); \
ppdev->xOffset = (pdsurfDst->poh->bDXManaged) ? 0 : pdsurfDst->poh->x; \
ppdev->bDstOffScreen = pdsurfDst->bOffScreen; \
\
if (glintInfo->currentCSbuffer != 0) { \
ULONG xAdjust = GLINT_BUFFER_OFFSET(1) % ppdev->cxMemory; \
ppdev->DstPixelOrigin += GLINT_BUFFER_OFFSET(1) - xAdjust; \
ppdev->SrcPixelOrigin += GLINT_BUFFER_OFFSET(1) - xAdjust; \
ppdev->xOffset += xAdjust; \
} \
} while(0)
#define GET_PPDEV_DST_OFFSETS(ppdev, PixOrigin, PixDelta, xyOffset, xOff, bOffScreen) \
do \
{ \
PixOrigin = ppdev->DstPixelOrigin; \
PixDelta = ppdev->DstPixelDelta; \
xyOffset = ppdev->xyOffsetDst; \
xOff = ppdev->xOffset; \
bOffScreen = ppdev->bDstOffScreen; \
} while(0)
#define SET_PPDEV_DST_OFFSETS(ppdev, PixOrigin, PixDelta, xyOffset, xOff, bOffScreen) \
do \
{ \
ppdev->DstPixelOrigin = PixOrigin; \
ppdev->DstPixelDelta = PixDelta; \
ppdev->xyOffsetDst = xyOffset; \
ppdev->xOffset = xOff; \
ppdev->bDstOffScreen = bOffScreen; \
} while(0)
#endif // _GLINT_H_