diff --git a/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx b/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx index 478c091876..2257193c18 100644 --- a/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx +++ b/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx @@ -33,7 +33,6 @@ #endif #include - #include //////////////////////////////////////////////////////////////////// @@ -48,6 +47,20 @@ TypeHandle wdxGraphicsWindow::_type_handle; typedef map 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 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)<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;isize();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;IDnumsize();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(IDnumsize()) { + _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 ("<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 #"<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 ("<dwRenderWidth<<"x"<dwRenderHeight<<"x"<dwFullScreenBitDepth<<") on device #"<< pScrn->CardIDNum<<": result = " << ConvD3DErrorToString(hr) << endl; + wdxdisplay_cat.fatal() << "SetDisplayMode failed to set ("<dwRenderWidth<<"x"<dwRenderHeight<<"x"<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_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; diff --git a/panda/src/wdxdisplay8/wdxGraphicsWindow8.h b/panda/src/wdxdisplay8/wdxGraphicsWindow8.h index 4be4143e7f..5b69c0675b 100644 --- a/panda/src/wdxdisplay8/wdxGraphicsWindow8.h +++ b/panda/src/wdxdisplay8/wdxGraphicsWindow8.h @@ -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 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; };