bool hsG3DDeviceSelector::IGetD3DCardInfo( hsG3DDeviceRecord &record, // In void *driverInfo, void *deviceInfo, DWORD *vendorID, DWORD *deviceID, // Out char **driverString, char **descString ) { D3DEnum_DriverInfo *driverD3DInfo = (D3DEnum_DriverInfo *)driverInfo; D3DEnum_DeviceInfo *deviceD3DInfo = (D3DEnum_DeviceInfo *)deviceInfo; D3DADAPTER_IDENTIFIER9 *adapterInfo; adapterInfo = &driverD3DInfo->fAdapterInfo; /// Print out to our demo data file plDemoDebugFile::Write( "DeviceSelector detected DX Direct3D device. Info:" ); plDemoDebugFile::Write( " Driver Description", (char *)adapterInfo->Description ); plDemoDebugFile::Write( " Driver Name", (char *)adapterInfo->Driver ); plDemoDebugFile::Write( " Vendor ID", (int32_t)adapterInfo->VendorId ); plDemoDebugFile::Write( " Device ID", (int32_t)adapterInfo->DeviceId ); plDemoDebugFile::Write( " Version", (char *)record.GetDriverVersion() ); plDemoDebugFile::Write( " Memory size (in MB)", record.GetMemoryBytes() / ( 1024 * 1024 ) ); plDemoDebugFile::Write( " Memory size (in bytes)", record.GetMemoryBytes() ); *vendorID = adapterInfo->VendorId; *deviceID = adapterInfo->DeviceId; *driverString = adapterInfo->Driver; *descString = adapterInfo->Description; return true; }
void hsG3DDeviceSelector::ITryDirect3DTnLDevice(D3DEnum_DeviceInfo* devInfo, hsG3DDeviceRecord& devRec) { devRec.SetDeviceDesc(devInfo->fStrName); if( devInfo->fDDType == D3DDEVTYPE_REF ) devRec.SetG3DHALorHEL( kHHD3DRefDev ); else if( devInfo->fDDType == D3DDEVTYPE_HAL ) { if( devInfo->fDDCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) { devRec.SetG3DHALorHEL( kHHD3DTnLHalDev ); devRec.SetCap( kCapsHWTransform ); } else devRec.SetG3DHALorHEL( kHHD3DHALDev ); } if( devInfo->fDDCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP ) devRec.SetCap( kCapsCubicTextures ); devRec.SetLayersAtOnce( devInfo->fDDCaps.MaxSimultaneousTextures ); if( devInfo->fDDCaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR ) devRec.SetCap( kCapsMipmap ); if( devInfo->fDDCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP ) devRec.SetCap( kCapsCubicMipmap ); if( devInfo->fDDCaps.TextureCaps & D3DPTEXTURECAPS_PERSPECTIVE ) devRec.SetCap(kCapsPerspective); if( devInfo->fIsHardware ) devRec.SetCap( kCapsHardware ); if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_DITHER ) devRec.SetCap(kCapsDither); if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_WBUFFER ) devRec.SetCap(kCapsWBuffer); if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_FOGTABLE ) { devRec.SetCap( kCapsFogLinear ); devRec.SetCap( kCapsFogExp ); devRec.SetCap( kCapsFogExp2 ); devRec.SetCap( kCapsPixelFog ); } else { devRec.SetCap( kCapsFogLinear ); } if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_FOGRANGE ) devRec.SetCap( kCapsFogRange ); if( devInfo->fDDCaps.MaxAnisotropy <= 1 ) devRec.SetMaxAnisotropicSamples( 0 ); else devRec.SetMaxAnisotropicSamples( (uint8_t)devInfo->fDDCaps.MaxAnisotropy ); if (D3DSHADER_VERSION_MAJOR(devInfo->fDDCaps.PixelShaderVersion) > 0) devRec.SetCap(kCapsPixelShader); /// Assume these by default devRec.SetCap( kCapsCompressTextures ); devRec.SetCap( kCapsDoesSmallTextures ); #if 1 // mf - want to leave this one off by default // if( devInfo->fCanAntialias ) // devRec.SetCap( kCapsAntiAlias ); #endif // mf - want to leave this one off by default hsG3DDeviceMode devMode; int i, j; const struct { D3DFORMAT fmt; uint16_t depth; } depths[] = { { D3DFMT_D16, 0x0010 }, { D3DFMT_D24X8, 0x0018 }, { D3DFMT_D32, 0x0020 }, { D3DFMT_D15S1, 0x010f }, { D3DFMT_D24X4S4, 0x0418 }, { D3DFMT_D24S8, 0x0818 }, { D3DFMT_UNKNOWN, 0 } }; for( i = 0; i < devInfo->fModes.GetCount(); i++ ) { D3DEnum_ModeInfo* modeInfo = &devInfo->fModes[i]; devMode.Clear(); devMode.SetWidth( modeInfo->fDDmode.Width ); devMode.SetHeight( modeInfo->fDDmode.Height ); devMode.SetColorDepth( modeInfo->fBitDepth ); if( modeInfo->fCanRenderToCubic ) devMode.SetCanRenderToCubics( true ); else devMode.SetCanRenderToCubics( false ); for( j = 0; depths[ j ].depth != 0; j++ ) { if( modeInfo->fDepthFormats.Find( depths[ j ].fmt ) != modeInfo->fDepthFormats.kMissingIndex ) devMode.AddZStencilDepth( depths[ j ].depth ); } for( j = 2; j <= 16; j++ ) { if( modeInfo->fFSAATypes.Find( (D3DMULTISAMPLE_TYPE)j ) != modeInfo->fFSAATypes.kMissingIndex ) devMode.AddFSAAType( j ); } devRec.GetModes().Append( devMode ); } }
void hsG3DDeviceSelector::ISetFudgeFactors( uint8_t chipsetID, hsG3DDeviceRecord &record ) { int i, maxIDs, j; maxIDs = sizeof( dsCFTable ) / sizeof( dsCFTable[ 0 ] ); /// Search for our chipset for( i = 0; i < maxIDs; i++ ) { if( dsCFTable[ i ].fType == chipsetID ) { /// Found it! // Flags to force set if( dsCFTable[ i ].fFlagsToSet != nil ) { for( j = 0; j < dsCFTable[ i ].fFlagsToSet[ 0 ]; j++ ) record.SetCap( dsCFTable[ i ].fFlagsToSet[ j + 1 ] ); } // Flags to force clear if( dsCFTable[ i ].fFlagsToClear != nil ) { for( j = 0; j < dsCFTable[ i ].fFlagsToClear[ 0 ]; j++ ) record.SetCap( dsCFTable[ i ].fFlagsToClear[ j + 1 ], false ); } // Suckiness record.SetZBiasRating( dsCFTable[ i ].fZSuckiness ); // Max # of layers if( dsCFTable[ i ].fForceMaxLayers > 0 ) record.SetLayersAtOnce( dsCFTable[ i ].fForceMaxLayers ); // LOD bias rating record.SetLODBiasRating( dsCFTable[ i ].fLODRating ); // Fog tweaks FogTweakTable *fogTweaks = dsCFTable[ i ].fFogTweaks; record.SetFogApproxStarts( fogTweaks->fFogExpApproxStart, fogTweaks->fFogExp2ApproxStart ); record.SetFogEndBias( fogTweaks->fFogEndBias ); record.SetFogKneeParams( hsG3DDeviceRecord::kFogExp, fogTweaks->fFogExpKnee, fogTweaks->fFogExpKneeVal ); record.SetFogKneeParams( hsG3DDeviceRecord::kFogExp2, fogTweaks->fFogExp2Knee, fogTweaks->fFogExp2KneeVal ); if( record.GetCap(kCapsNoAA) ) { int j; for( j = 0; j < record.GetModes().GetCount(); j++ ) record.GetModes()[j].ClearFSAATypes(); } return; } } }
void hsG3DDeviceSelector::IFudgeDirectXDevice( hsG3DDeviceRecord &record, D3DEnum_DriverInfo *driverInfo, D3DEnum_DeviceInfo *deviceInfo ) { uint32_t vendorID, deviceID; char *szDriver, *szDesc; /// Send it off to each D3D device, respectively if( record.GetG3DDeviceType() == kDevTypeDirect3D ) { if( !IGetD3DCardInfo( record, driverInfo, deviceInfo, &vendorID, &deviceID, &szDriver, &szDesc ) ) { // {} to make VC6 happy in release build hsAssert( false, "Trying to fudge D3D device but D3D support isn't in this EXE!" ); } } else { hsAssert( false, "IFudgeDirectXDevice got a device type that support wasn't compiled for!" ); } /// So capitalization won't matter in our tests plString desc = plString::FromIso8859_1(szDesc).ToLower(); /// Detect ATI Radeon chipset // We will probably need to differentiate between different Radeons at some point in // the future, but not now. ssize_t radeon = desc.Find("radeon"); if (stricmp(szDriver, "ati2dvag.dll") == 0 || radeon >= 0) { int series = 0; if (radeon >= 0) { const char* str = desc.c_str() + radeon + strlen("radeon"); if( 1 == sscanf(str, "%d", &series) ) { if( (series >= 8000) && (series < 9000) ) { hsStatusMessage( "== Using fudge factors for ATI Radeon 8X00 chipset ==\n" ); ISetFudgeFactors( kATIR8X00Chipset, record ); } else if (series >= 9000) { hsStatusMessage("== Using fudge factors for ATI Radeon 9X00 chipset ==\n"); ISetFudgeFactors(kATIRadeonChipset, record); } else { series = 0; } } } if (series == 0) { hsStatusMessage("== Using fudge factors for ATI/AMD Radeon X/HD/R chipset ==\n"); ISetFudgeFactors(kDefaultChipset, record); } } //// Other Cards ////////////////////////////////////////////////////////// /// Detect Intel i810 chipset else if( deviceID == 0x00007125 && ( stricmp( szDriver, "i81xdd.dll" ) == 0 || ( desc.Find("intel") >= 0 && desc.Find("810") >= 0 ) ) ) { hsStatusMessage( "== Using fudge factors for an Intel i810 chipset ==\n" ); ISetFudgeFactors( kIntelI810Chipset, record ); } /// Detect for a GeForc FX card. We only need to nerf the really low end one. else if( desc.Find("nvidia") >= 0 && desc.Find("geforce fx 5200") >= 0 ) { hsStatusMessage( "== Using fudge factors for an NVidia GeForceFX-based chipset ==\n" ); ISetFudgeFactors( kNVidiaGeForceFXChipset, record ); } /// Default fudge values else { hsStatusMessage( "== Using default fudge factors ==\n" ); ISetFudgeFactors( kDefaultChipset, record ); } }