/*------------------------------------------------------------------- Function: initControl Date: 10/9 Implementor(s): murali Library: init Description: This will re-attach new buffers for the rendering context, used typically only in a windowing system where buffers need to move and resize. Also, implicitly detach old associated buffers. Arguments: XXX Return: FXTRUE - all resources requested where allocated FXFALSE - some or all resources were not available. By comparing desc before and after call, the user can determine which resources were denied. -------------------------------------------------------------------*/ FxBool initControl( FxU32 code) { FxBool rv; GDBG_INFO((80, "initControl: code = %d, context=%.08x\n", code, context)); if ( context ) { rv = context->control( code ); } else { rv = FXFALSE; } return rv; } /* initControl */
void _grDebugGroupWriteHeader(FxU32 header, FxU32 address) { #define FN_NAME "_grDebugGroupWriteHeader" GR_DCL_GC; FxU32 offset, /* laddress, * chipField, */ lheader = header; int index, nBits = 0; GR_ASSERT(address & GWH_ENABLE_BIT); GDBG_INFO((128, "New Group Write Packet ======================\n")); GDBG_INFO((128, "Address: 0x%x\n", address)); GDBG_INFO((128, "Header: 0x%x\n", header)); GDBG_INFO((128, "PCI Address: 0x%x\n", (address & 0xfffff) << 2)); GDBG_INFO((128, "Chip Field: 0x%x\n", (address >> 14) & 0xf)); offset = (address & ~(0xf << 14)) & 0xfffff; index = offset; if (offset < 0x100 ) { /* It's state or triangle */ GDBG_INFO((128, "Start: 0x%s (0x%x)\n", regNames[index], index)); GDBG_INFO((128, "Mask: 0x%x\n", header)); while (lheader) { if (lheader & 0x1) { nBits++; GDBG_INFO((128, "Includes:\t%s (0x%x)\n", regNames[index], index)); } lheader >>= 1; index++; } } else if (offset >= 0x10000) { /* It's texture */
FxBool hwcAllocBuffers(hwcBoardInfo *bInfo, FxU32 nColBuffers, FxU32 nAuxBuffers) { #define FN_NAME "hwcAllocBuffers" FxU32 bufStride, bufSize; if (bInfo->vidInfo.initialized == FXFALSE) { sprintf(errorString, "%s: Called before video initialization\n", FN_NAME); return FXFALSE; } GDBG_INFO(80, "%s(0x%x, 0x%x, 0x%x)\n", FN_NAME, bInfo, nColBuffers, nAuxBuffers); /* I've decided on > 2 instead of == 3 because we may support more than 3 buffers in the future, and want 4 to set the triple-buffering bit in dramInit1, also */ bInfo->vidInfo.tripleBuffering = (nColBuffers > 2); bInfo->vidInfo.stride = bufStride = calcBufferStride(driInfo.screenWidth, bInfo->vidInfo.tiled); /* We want to place the FIFO after the tram but before the color buffers with some pad */ bufSize = calcBufferSize(driInfo.screenWidth, driInfo.screenHeight, bInfo->vidInfo.tiled); bInfo->buffInfo.bufStride = bufStride; bInfo->buffInfo.bufSize = bufSize; if (bInfo->vidInfo.tiled) { bInfo->buffInfo.bufStrideInTiles = (bufStride >> 7); bInfo->buffInfo.bufSizeInTiles = calcBufferSizeInTiles(driInfo.screenWidth, driInfo.screenHeight); bInfo->buffInfo.bufHeightInTiles = calcBufferHeightInTiles(driInfo.screenHeight); }
/*------------------------------------------------------------------- Function: initEnumHardware Date: 10/9 Implementor(s): jdt Library: init Description: Calls a user supplied function on an initialized InitDeviceInfo structure for each device in the system. Calls a user supplied callback repeatedly for each device in the system. The callback can stop the enumeration cycle by return a value of FXTRUE. Arguments: cb - callback function of type INitHWEnumCallback which is called on an initialzied InitDeviceInfo structure Return: none -------------------------------------------------------------------*/ void initEnumHardware( InitHWEnumCallback *cb ) { FxU32 busLocation; FxU32 device; if ( !libInitialized ) { /* When initializing the Library snoop out all 3Dfx devices and fill a static data structure with pertinant data. */ numDevicesInSystem = 0; numSst1s = 0; if ( !pciOpen() ) return; for( busLocation = 0; busLocation < MAX_PCI_DEVICES; busLocation++ ) { if ( pciDeviceExists( busLocation ) ) { FxU32 vId, dId; pciGetConfigData( PCI_VENDOR_ID, busLocation, &vId ); pciGetConfigData( PCI_DEVICE_ID, busLocation, &dId ); GDBG_INFO((80, "initEnumHardware: Vendor: 0x%x Device: 0x%x\n", vId, dId)); #if defined( SST1 ) if ( (vId == TDFXVID) && (dId == SST1DID) ) { /* Detect SST1 */ FxU32 *base; sst1DeviceInfoStruct info; /* Scanline interleave must be two boards back to back if there is a second board in the system, and the previous board was SLI, then this is the slave */ if ( numDevicesInSystem > 0 ) { if ( hwInfo[numDevicesInSystem-1].hwClass==INIT_VOODOO && hwInfo[numDevicesInSystem-1].hwDep.vgInfo.sliDetect ) { hwInfo[numDevicesInSystem-1].hwDep.vgInfo.slaveBaseAddr = (FxU32)sst1InitMapBoard( numSst1s ); hwInfo[numDevicesInSystem-1].regs.hwDep.VGRegDesc.slavePtr = (FxU32*)hwInfo[numDevicesInSystem-1].hwDep.vgInfo.slaveBaseAddr; numSst1s++; continue; } } hwInfo[numDevicesInSystem].vendorID = (FxU16) vId; hwInfo[numDevicesInSystem].deviceID = (FxU16) dId; hwInfo[numDevicesInSystem].devNumber = numDevicesInSystem; hwInfo[numDevicesInSystem].hwClass = INIT_VOODOO; /* On SST-1 We Have to Initialize the Registers to Discover the configuration of the board */ #if 0 base = sst1InitMapBoard( numSst1s ); sst1InitRegisters( base ); #else base = (FxU32*)initMapBoard(numSst1s); #endif sst1InitGetDeviceInfo( base, &info ); hwInfo[numDevicesInSystem].hwDep.vgInfo.vgBaseAddr = (FxU32) base; hwInfo[numDevicesInSystem].hwDep.vgInfo.pfxRev = info.fbiRevision; hwInfo[numDevicesInSystem].hwDep.vgInfo.pfxRam = info.fbiMemSize; hwInfo[numDevicesInSystem].hwDep.vgInfo.nTFX = info.numberTmus; hwInfo[numDevicesInSystem].hwDep.vgInfo.tfxRev = info.tmuRevision; hwInfo[numDevicesInSystem].hwDep.vgInfo.tfxRam = info.tmuMemSize[0]; hwInfo[numDevicesInSystem].hwDep.vgInfo.sliDetect = info.sstSliDetect; hwInfo[numDevicesInSystem].hwDep.vgInfo.slaveBaseAddr = 0; hwInfo[numDevicesInSystem].regs.hwDep.VGRegDesc.baseAddress = base; hwInfo[numDevicesInSystem].regs.hwDep.VGRegDesc.slavePtr = 0; numSst1s++; numDevicesInSystem++; } #elif defined(SST96) #define IS_CHIP(name) (vId == name##VID && dId == name##DID) if (IS_CHIP(AT3D) || IS_CHIP(MCRX)) { if (IS_CHIP(MCRX)) { /* In the case of Macronix, look for 3d4/3f[2] == 1, as they set that bit when we're attached. */ FxU8 regVal; _outp(0x3d4, 0x3f); regVal = _inp(0x3d5); if (!(regVal & (1 << 2))) /* we're not there */ continue; } hwInfo[numDevicesInSystem].vendorID = (FxU16) vId; hwInfo[numDevicesInSystem].deviceID = (FxU16) dId; hwInfo[numDevicesInSystem].devNumber = numDevicesInSystem; hwInfo[numDevicesInSystem].hwClass = INIT_VG96; /* SST-96 initialization also retrieves board configuration info */ #if 0 init96MapBoard(&hwInfo[numDevicesInSystem].regs, &hwInfo[numDevicesInSystem].hwDep.vg96Info, (FxU16) vId, (FxU16) dId); #else initMapBoard(numDevicesInSystem); #endif hwInfo[numDevicesInSystem].hwDep.vg96Info.vgaBaseAddr = (FxU32)hwInfo[numDevicesInSystem].regs.hwDep.VG96RegDesc.partnerRegPtr; hwInfo[numDevicesInSystem].hwDep.vg96Info.vg96BaseAddr = (FxU32)hwInfo[numDevicesInSystem].regs.hwDep.VG96RegDesc.baseAddress; numDevicesInSystem++; } #else # error "Do hardware enumeration for this chip!" #endif } } /* Sanity Check for SLI detection */ for( device = 0; device < numDevicesInSystem; device++ ) { if ( hwInfo[device].hwClass == INIT_VOODOO && hwInfo[device].hwDep.vgInfo.sliDetect && hwInfo[device].hwDep.vgInfo.slaveBaseAddr == 0 ) { hwInfo[device].hwDep.vgInfo.sliDetect = FXFALSE; } } /* Initialize all drivers */ vgDriverInit( &contexts[INIT_VOODOO] ); vg96DriverInit( &contexts[INIT_VG96] ); /* Mark the library as initialized */ libInitialized = FXTRUE; } if ( cb ) { for( device = 0; device < numDevicesInSystem; device++ ) { cb( &hwInfo[device] ); } } return; } /* initEnumHardware */
/* Make sure that the trilinear blending bits are set in a * consistent manner across the tmu's. This only really matters if * we have multiple tmu's, but this state is really setup across * multiple calls (grTexCombine, grTexMipMapMode, and * grTexSource). * * NB: This must be called after the shadows are updated because * _grTexCheckTriLinear() will use the shadow register values * to determine the current state of trilinearness. * * FixMe: This should eventually get merged in w/ the texture * statemonster. When/If that ever happens. */ static void _grTexCheckTriLinear(GrChipID_t tmu) { #define FN_NAME "_grTexCheckTriLinear" GR_BEGIN_NOFIFOCHECK(FN_NAME, 90); GDBG_INFO_MORE(gc->myLevel, "(0x%X)\n", tmu); #if (GLIDE_NUM_TMU > 2) #error "(GLIDE_NUM_TMU > 2): Write this code" #endif /* NB: The factor mask needs to include the factor bits as * well as the reverse bit so that we can differentiate * between the lodfrac and the (1 - lodfrac) case. */ #define SST_TC_FACTOR_MASK (SST_TC_MSELECT | SST_TC_REVERSE_BLEND) #define SST_MIPMAP_LEVEL_MASK (SST_LOD_ODD | SST_LOD_TSPLIT) /* Is this tmu on? */ if (!gc->tmuLodDisable[tmu]) { const struct tmu_config_t* tmu0 = gc->state.tmu_config; const struct tmu_config_t* tmu1 = gc->state.tmu_config + 1; const struct tmu_config_t* curTmu = gc->state.tmu_config + tmu; const struct tmu_config_t* otherTmu = gc->state.tmu_config + !tmu; /* This is the 'tricky' state where we have to manage the states * of teh tmu's together to get the correct effect. Within this * state there are two sub-states: two-pass trilinear and single * pass using both tmu's w/ split levels. * * Case 1 - TMU set for lod blending and has both even/odd levels */ if (((curTmu->textureMode & SST_TRILINEAR) == SST_TRILINEAR) && (curTmu->evenOdd == GR_MIPMAPLEVELMASK_BOTH)) { /* Check the 'other' tmu to see if it is active, if not then we * are doing two pass trilinear so check that we have the * correct even/odd things set based on the factor where one * pass will use GR_COMBINE_FACTOR_LOD_FRACTION and the other * will use (1 - GR_COMBINE_FACTOR_LOD_FRACTION). */ if (gc->tmuLodDisable[!tmu]) { /* NB: In this case the rgb/alpha factors need to match so * checking for only one of them is fine. */ const FxU32 levelMask = (((curTmu->textureMode & SST_TC_FACTOR_MASK) == SST_TC_MLODFRAC) ? SST_LOD_ODD : 0); GDBG_INFO(gc->myLevel, FN_NAME": Two-pass trilinear fixup (0x%X) : tLOD : (0x%X : 0x%X)\n", tmu, curTmu->tLOD, ((curTmu->tLOD & ~SST_MIPMAP_LEVEL_MASK) | levelMask)); GR_SET_EXPECTED_SIZE(sizeof(FxU32), 1); GR_SET(eChipTMU0, SST_TMU(hw, 0), tLOD, ((curTmu->tLOD & ~SST_MIPMAP_LEVEL_MASK) | levelMask)); GR_CHECK_SIZE(); } else { /* One pass trilinear * * Make sure that the tmu's have the levels split across the * two tmu's. There are basically three cases based on what * the user might have already set on the other tmu. */ if (((tmu0->textureMode & SST_TC_BLEND) == SST_TC_BLEND) && ((tmu1->textureMode & SST_TC_REPLACE) == SST_TC_REPLACE)) { FxU32 evenOdd[GLIDE_NUM_TMU]; FxU32* curEvenOdd = evenOdd + tmu; { FxU32 i; for(i = 0; i < GLIDE_NUM_TMU; i++) { evenOdd[i] = gc->state.tmu_config[i].tLOD & SST_LOD_ODD; } } /* 1 - The other tmu already has the even levels. */ if ((otherTmu->evenOdd == GR_MIPMAPLEVELMASK_EVEN) && (curTmu->evenOdd != GR_MIPMAPLEVELMASK_ODD)) { *curEvenOdd = SST_LOD_ODD; goto __tmuRegUpdate; } /* 2 - The other tmu already has the odd levels. */ if ((otherTmu->evenOdd == GR_MIPMAPLEVELMASK_ODD) && (curTmu->evenOdd != GR_MIPMAPLEVELMASK_EVEN)) { *curEvenOdd = 0; goto __tmuRegUpdate; } /* 3 - The other tmu already has both the levels. If the * downstream tmu's factor is lodFrac then the upstream tmu * needs to be (1 - lodFrac) and vice-versa. */ if (otherTmu->evenOdd == GR_MIPMAPLEVELMASK_BOTH) { evenOdd[0] = (((tmu0->textureMode & SST_TC_FACTOR_MASK) == SST_TC_MLODFRAC) ? SST_LOD_ODD : 0); evenOdd[1] = ~evenOdd[0] & SST_LOD_ODD; goto __tmuRegUpdate; } /* Do the register updates */ if (0) { __tmuRegUpdate: GDBG_INFO(gc->myLevel, FN_NAME": Tri-linear fixup (0x%X : 0x%X) : (0x%X : 0x%X)\n", tmu0->tLOD, tmu1->tLOD, ((tmu0->tLOD & ~SST_MIPMAP_LEVEL_MASK) | evenOdd[0]), ((tmu1->tLOD & ~SST_MIPMAP_LEVEL_MASK) | evenOdd[1])); GR_SET_EXPECTED_SIZE((sizeof(FxU32) << 1), 2); { GR_SET(eChipTMU0, SST_TMU(hw, 0), tLOD, ((tmu0->tLOD & ~SST_MIPMAP_LEVEL_MASK) | evenOdd[0])); GR_SET(eChipTMU1, SST_TMU(hw, 1), tLOD, ((tmu1->tLOD & ~SST_MIPMAP_LEVEL_MASK) | evenOdd[1])); } GR_CHECK_SIZE(); } } } } } GR_END(); #undef FN_NAME }