Browse Source

fix low-memory checks

cxgeorge 24 years ago
parent
commit
c84569bf73

+ 223 - 94
panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx

@@ -33,7 +33,6 @@
 #endif
 #endif
 
 
 #include <ddraw.h>
 #include <ddraw.h>
-
 #include <map>
 #include <map>
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -48,6 +47,20 @@ TypeHandle wdxGraphicsWindow::_type_handle;
 
 
 typedef map<HWND,wdxGraphicsWindow *> HWND_PANDAWIN_MAP;
 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;
 HWND_PANDAWIN_MAP hwnd_pandawin_map;
 wdxGraphicsWindow* global_wdxwinptr = NULL;  // need this for temporary windproc
 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,
 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_UP,VK_DOWN,VK_LEFT,VK_RIGHT,VK_PRIOR,VK_NEXT,VK_HOME,VK_END,
                                          VK_INSERT,VK_DELETE,VK_ESCAPE};
                                          VK_INSERT,VK_DELETE,VK_ESCAPE};
-
+/*
 static DWORD BitDepth_2_DDBDMask(DWORD iBitDepth) {
 static DWORD BitDepth_2_DDBDMask(DWORD iBitDepth) {
     switch(iBitDepth) {
     switch(iBitDepth) {
         case 16: return DDBD_16;
         case 16: return DDBD_16;
@@ -82,7 +95,7 @@ static DWORD BitDepth_2_DDBDMask(DWORD iBitDepth) {
     }
     }
     return 0x0;
     return 0x0;
 }
 }
-/*
+
 typedef enum {DBGLEV_FATAL,DBGLEV_ERROR,DBGLEV_WARNING,DBGLEV_INFO,DBGLEV_DEBUG,DBGLEV_SPAM
 typedef enum {DBGLEV_FATAL,DBGLEV_ERROR,DBGLEV_WARNING,DBGLEV_INFO,DBGLEV_DEBUG,DBGLEV_SPAM
     } DebugLevels;
     } DebugLevels;
  
  
@@ -93,7 +106,7 @@ void PrintDBGStr(DebugLevels level,HRESULT hr,const char *msgstr) {
     assert(level<=DBGLEV_SPAM);
     assert(level<=DBGLEV_SPAM);
 
 
     pstrm=dbg_strms[level];
     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
 //  ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; done internally by DX anyway
 
 
     if(FAILED(  hr = pDD->GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) {
     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);
         exit(1);
     }
     }
 
 
@@ -651,7 +664,7 @@ bool wdxGraphicsWindow::reset_device_resize_window(RECT &viewrect) {
     if(FAILED(hr)) {
     if(FAILED(hr)) {
         if(hr==D3DERR_OUTOFVIDEOMEMORY)
         if(hr==D3DERR_OUTOFVIDEOMEMORY)
             return false;
             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);
         exit(1);
     }
     }
 
 
@@ -1298,7 +1311,7 @@ verify_window_sizes(unsigned int numsizes,unsigned int *dimen) {
        DMI.pDDSD_Arr=DDSD_Arr;
        DMI.pDDSD_Arr=DDSD_Arr;
     
     
        if(FAILED(hr = _dxgsg->scrn.pDD->EnumDisplayModes(DDEDM_REFRESHRATES,&ddsd_search,&DMI,EnumDisplayModesCallBack))) {
        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;
            return 0;
        }
        }
     
     
@@ -1339,6 +1352,137 @@ verify_window_sizes(unsigned int numsizes,unsigned int *dimen) {
  #endif
  #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::
 void wdxGraphicsWindow::
 check_for_color_cursor_support(void) {
 check_for_color_cursor_support(void) {
@@ -1447,7 +1591,7 @@ bool wdxGraphicsWindow::FindBestDepthFormat(DXScreenData &Display,D3DDISPLAYMODE
           if(hr==D3DERR_NOTAVAILABLE)
           if(hr==D3DERR_NOTAVAILABLE)
               continue;
               continue;
 
 
-          wdxdisplay_cat.error() << "unexpected CheckDeviceFormat failure, hr=" << D3DERRORSTRING(hr);
+          wdxdisplay_cat.error() << "unexpected CheckDeviceFormat failure" << D3DERRORSTRING(hr);
           exit(1);
           exit(1);
         }
         }
 
 
@@ -1457,7 +1601,7 @@ bool wdxGraphicsWindow::FindBestDepthFormat(DXScreenData &Display,D3DDISPLAYMODE
                                            TestDepthFmt);
                                            TestDepthFmt);
 
 
         if(FAILED(hr) && (hr!=D3DERR_NOTAVAILABLE)) {
         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);
           exit(1);
         }
         }
 
 
@@ -1491,7 +1635,7 @@ void wdxGraphicsWindow::search_for_valid_displaymode(UINT RequestedXsize,UINT Re
         D3DDISPLAYMODE dispmode;
         D3DDISPLAYMODE dispmode;
         hr = _dxgsg->scrn.pD3D8->EnumAdapterModes(_dxgsg->scrn.CardIDNum,i,&dispmode);
         hr = _dxgsg->scrn.pD3D8->EnumAdapterModes(_dxgsg->scrn.CardIDNum,i,&dispmode);
         if(FAILED(hr)) {
         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); 
             exit(1); 
         }
         }
 
 
@@ -1509,7 +1653,7 @@ void wdxGraphicsWindow::search_for_valid_displaymode(UINT RequestedXsize,UINT Re
            if(hr==D3DERR_NOTAVAILABLE)
            if(hr==D3DERR_NOTAVAILABLE)
                continue;
                continue;
              else {
              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); 
                  exit(1); 
              }
              }
         }
         }
@@ -1575,7 +1719,7 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
          if(hr==D3DERR_INVALIDDEVICE) {
          if(hr==D3DERR_INVALIDDEVICE) {
              wdxdisplay_cat.fatal() << "No DirectX 8 D3D-capable 3D hardware detected!  Exiting...\n";
              wdxdisplay_cat.fatal() << "No DirectX 8 D3D-capable 3D hardware detected!  Exiting...\n";
          } else {
          } else {
-             wdxdisplay_cat.fatal() << "GetDeviceCaps failed, hr = " << D3DERRORSTRING(hr);
+             wdxdisplay_cat.fatal() << "GetDeviceCaps failed" << D3DERRORSTRING(hr);
          }
          }
          exit(1);
          exit(1);
     }
     }
@@ -1584,9 +1728,33 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
     memcpy(&_dxgsg->scrn.d3dcaps,&d3dcaps,sizeof(D3DCAPS8));  
     memcpy(&_dxgsg->scrn.d3dcaps,&d3dcaps,sizeof(D3DCAPS8));  
     _dxgsg->scrn.CardIDNum=pDevInfo->cardID; 
     _dxgsg->scrn.CardIDNum=pDevInfo->cardID; 
 
 
+    _dxgsg->scrn.MaxAvailVidMem = 0xFFFFFFFF;
+    _dxgsg->scrn.bIsLowVidMemCard = false;
+
     if(d3dcaps.MaxStreams==0) {
     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)) {
     if((bWantStencil) && (d3dcaps.StencilCaps==0x0)) {
             wdxdisplay_cat.fatal() << "Stencil ability requested, but device #" << pDevInfo->cardID << " (" << _dxgsg->scrn.DXDeviceID.Description<<"), has no stencil capability!\n";
             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);
     _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 )) 
     bool bNeedZBuffer = ((!(d3dcaps.RasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )) 
                          && (_props._mask & W_DEPTH));
                          && (_props._mask & W_DEPTH));
@@ -1664,7 +1789,6 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
            return false;
            return false;
         }
         }
         
         
-        #ifdef DO_LOWVIDMEM_CHKS
         if(_dxgsg->scrn.bIsLowVidMemCard) {
         if(_dxgsg->scrn.bIsLowVidMemCard) {
                // hack: figuring out exactly what res to use is tricky, instead I will
                // hack: figuring out exactly what res to use is tricky, instead I will
                // just use 640x480 if we have < 3 meg avail
                // 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;
                    pixFmt = D3DFMT_X1R5G5B5;
                else {
                else {
                    wdxdisplay_cat.fatal() << "Low Memory VidCard has no supported FullScreen 16bpp resolutions at "<< dwRenderWidth << "x" << dwRenderHeight   
                    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;
                    return false;
                }
                }
                dwRenderWidth=640;
                dwRenderWidth=640;
@@ -1683,14 +1807,13 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
                dx_force_16bpptextures = true;
                dx_force_16bpptextures = true;
         
         
                if(wdxdisplay_cat.is_info())
                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 {
     } else {
         D3DDISPLAYMODE dispmode;
         D3DDISPLAYMODE dispmode;
         hr=pD3D8->GetAdapterDisplayMode(pDevInfo->cardID,&dispmode);
         hr=pD3D8->GetAdapterDisplayMode(pDevInfo->cardID,&dispmode);
         if(FAILED(hr)) {
         if(FAILED(hr)) {
-            wdxdisplay_cat.fatal() << "GetAdapterDisplayMode(" << pDevInfo->cardID << ") failed, hr=" << D3DERRORSTRING(hr);
+            wdxdisplay_cat.fatal() << "GetAdapterDisplayMode(" << pDevInfo->cardID << ") failed" << D3DERRORSTRING(hr);
             exit(1);
             exit(1);
         }
         }
         pixFmt = dispmode.Format;
         pixFmt = dispmode.Format;
@@ -1719,7 +1842,7 @@ SetCoopLevelsAndDisplayModes(void) {
 
 
     if(!_props._fullscreen) {
     if(!_props._fullscreen) {
         if(FAILED(hr = pScrn->pDD->SetCooperativeLevel(_hParentWindow, SCL_FPUFlag | DDSCL_NORMAL))) {
         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);
             exit(1);
         }
         }
         return; 
         return; 
@@ -1739,7 +1862,7 @@ SetCoopLevelsAndDisplayModes(void) {
        // all ddraw objs need to have same focus window
        // all ddraw objs need to have same focus window
        if(_windows.size()>1) {    
        if(_windows.size()>1) {    
            if(FAILED(hr = pScrn->pDD->SetCooperativeLevel(_hParentWindow, DDSCL_SETFOCUSWINDOW))) {
            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);
                exit(1);
            }
            }
        }
        }
@@ -1748,13 +1871,13 @@ SetCoopLevelsAndDisplayModes(void) {
        // so we do it, it really shouldnt be necessary if drivers werent buggy
        // so we do it, it really shouldnt be necessary if drivers werent buggy
        for(int jj=0;jj<2;jj++) {
        for(int jj=0;jj<2;jj++) {
            if(FAILED(hr = pScrn->pDD->SetCooperativeLevel(pScrn->hWnd, SCL_FLAGS))) {
            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);
                exit(1);
            }
            }
        }
        }
     
     
        if(FAILED(hr = pScrn->pDD->TestCooperativeLevel())) {
        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";
            wdxdisplay_cat.fatal() << "Full screen app failed to get exclusive mode on init, exiting..\n";
            exit(1);
            exit(1);
        }
        }
@@ -1763,7 +1886,7 @@ SetCoopLevelsAndDisplayModes(void) {
        // let driver choose default refresh rate (hopefully its >=60Hz)
        // let driver choose default refresh rate (hopefully its >=60Hz)
        if(FAILED( hr = pScrn->pDD->SetDisplayMode( pScrn->dwRenderWidth, pScrn->dwRenderHeight,
        if(FAILED( hr = pScrn->pDD->SetDisplayMode( pScrn->dwRenderWidth, pScrn->dwRenderHeight,
                                             pScrn->dwFullScreenBitDepth, 0, 0 ))) {
                                             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);
            exit(1);
        }
        }
     
     
@@ -1775,7 +1898,7 @@ SetCoopLevelsAndDisplayModes(void) {
          /*
          /*
          #ifdef _DEBUG
          #ifdef _DEBUG
           if(FAILED(hr = (*Disply).pDD->GetAvailableVidMem(&ddsGAVMCaps,&dwVidMemTotal,&dwVidMemFree))) {
           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);
               exit(1);
           }
           }
           wdxdisplay_cat.debug() << "after fullscreen switch: GetAvailableVidMem returns Total: " << dwVidMemTotal/1000000.0 << "  Free: " << dwVidMemFree/1000000.0 << endl;
           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); 
         hr = Display.pD3D8->GetAdapterDisplayMode(Display.CardIDNum, &dispmode); 
 
 
         if(FAILED(hr)) {
         if(FAILED(hr)) {
-            wdxdisplay_cat.fatal() << "GetAdapterDisplayMode failed result = " << D3DERRORSTRING(hr);
+            wdxdisplay_cat.fatal() << "GetAdapterDisplayMode failed" << D3DERRORSTRING(hr);
             exit(1);
             exit(1);
         }
         }
 
 
@@ -1962,7 +2085,7 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) {
                                  dwBehaviorFlags, pPresParams, &Display.pD3DDevice);
                                  dwBehaviorFlags, pPresParams, &Display.pD3DDevice);
 
 
         if(FAILED(hr)) {
         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);
             exit(1);
         }
         }
     }  // end create windowed buffers
     }  // end create windowed buffers
@@ -1991,7 +2114,7 @@ Fallback_to_16bpp_buffers:
 
 
             dx_force_16bpp_zbuffer=true;
             dx_force_16bpp_zbuffer=true;
             if(wdxdisplay_cat.info())
             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);
             CreateScreenBuffersAndDevice(Display);
             return;
             return;
     } else {
     } else {
@@ -2036,14 +2159,14 @@ void wdxGraphicsWindow::init_resized_window(void) {
 
 
     hr = pDisplay->pD3DDevice->ResourceManagerDiscardBytes(0);
     hr = pDisplay->pD3DDevice->ResourceManagerDiscardBytes(0);
     if(FAILED(hr)) {
     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
     // Create the viewport
     D3DVIEWPORT8 vp = {0,0,_props._xsize,_props._ysize,0.0f,1.0f};
     D3DVIEWPORT8 vp = {0,0,_props._xsize,_props._ysize,0.0f,1.0f};
     hr = pDisplay->pD3DDevice->SetViewport( &vp );
     hr = pDisplay->pD3DDevice->SetViewport( &vp );
     if(FAILED(hr)) {
     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);
         exit(1);
     }
     }
 
 
@@ -2536,20 +2659,6 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
         exit(1);
         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;
     _hMouseCursor = NULL;
     _bLoadedCustomCursor = false;
     _bLoadedCustomCursor = false;
 
 
@@ -2566,6 +2675,9 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
           }
           }
     }     
     }     
 
 
+    // Do all DX7 stuff first
+//  find_all_card_memavails();
+
     LPDIRECT3D8 pD3D8;
     LPDIRECT3D8 pD3D8;
 
 
     typedef LPDIRECT3D8 (WINAPI *Direct3DCreate8_ProcPtr)(UINT SDKVersion);
     typedef LPDIRECT3D8 (WINAPI *Direct3DCreate8_ProcPtr)(UINT SDKVersion);
@@ -2609,6 +2721,7 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
 
 
     for(UINT i=0;i<_numAdapters;i++) {
     for(UINT i=0;i<_numAdapters;i++) {
         D3DADAPTER_IDENTIFIER8 adapter_info;
         D3DADAPTER_IDENTIFIER8 adapter_info;
+        ZeroMemory(&adapter_info,sizeof(D3DADAPTER_IDENTIFIER8));
         hr = pD3D8->GetAdapterIdentifier(i,D3DENUM_NO_WHQL_LEVEL,&adapter_info);
         hr = pD3D8->GetAdapterIdentifier(i,D3DENUM_NO_WHQL_LEVEL,&adapter_info);
         if(FAILED(hr)) {
         if(FAILED(hr)) {
             wdxdisplay_cat.fatal() << "D3D GetAdapterID failed" << D3DERRORSTRING(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"
             << " SubsysID: 0x" << (void*) adapter_info.SubSysId << " Revision: 0x"
             << (void*) adapter_info.Revision << endl;
             << (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;
         DXDeviceInfo devinfo;
         ZeroMemory(&devinfo,sizeof(devinfo));
         ZeroMemory(&devinfo,sizeof(devinfo));
         memcpy(&devinfo.guidDeviceIdentifier,&adapter_info.DeviceIdentifier,sizeof(GUID));
         memcpy(&devinfo.guidDeviceIdentifier,&adapter_info.DeviceIdentifier,sizeof(GUID));
         strncpy(devinfo.szDescription,adapter_info.Description,MAX_DEVICE_IDENTIFIER_STRING);
         strncpy(devinfo.szDescription,adapter_info.Description,MAX_DEVICE_IDENTIFIER_STRING);
         strncpy(devinfo.szDriver,adapter_info.Driver,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;
         devinfo.cardID=i;
+
         _DeviceInfoVec.push_back(devinfo);
         _DeviceInfoVec.push_back(devinfo);
     }
     }
 
 
@@ -2666,6 +2788,17 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
 
 
     _DeviceInfoVec.clear();  // dont need this anymore
     _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, 
     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()
                       // but after we have all the monitor handles needed by CreateWindow()
 
 
@@ -2682,6 +2815,8 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) {
         _windows[i]->finish_window_setup();
         _windows[i]->finish_window_setup();
     }
     }
 
 
+    SAFE_DELETE(g_pCardIDVec);  // dont need this anymore
+
     for(UINT i=0;i<num_windows;i++) {
     for(UINT i=0;i<num_windows;i++) {
         _windows[i]->_dxgsg->SetDXReady(true);
         _windows[i]->_dxgsg->SetDXReady(true);
     }
     }
@@ -2728,12 +2863,6 @@ wdxGraphicsWindowGroup::~wdxGraphicsWindowGroup() {
     if(_bLoadedCustomCursor && (_hMouseCursor!=NULL))
     if(_bLoadedCustomCursor && (_hMouseCursor!=NULL))
       DestroyCursor(_hMouseCursor);
       DestroyCursor(_hMouseCursor);
 
 
-
-    if(_hDDrawDLL != NULL) {
-       FreeLibrary(_hDDrawDLL);
-       _hDDrawDLL = NULL;
-    }
-
     if(_hD3D8_DLL != NULL) {
     if(_hD3D8_DLL != NULL) {
        FreeLibrary(_hD3D8_DLL);
        FreeLibrary(_hD3D8_DLL);
        _hD3D8_DLL = NULL;
        _hD3D8_DLL = NULL;

+ 4 - 2
panda/src/wdxdisplay8/wdxGraphicsWindow8.h

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