fix low-memory checks

This commit is contained in:
cxgeorge 2002-03-19 05:36:52 +00:00
parent 6b7c334478
commit c84569bf73
2 changed files with 227 additions and 96 deletions

View File

@ -33,7 +33,6 @@
#endif
#include <ddraw.h>
#include <map>
////////////////////////////////////////////////////////////////////
@ -48,6 +47,20 @@ TypeHandle wdxGraphicsWindow::_type_handle;
typedef map<HWND,wdxGraphicsWindow *> HWND_PANDAWIN_MAP;
// CardIDVec is used in DX7 lowmem card-classification pass so DX8 can
// establish correspondence b/w DX7 mem info & DX8 device
typedef struct {
HMONITOR hMon;
DWORD MaxAvailVidMem;
bool bIsLowVidMemCard;
GUID DX7_DeviceGUID;
DWORD VendorID,DeviceID;
// char szDriver[MAX_DEVICE_IDENTIFIER_STRING];
} CardID;
typedef vector<CardID> CardIDVec;
static CardIDVec *g_pCardIDVec=NULL;
HWND_PANDAWIN_MAP hwnd_pandawin_map;
wdxGraphicsWindow* global_wdxwinptr = NULL; // need this for temporary windproc
@ -69,7 +82,7 @@ LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam,LPARAM lparam)
unsigned int hardcoded_modifier_buttons[NUM_MODIFIER_KEYS]={VK_SHIFT,VK_MENU,VK_CONTROL,VK_SPACE,VK_TAB,
VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT,VK_PRIOR,VK_NEXT,VK_HOME,VK_END,
VK_INSERT,VK_DELETE,VK_ESCAPE};
/*
static DWORD BitDepth_2_DDBDMask(DWORD iBitDepth) {
switch(iBitDepth) {
case 16: return DDBD_16;
@ -82,7 +95,7 @@ static DWORD BitDepth_2_DDBDMask(DWORD iBitDepth) {
}
return 0x0;
}
/*
typedef enum {DBGLEV_FATAL,DBGLEV_ERROR,DBGLEV_WARNING,DBGLEV_INFO,DBGLEV_DEBUG,DBGLEV_SPAM
} DebugLevels;
@ -93,7 +106,7 @@ void PrintDBGStr(DebugLevels level,HRESULT hr,const char *msgstr) {
assert(level<=DBGLEV_SPAM);
pstrm=dbg_strms[level];
(*pstrm)->fatal() << "GetDisplayMode failed, result = " << ConvD3DErrorToString(hr) << endl;
(*pstrm)->fatal() << "GetDisplayMode failed, hr = " << ConvD3DErrorToString(hr) << endl;
}
*/
@ -140,7 +153,7 @@ extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *p
// ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; done internally by DX anyway
if(FAILED( hr = pDD->GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) {
wdxdisplay_cat.debug() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl;
wdxdisplay_cat.debug() << "GetAvailableVidMem failed : hr = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
@ -651,7 +664,7 @@ bool wdxGraphicsWindow::reset_device_resize_window(RECT &viewrect) {
if(FAILED(hr)) {
if(hr==D3DERR_OUTOFVIDEOMEMORY)
return false;
wdxdisplay_cat.error() << "reset_device_resize_window Reset() failed, hr = " << D3DERRORSTRING(hr);
wdxdisplay_cat.error() << "reset_device_resize_window Reset() failed" << D3DERRORSTRING(hr);
exit(1);
}
@ -1298,7 +1311,7 @@ verify_window_sizes(unsigned int numsizes,unsigned int *dimen) {
DMI.pDDSD_Arr=DDSD_Arr;
if(FAILED(hr = _dxgsg->scrn.pDD->EnumDisplayModes(DDEDM_REFRESHRATES,&ddsd_search,&DMI,EnumDisplayModesCallBack))) {
wdxdisplay_cat.fatal() << "resize() - EnumDisplayModes failed, result = " << ConvD3DErrorToString(hr) << endl;
wdxdisplay_cat.fatal() << "resize() - EnumDisplayModes failed, hr = " << ConvD3DErrorToString(hr) << endl;
return 0;
}
@ -1339,6 +1352,137 @@ verify_window_sizes(unsigned int numsizes,unsigned int *dimen) {
#endif
}
BOOL WINAPI DX7_DriverEnumCallback( GUID* pGUID, TCHAR* strDesc,TCHAR* strName,VOID *argptr, HMONITOR hm) {
// #define PRNT(XX) ((XX!=NULL) ? XX : "NULL")
// cout << "strDesc: "<< PRNT(strDesc) << " strName: "<< PRNT(strName)<<endl;
CardID CurCardID;
ZeroMemory(&CurCardID,sizeof(CardID));
if(hm==NULL) {
CurCardID.hMon=MonitorFromWindow(GetDesktopWindow(),MONITOR_DEFAULTTOPRIMARY);
} else {
CurCardID.hMon=hm;
}
if(pGUID!=NULL)
memcpy(&CurCardID.DX7_DeviceGUID,pGUID,sizeof(GUID));
if(g_pCardIDVec==NULL) {
g_pCardIDVec= new CardIDVec;
}
g_pCardIDVec->push_back(CurCardID);
return DDENUMRET_OK;
}
void wdxGraphicsWindowGroup::
find_all_card_memavails(void) {
if(g_pCardIDVec!=NULL) // we've already got the info
return;
#define DDRAW_NAME "ddraw.dll"
HINSTANCE hDDrawDLL = LoadLibrary(DDRAW_NAME);
if(hDDrawDLL == 0) {
wdxdisplay_cat.fatal() << "can't locate " << DDRAW_NAME <<"!\n";
exit(1);
}
LPDIRECTDRAWCREATEEX pDDCreateEx;
pDDCreateEx = (LPDIRECTDRAWCREATEEX) GetProcAddress(hDDrawDLL,"DirectDrawCreateEx");
if(pDDCreateEx == NULL) {
wdxdisplay_cat.fatal() << "GetProcAddr failed for DDCreateEx" << endl;
exit(1);
}
LPDIRECTDRAWENUMERATEEX pDDEnumEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(hDDrawDLL,"DirectDrawEnumerateExA");
if(pDDEnumEx == NULL) {
wdxdisplay_cat.fatal() << "GetProcAddr failed for DirectDrawEnumerateEx! (win95 system?)\n";
exit(1);
}
HRESULT hr = (*pDDEnumEx)(DX7_DriverEnumCallback, NULL, DDENUM_ATTACHEDSECONDARYDEVICES | DDENUM_NONDISPLAYDEVICES);
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "DirectDrawEnumerateEx failed" << D3DERRORSTRING(hr);
exit(1);
}
if(g_pCardIDVec==NULL) {
wdxdisplay_cat.error() << "DirectDrawEnumerateEx enum'ed no devices!\n";
return;
}
GUID ZeroGUID;
ZeroMemory(&ZeroGUID,sizeof(GUID));
if(g_pCardIDVec->size()>1) {
assert(IsEqualGUID(ZeroGUID,(*g_pCardIDVec)[0].DX7_DeviceGUID));
// delete enum of primary display (always the first), since it is duplicated by explicit entry
g_pCardIDVec->erase(g_pCardIDVec->begin());
}
for(UINT i=0;i<g_pCardIDVec->size();i++) {
LPDIRECTDRAW7 pDD;
BYTE ddd_space[sizeof(DDDEVICEIDENTIFIER2)+4]; //bug in DX7 requires 4 extra bytes for GetDeviceID
DDDEVICEIDENTIFIER2 *pDX7DeviceID=(DDDEVICEIDENTIFIER2 *)&ddd_space[0];
GUID *pGUID= &((*g_pCardIDVec)[i].DX7_DeviceGUID);
if(IsEqualGUID(*pGUID,ZeroGUID))
pGUID=NULL;
// Create the Direct Draw Object
hr = (*pDDCreateEx)(pGUID,(void **)&pDD, IID_IDirectDraw7, NULL);
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "DirectDrawCreateEx failed for device ("<< i << ")" << D3DERRORSTRING(hr);
continue;
}
ZeroMemory(ddd_space,sizeof(DDDEVICEIDENTIFIER2));
hr = pDD->GetDeviceIdentifier(pDX7DeviceID,0x0);
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "GetDeviceID failed for device ("<< i << ")" << D3DERRORSTRING(hr);
continue;
}
(*g_pCardIDVec)[i].DeviceID = pDX7DeviceID->dwDeviceId;
(*g_pCardIDVec)[i].VendorID = pDX7DeviceID->dwVendorId;
// Get Current VidMem avail. Note this is only an estimate, when we switch to fullscreen
// mode from desktop, more vidmem will be available (typically 1.2 meg). I dont want
// to switch to fullscreen more than once due to the annoying monitor flicker, so try
// to figure out optimal mode using this estimate
DDSCAPS2 ddsGAVMCaps;
DWORD dwVidMemTotal,dwVidMemFree;
dwVidMemTotal=dwVidMemFree=0;
ZeroMemory(&ddsGAVMCaps,sizeof(DDSCAPS2));
ddsGAVMCaps.dwCaps = DDSCAPS_VIDEOMEMORY; //set internally by DX anyway, dont think this any different than 0x0
if(FAILED(hr = pDD->GetAvailableVidMem(&ddsGAVMCaps,&dwVidMemTotal,&dwVidMemFree))) {
wdxdisplay_cat.error() << "GetAvailableVidMem failed for device #"<< pDX7DeviceID->szDescription<< D3DERRORSTRING(hr);
// goto skip_device;
exit(1); // probably want to exit, since it may be my fault
}
pDD->Release(); // release DD obj, since this is all we needed it for
// after SetDisplayMode, GetAvailVidMem totalmem seems to go down by 1.2 meg (contradicting above
// comment and what I think would be correct behavior (shouldnt FS mode release the desktop vidmem?),
// so this is the true value
(*g_pCardIDVec)[i].MaxAvailVidMem = dwVidMemTotal;
#define LOWVIDMEMTHRESHOLD 3500000
#define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000
// assume buggy drivers (this means you, FireGL2) may return zero for dwVidMemTotal, so ignore value if its < CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD
(*g_pCardIDVec)[i].bIsLowVidMemCard = ((dwVidMemTotal>CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD) && (dwVidMemTotal< LOWVIDMEMTHRESHOLD));
}
FreeLibrary(hDDrawDLL);
}
/*
void wdxGraphicsWindow::
check_for_color_cursor_support(void) {
@ -1447,7 +1591,7 @@ bool wdxGraphicsWindow::FindBestDepthFormat(DXScreenData &Display,D3DDISPLAYMODE
if(hr==D3DERR_NOTAVAILABLE)
continue;
wdxdisplay_cat.error() << "unexpected CheckDeviceFormat failure, hr=" << D3DERRORSTRING(hr);
wdxdisplay_cat.error() << "unexpected CheckDeviceFormat failure" << D3DERRORSTRING(hr);
exit(1);
}
@ -1457,7 +1601,7 @@ bool wdxGraphicsWindow::FindBestDepthFormat(DXScreenData &Display,D3DDISPLAYMODE
TestDepthFmt);
if(FAILED(hr) && (hr!=D3DERR_NOTAVAILABLE)) {
wdxdisplay_cat.error() << "unexpected CheckDepthStencilMatch failure, hr=" << D3DERRORSTRING(hr);
wdxdisplay_cat.error() << "unexpected CheckDepthStencilMatch failure" << D3DERRORSTRING(hr);
exit(1);
}
@ -1491,7 +1635,7 @@ void wdxGraphicsWindow::search_for_valid_displaymode(UINT RequestedXsize,UINT Re
D3DDISPLAYMODE dispmode;
hr = _dxgsg->scrn.pD3D8->EnumAdapterModes(_dxgsg->scrn.CardIDNum,i,&dispmode);
if(FAILED(hr)) {
wdxdisplay_cat.error() << "EnumAdapterDisplayMode failed for device #"<<_dxgsg->scrn.CardIDNum<<": result = " << D3DERRORSTRING(hr);
wdxdisplay_cat.error() << "EnumAdapterDisplayMode failed for device #"<<_dxgsg->scrn.CardIDNum<< D3DERRORSTRING(hr);
exit(1);
}
@ -1509,7 +1653,7 @@ void wdxGraphicsWindow::search_for_valid_displaymode(UINT RequestedXsize,UINT Re
if(hr==D3DERR_NOTAVAILABLE)
continue;
else {
wdxdisplay_cat.error() << "CheckDeviceFormat failed for device #"<<_dxgsg->scrn.CardIDNum<<": result = " << D3DERRORSTRING(hr);
wdxdisplay_cat.error() << "CheckDeviceFormat failed for device #"<<_dxgsg->scrn.CardIDNum << D3DERRORSTRING(hr);
exit(1);
}
}
@ -1575,7 +1719,7 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
if(hr==D3DERR_INVALIDDEVICE) {
wdxdisplay_cat.fatal() << "No DirectX 8 D3D-capable 3D hardware detected! Exiting...\n";
} else {
wdxdisplay_cat.fatal() << "GetDeviceCaps failed, hr = " << D3DERRORSTRING(hr);
wdxdisplay_cat.fatal() << "GetDeviceCaps failed" << D3DERRORSTRING(hr);
}
exit(1);
}
@ -1584,9 +1728,33 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
memcpy(&_dxgsg->scrn.d3dcaps,&d3dcaps,sizeof(D3DCAPS8));
_dxgsg->scrn.CardIDNum=pDevInfo->cardID;
_dxgsg->scrn.MaxAvailVidMem = 0xFFFFFFFF;
_dxgsg->scrn.bIsLowVidMemCard = false;
if(d3dcaps.MaxStreams==0) {
wdxdisplay_cat.info() << "Note: video driver is a pre-DX8-class driver\n";
}
wdxdisplay_cat.info() << "Note: video driver is a pre-DX8-class driver, checking for low memory cards\n";
assert(IS_VALID_PTR(_pParentWindowGroup));
// look for low memory video cards
_pParentWindowGroup->find_all_card_memavails();
UINT IDnum;
// simple linear search
for(IDnum=0;IDnum<g_pCardIDVec->size();IDnum++) {
// wdxdisplay_cat.info() << "comparing '" << (*g_pCardIDVec)[IDnum].Driver << "' to '" << _dxgsg->scrn.DXDeviceID.Driver << "'\n";
if(//(stricmp((*g_pCardIDVec)[IDnum].szDriver,pDevInfo->szDriver)==0) &&
(pDevInfo->VendorID==(*g_pCardIDVec)[IDnum].VendorID) &&
(pDevInfo->DeviceID==(*g_pCardIDVec)[IDnum].DeviceID) &&
(pDevInfo->hMon==(*g_pCardIDVec)[IDnum].hMon))
break;
}
if(IDnum<g_pCardIDVec->size()) {
_dxgsg->scrn.MaxAvailVidMem = (*g_pCardIDVec)[IDnum].MaxAvailVidMem;
_dxgsg->scrn.bIsLowVidMemCard = (*g_pCardIDVec)[IDnum].bIsLowVidMemCard;
} else wdxdisplay_cat.error() << "Error: couldnt find a CardID match in DX7 info, assuming card is not a lowmem card\n";
}
if((bWantStencil) && (d3dcaps.StencilCaps==0x0)) {
wdxdisplay_cat.fatal() << "Stencil ability requested, but device #" << pDevInfo->cardID << " (" << _dxgsg->scrn.DXDeviceID.Description<<"), has no stencil capability!\n";
@ -1594,50 +1762,7 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
}
_dxgsg->scrn.bIsTNLDevice=((d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)!=0);
#ifdef DO_LOWVIDMEM_CHKS
// only way to get vidmem estimate prior to device creation and displaymode changing on DX8 is to use DX7 ddraw
LPDIRECTDRAW7 pDD;
// Create the Direct Draw Objects
hr = (*_pParentWindowGroup->_pDDCreateEx)(&pDevInfo->guidDeviceIdentifier,(void **)&pDD, IID_IDirectDraw7, NULL);
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "DirectDrawCreateEx failed for device ("<<pDevInfo->cardID<< "): result = " << D3DERRORSTRING(hr);
return false;
}
// Get Current VidMem avail. Note this is only an estimate, when we switch to fullscreen
// mode from desktop, more vidmem will be available (typically 1.2 meg). I dont want
// to switch to fullscreen more than once due to the annoying monitor flicker, so try
// to figure out optimal mode using this estimate
DDSCAPS2 ddsGAVMCaps;
DWORD dwVidMemTotal,dwVidMemFree;
dwVidMemTotal=dwVidMemFree=0;
ZeroMemory(&ddsGAVMCaps,sizeof(DDSCAPS2));
ddsGAVMCaps.dwCaps = DDSCAPS_VIDEOMEMORY; //set internally by DX anyway, dont think this any different than 0x0
if(FAILED(hr = pDD->GetAvailableVidMem(&ddsGAVMCaps,&dwVidMemTotal,&dwVidMemFree))) {
wdxdisplay_cat.error() << "GetAvailableVidMem failed for device #"<<pDevInfo->cardID<<": result = " << D3DERRORSTRING(hr);
// goto skip_device;
exit(1); // probably want to exit, since it may be my fault
}
pDD->Release(); // release DD obj, since this is all we needed it for
// after SetDisplayMode, GetAvailVidMem totalmem seems to go down by 1.2 meg (contradicting above
// comment and what I think would be correct behavior (shouldnt FS mode release the desktop vidmem?),
// so this is the true value
_dxgsg->scrn.MaxAvailVidMem = dwVidMemTotal;
#define LOWVIDMEMTHRESHOLD 3500000
#define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000
// assume buggy drivers (this means you, FireGL2) may return zero for dwVidMemTotal, so ignore value if its < CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD
_dxgsg->scrn.bIsLowVidMemCard = ((dwVidMemTotal>CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD) && (dwVidMemTotal< LOWVIDMEMTHRESHOLD));
#else
_dxgsg->scrn.bIsLowVidMemCard = false;
_dxgsg->scrn.MaxAvailVidMem = 350000000;
#endif
bool bNeedZBuffer = ((!(d3dcaps.RasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR ))
&& (_props._mask & W_DEPTH));
@ -1664,7 +1789,6 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
return false;
}
#ifdef DO_LOWVIDMEM_CHKS
if(_dxgsg->scrn.bIsLowVidMemCard) {
// hack: figuring out exactly what res to use is tricky, instead I will
// just use 640x480 if we have < 3 meg avail
@ -1675,7 +1799,7 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
pixFmt = D3DFMT_X1R5G5B5;
else {
wdxdisplay_cat.fatal() << "Low Memory VidCard has no supported FullScreen 16bpp resolutions at "<< dwRenderWidth << "x" << dwRenderHeight
<< " for device #" << pDevInfo->cardID << " (" << _dxgsg->scrn.DXDeviceID.Description<<"), skipping device...\n";
<< " for device #" << pDevInfo->cardID << " (" << _dxgsg->scrn.DXDeviceID.Description <<"), skipping device...\n";
return false;
}
dwRenderWidth=640;
@ -1683,14 +1807,13 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
dx_force_16bpptextures = true;
if(wdxdisplay_cat.is_info())
wdxdisplay_cat.info() << "Available VidMem (" << dwVidMemFree<<") is under " << LOWVIDMEMTHRESHOLD <<", using 640x480 16bpp rendertargets to save tex vidmem.\n";
wdxdisplay_cat.info() << "Available VidMem (" << _dxgsg->scrn.MaxAvailVidMem << ") is under " << LOWVIDMEMTHRESHOLD <<", using 640x480 16bpp rendertargets to save tex vidmem.\n";
}
#endif
} else {
D3DDISPLAYMODE dispmode;
hr=pD3D8->GetAdapterDisplayMode(pDevInfo->cardID,&dispmode);
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "GetAdapterDisplayMode(" << pDevInfo->cardID << ") failed, hr=" << D3DERRORSTRING(hr);
wdxdisplay_cat.fatal() << "GetAdapterDisplayMode(" << pDevInfo->cardID << ") failed" << D3DERRORSTRING(hr);
exit(1);
}
pixFmt = dispmode.Format;
@ -1719,7 +1842,7 @@ SetCoopLevelsAndDisplayModes(void) {
if(!_props._fullscreen) {
if(FAILED(hr = pScrn->pDD->SetCooperativeLevel(_hParentWindow, SCL_FPUFlag | DDSCL_NORMAL))) {
wdxdisplay_cat.fatal() << "SetCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl;
wdxdisplay_cat.fatal() << "SetCooperativeLevel failed" << ConvD3DErrorToString(hr) << endl;
exit(1);
}
return;
@ -1739,7 +1862,7 @@ SetCoopLevelsAndDisplayModes(void) {
// all ddraw objs need to have same focus window
if(_windows.size()>1) {
if(FAILED(hr = pScrn->pDD->SetCooperativeLevel(_hParentWindow, DDSCL_SETFOCUSWINDOW))) {
wdxdisplay_cat.fatal() << "SetCooperativeLevel SetFocusWindow failed on device 0: result = " << ConvD3DErrorToString(hr) << endl;
wdxdisplay_cat.fatal() << "SetCooperativeLevel SetFocusWindow failed on device 0: hr = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
}
@ -1748,13 +1871,13 @@ SetCoopLevelsAndDisplayModes(void) {
// so we do it, it really shouldnt be necessary if drivers werent buggy
for(int jj=0;jj<2;jj++) {
if(FAILED(hr = pScrn->pDD->SetCooperativeLevel(pScrn->hWnd, SCL_FLAGS))) {
wdxdisplay_cat.fatal() << "SetCooperativeLevel failed for device #"<< devnum<<": result = " << ConvD3DErrorToString(hr) << endl;
wdxdisplay_cat.fatal() << "SetCooperativeLevel failed for device #"<< devnum<<": hr = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
}
if(FAILED(hr = pScrn->pDD->TestCooperativeLevel())) {
wdxdisplay_cat.fatal() << "TestCooperativeLevel failed for device #"<< devnum<<": result = " << ConvD3DErrorToString(hr) << endl;
wdxdisplay_cat.fatal() << "TestCooperativeLevel failed for device #"<< devnum<<": hr = " << ConvD3DErrorToString(hr) << endl;
wdxdisplay_cat.fatal() << "Full screen app failed to get exclusive mode on init, exiting..\n";
exit(1);
}
@ -1763,7 +1886,7 @@ SetCoopLevelsAndDisplayModes(void) {
// let driver choose default refresh rate (hopefully its >=60Hz)
if(FAILED( hr = pScrn->pDD->SetDisplayMode( pScrn->dwRenderWidth, pScrn->dwRenderHeight,
pScrn->dwFullScreenBitDepth, 0, 0 ))) {
wdxdisplay_cat.fatal() << "SetDisplayMode failed to set ("<<pScrn->dwRenderWidth<<"x"<<pScrn->dwRenderHeight<<"x"<<pScrn->dwFullScreenBitDepth<<") on device #"<< pScrn->CardIDNum<<": result = " << ConvD3DErrorToString(hr) << endl;
wdxdisplay_cat.fatal() << "SetDisplayMode failed to set ("<<pScrn->dwRenderWidth<<"x"<<pScrn->dwRenderHeight<<"x"<<pScrn->dwFullScreenBitDepth<<") on device #"<< pScrn->CardIDNum<<": hr = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
@ -1775,7 +1898,7 @@ SetCoopLevelsAndDisplayModes(void) {
/*
#ifdef _DEBUG
if(FAILED(hr = (*Disply).pDD->GetAvailableVidMem(&ddsGAVMCaps,&dwVidMemTotal,&dwVidMemFree))) {
wdxdisplay_cat.debug() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl;
wdxdisplay_cat.debug() << "GetAvailableVidMem failed : hr = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
wdxdisplay_cat.debug() << "after fullscreen switch: GetAvailableVidMem returns Total: " << dwVidMemTotal/1000000.0 << " Free: " << dwVidMemFree/1000000.0 << endl;
@ -1935,7 +2058,7 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) {
hr = Display.pD3D8->GetAdapterDisplayMode(Display.CardIDNum, &dispmode);
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "GetAdapterDisplayMode failed result = " << D3DERRORSTRING(hr);
wdxdisplay_cat.fatal() << "GetAdapterDisplayMode failed" << D3DERRORSTRING(hr);
exit(1);
}
@ -1962,7 +2085,7 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) {
dwBehaviorFlags, pPresParams, &Display.pD3DDevice);
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "D3D CreateDevice failed for device #" << Display.CardIDNum << ", " << D3DERRORSTRING(hr);
wdxdisplay_cat.fatal() << "D3D CreateDevice failed for device #" << Display.CardIDNum << D3DERRORSTRING(hr);
exit(1);
}
} // end create windowed buffers
@ -1991,7 +2114,7 @@ Fallback_to_16bpp_buffers:
dx_force_16bpp_zbuffer=true;
if(wdxdisplay_cat.info())
wdxdisplay_cat.info() << "CreateDevice failed, retrying w/16bpp buffers on device #"<< Display.CardIDNum<< ", hr = " << D3DERRORSTRING(hr);
wdxdisplay_cat.info() << "CreateDevice failed, retrying w/16bpp buffers on device #"<< Display.CardIDNum << D3DERRORSTRING(hr);
CreateScreenBuffersAndDevice(Display);
return;
} else {
@ -2036,14 +2159,14 @@ void wdxGraphicsWindow::init_resized_window(void) {
hr = pDisplay->pD3DDevice->ResourceManagerDiscardBytes(0);
if(FAILED(hr)) {
wdxdisplay_cat.error() << "ResourceManagerDiscardBytes failed for device #" << pDisplay->CardIDNum << ", hr=" << D3DERRORSTRING(hr);
wdxdisplay_cat.error() << "ResourceManagerDiscardBytes failed for device #" << pDisplay->CardIDNum << D3DERRORSTRING(hr);
}
// Create the viewport
D3DVIEWPORT8 vp = {0,0,_props._xsize,_props._ysize,0.0f,1.0f};
hr = pDisplay->pD3DDevice->SetViewport( &vp );
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "SetViewport failed for device #" << pDisplay->CardIDNum << ", " << D3DERRORSTRING(hr);
wdxdisplay_cat.fatal() << "SetViewport failed for device #" << pDisplay->CardIDNum << D3DERRORSTRING(hr);
exit(1);
}
@ -2536,20 +2659,6 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
exit(1);
}
#define DDRAW_NAME "ddraw.dll"
_hDDrawDLL = LoadLibrary(DDRAW_NAME);
if(_hDDrawDLL == 0) {
wdxdisplay_cat.fatal() << "can't locate " << DDRAW_NAME <<"!\n";
exit(1);
}
_pDDCreateEx = (LPDIRECTDRAWCREATEEX) GetProcAddress(_hDDrawDLL,"DirectDrawCreateEx");
if(_pDDCreateEx == NULL) {
wdxdisplay_cat.fatal() << "Panda currently requires at least DirectX 7.0!\n";
exit(1);
}
_hMouseCursor = NULL;
_bLoadedCustomCursor = false;
@ -2566,6 +2675,9 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
}
}
// Do all DX7 stuff first
// find_all_card_memavails();
LPDIRECT3D8 pD3D8;
typedef LPDIRECT3D8 (WINAPI *Direct3DCreate8_ProcPtr)(UINT SDKVersion);
@ -2609,6 +2721,7 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
for(UINT i=0;i<_numAdapters;i++) {
D3DADAPTER_IDENTIFIER8 adapter_info;
ZeroMemory(&adapter_info,sizeof(D3DADAPTER_IDENTIFIER8));
hr = pD3D8->GetAdapterIdentifier(i,D3DENUM_NO_WHQL_LEVEL,&adapter_info);
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "D3D GetAdapterID failed" << D3DERRORSTRING(hr);
@ -2624,13 +2737,22 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
<< " SubsysID: 0x" << (void*) adapter_info.SubSysId << " Revision: 0x"
<< (void*) adapter_info.Revision << endl;
HMONITOR hMon=pD3D8->GetAdapterMonitor(i);
if(hMon==NULL) {
wdxdisplay_cat.info() << "D3D8 Adapter[" << i << "]: seems to be disabled, skipping it\n";
continue;
}
DXDeviceInfo devinfo;
ZeroMemory(&devinfo,sizeof(devinfo));
memcpy(&devinfo.guidDeviceIdentifier,&adapter_info.DeviceIdentifier,sizeof(GUID));
strncpy(devinfo.szDescription,adapter_info.Description,MAX_DEVICE_IDENTIFIER_STRING);
strncpy(devinfo.szDriver,adapter_info.Driver,MAX_DEVICE_IDENTIFIER_STRING);
devinfo.hMon=pD3D8->GetAdapterMonitor(i);
devinfo.VendorID=adapter_info.VendorId;
devinfo.DeviceID=adapter_info.DeviceId;
devinfo.hMon=hMon;
devinfo.cardID=i;
_DeviceInfoVec.push_back(devinfo);
}
@ -2666,6 +2788,17 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
_DeviceInfoVec.clear(); // dont need this anymore
if(wdxdisplay_cat.is_debug() && (g_pCardIDVec!=NULL)) {
// print out the MaxAvailVidMems
for(UINT i=0;i<_windows.size();i++) {
D3DADAPTER_IDENTIFIER8 adapter_info;
pD3D8->GetAdapterIdentifier(_windows[i]->_dxgsg->scrn.CardIDNum,D3DENUM_NO_WHQL_LEVEL,&adapter_info);
wdxdisplay_cat.info() << "D3D8 Adapter[" << i << "]: " << adapter_info.Description
<< ", MaxAvailVideoMem: " << _windows[i]->_dxgsg->scrn.MaxAvailVidMem
<< ", IsLowVidMemCard: " << (_windows[i]->_dxgsg->scrn.bIsLowVidMemCard ? "true" : "false") << endl;
}
}
CreateWindows(); // creates win32 windows (need to do this before Setting coopLvls and display modes,
// but after we have all the monitor handles needed by CreateWindow()
@ -2682,6 +2815,8 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
_windows[i]->finish_window_setup();
}
SAFE_DELETE(g_pCardIDVec); // dont need this anymore
for(UINT i=0;i<num_windows;i++) {
_windows[i]->_dxgsg->SetDXReady(true);
}
@ -2728,12 +2863,6 @@ wdxGraphicsWindowGroup::~wdxGraphicsWindowGroup() {
if(_bLoadedCustomCursor && (_hMouseCursor!=NULL))
DestroyCursor(_hMouseCursor);
if(_hDDrawDLL != NULL) {
FreeLibrary(_hDDrawDLL);
_hDDrawDLL = NULL;
}
if(_hD3D8_DLL != NULL) {
FreeLibrary(_hD3D8_DLL);
_hD3D8_DLL = NULL;

View File

@ -41,6 +41,7 @@ typedef struct {
char szDriver[MAX_DEVICE_IDENTIFIER_STRING];
char szDescription[MAX_DEVICE_IDENTIFIER_STRING];
GUID guidDeviceIdentifier;
DWORD VendorID,DeviceID;
HMONITOR hMon;
} DXDeviceInfo;
typedef vector<DXDeviceInfo> DXDeviceInfoVec;
@ -151,6 +152,8 @@ public:
wdxGraphicsWindowGroup(GraphicsPipe *pipe,int num_windows,GraphicsWindow::Properties *WinPropArray);
~wdxGraphicsWindowGroup();
// void SetCoopLevelsAndDisplayModes(void);
protected:
void find_all_card_memavails(void);
public:
void CreateWindows(void);
void make_windows(GraphicsPipe *,int num_windows,GraphicsWindow::Properties *pWinPropArray);
@ -166,8 +169,7 @@ public:
bool _bIsDX81;
DWORD _numMonitors,_numAdapters;
LPDIRECT3D8 _pD3D8;
HINSTANCE _hDDrawDLL,_hD3D8_DLL;
LPDIRECTDRAWCREATEEX _pDDCreateEx;
HINSTANCE _hD3D8_DLL;
DXDeviceInfoVec _DeviceInfoVec;
};