diff --git a/panda/src/wdxdisplay/config_wdxdisplay.cxx b/panda/src/wdxdisplay/config_wdxdisplay.cxx index f2c67f159f..df0a115d1a 100644 --- a/panda/src/wdxdisplay/config_wdxdisplay.cxx +++ b/panda/src/wdxdisplay/config_wdxdisplay.cxx @@ -32,6 +32,7 @@ ConfigureFn(config_wdxdisplay) { int dx_use_multimon = config_wdxdisplay.GetInt("dx-multimon", 1); bool dx_force_16bpp_zbuffer = config_wdxdisplay.GetBool("dx-force-16bpp-zbuffer", false); bool bResponsive_minimized_fullscreen_window = config_wdxdisplay.GetBool("responsive-minimized-fullscreen-window",false); +bool dx_preserve_fpu_state = config_wdxdisplay.GetBool("dx-preserve-fpu-state", false); extern void AtExitFn(void); diff --git a/panda/src/wdxdisplay/config_wdxdisplay.h b/panda/src/wdxdisplay/config_wdxdisplay.h index ac160aa1ab..5f845d4d92 100644 --- a/panda/src/wdxdisplay/config_wdxdisplay.h +++ b/panda/src/wdxdisplay/config_wdxdisplay.h @@ -27,6 +27,7 @@ NotifyCategoryDecl(wdxdisplay, EXPCL_PANDADX, EXPTP_PANDADX); extern bool bResponsive_minimized_fullscreen_window; extern bool dx_force_16bpp_zbuffer; +extern bool dx_preserve_fpu_state; extern int dx_use_multimon; extern Filename get_icon_filename(); extern Filename get_mono_cursor_filename(); diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx index 78470c7ec5..3cc59099ce 100644 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx +++ b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx @@ -853,6 +853,7 @@ void wdxGraphicsWindow::config(void) { global_wdxwinptr = this; // for use during createwin() + _hDDraw_DLL = NULL; _hdc = NULL; _mwindow = NULL; _gsg = _dxgsg = NULL; @@ -861,6 +862,7 @@ void wdxGraphicsWindow::config(void) { _return_control_to_app = false; _active_minimized_fullscreen = false; _bIsLowVidMemCard = false; + _MaxAvailVidMem = 0; _hOldForegroundWindow=GetForegroundWindow(); @@ -1173,7 +1175,6 @@ verify_window_sizes(unsigned int numsizes,unsigned int *dimen) { DisplayModeInfo DMI; DWORD i,*pCurDim=(DWORD *)dimen; - for(i=0;iGetDeviceIdentifier(&_DXDeviceID,0x0); #ifdef _DEBUG @@ -1386,6 +1407,24 @@ dx_setup() { DWORD dwRenderWidth=0, dwRenderHeight=0; + // 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=0,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 : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + // 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 + _MaxAvailVidMem = dwVidMemTotal; + if(dx_full_screen) { dwRenderWidth = _props._xsize; dwRenderHeight = _props._ysize; @@ -1410,29 +1449,15 @@ dx_setup() { exit(1); } + #ifdef _DEBUG + wdxdisplay_cat.debug() << "before fullscreen switch: GetAvailableVidMem returns Total: " << dwVidMemTotal/1000000.0 << " Free: " << dwVidMemFree/1000000.0 << endl; + #endif + DWORD dwFullScreenBitDepth; // Now we try to figure out if we can use requested screen resolution and best // rendertarget bpp and still have at least 2 meg of texture vidmem - // 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 ddsCaps; - DWORD dwTotal,dwFree; - ZeroMemory(&ddsCaps,sizeof(DDSCAPS2)); - ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; //set internally by DX anyway, dont think this any different than 0x0 - - if(FAILED( hr = pDD->GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) { - wdxdisplay_cat.error() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - #ifdef _DEBUG - wdxdisplay_cat.debug() << "before FullScreen switch: GetAvailableVidMem returns Total: " << dwTotal/1000000.0 << " Free: " << dwFree/1000000.0 << endl; - #endif - DMI.supportedBitDepths &= pD3DDevDesc->dwDeviceRenderBitDepth; // note: this chooses 32bpp, which may not be preferred over 16 for memory & speed reasons @@ -1448,19 +1473,19 @@ dx_setup() { exit(1); } - if(dwFree>0) { // assume buggy drivers (this means you, FireGL2) may return zero for dwTotal, so ignore value if its 0 + if(dwVidMemFree>0) { // assume buggy drivers (this means you, FireGL2) may return zero for dwTotal, so ignore value if its 0 // hack: figuring out exactly what res to use is tricky, instead I will // just use 640x480 if we have < 3 meg avail #define LOWVIDMEMTHRESHOLD 3500000 - if(dwFree< LOWVIDMEMTHRESHOLD) { + if(dwVidMemFree< LOWVIDMEMTHRESHOLD) { // we're going to need 800x600 or 640x480 at 16 bit to save enough tex vidmem dwFullScreenBitDepth=16; // do 16bpp dwRenderWidth=640; dwRenderHeight=480; _bIsLowVidMemCard = true; - wdxdisplay_cat.debug() << " "<SetCooperativeLevel(_mwindow, SCL_FLAGS))) { - wdxdisplay_cat.fatal() << "SetCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - // s3 savage2000 on w95 seems to set EXCLUSIVE_MODE only if you call SetCoopLevel twice. // so we do it, it really shouldnt be necessary if drivers werent buggy - if(FAILED(hr = pDD->SetCooperativeLevel(_mwindow, SCL_FLAGS))) { - wdxdisplay_cat.fatal() - << "SetCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); + for(int jj=0;jj<2;jj++) { + if(FAILED(hr = pDD->SetCooperativeLevel(_mwindow, SCL_FLAGS))) { + wdxdisplay_cat.fatal() << "SetCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } } if(FAILED(hr = pDD->TestCooperativeLevel())) { @@ -1529,11 +1549,11 @@ dx_setup() { wdxdisplay_cat.debug() << "set displaymode to " << ddsd34.dwWidth << "x" << ddsd34.dwHeight << " at "<< ddsd34.ddpfPixelFormat.dwRGBBitCount << "bpp, " << ddsd34.dwRefreshRate<< "Hz\n"; #ifdef _DEBUG - if(FAILED( hr = pDD->GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) { + if(FAILED(hr = pDD->GetAvailableVidMem(&ddsGAVMCaps,&dwVidMemTotal,&dwVidMemFree))) { wdxdisplay_cat.debug() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } - wdxdisplay_cat.debug() << "after FullScreen switch: GetAvailableVidMem returns Total: " << dwTotal/1000000.0 << " Free: " << dwFree/1000000.0 << endl; + wdxdisplay_cat.debug() << "before fullscreen switch: GetAvailableVidMem returns Total: " << dwVidMemTotal/1000000.0 << " Free: " << dwVidMemFree/1000000.0 << endl; #endif } } @@ -1661,11 +1681,10 @@ CreateScreenBuffersAndDevice(DWORD dwRenderWidth, DWORD dwRenderHeight,LPDIRECTD exit(1); } -// extern bool dx_preserve_fpu_state; - DWORD SCL_FPUFlag = DDSCL_FPUSETUP; - -// if(dx_preserve_fpu_state) -// SCL_FPUFlag = DDSCL_FPUPRESERVE; // tell d3d to preserve the fpu state across calls. this hurts perf, but is good for dbgging + DWORD SCL_FPUFlag; + if(dx_preserve_fpu_state) + SCL_FPUFlag = DDSCL_FPUPRESERVE; // tell d3d to preserve the fpu state across calls. this hurts perf, but is good for dbgging + else SCL_FPUFlag = DDSCL_FPUSETUP; if(FAILED(hr = pDD->SetCooperativeLevel(_mwindow, SCL_FPUFlag | DDSCL_NORMAL))) { wdxdisplay_cat.fatal() << "SetCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; @@ -2351,11 +2370,15 @@ static int iMouseTrails; static bool bCursorShadowOn,bMouseVanish; #ifndef SPI_GETMOUSEVANISH -// get of this when we upgrade to winxp winuser.h +// get rid of this when we upgrade to winxp winuser.h in newest platform sdk #define SPI_GETMOUSEVANISH 0x1020 #define SPI_SETMOUSEVANISH 0x1021 #endif +#ifndef SPI_GETCURSORSHADOW +#error You have old windows headers, need to get latest MS Platform SDK +#endif + void set_global_parameters(void) { // turn off mousetrails and cursor shadow and mouse cursor vanish // cursor shadow causes cursor blink and reduced frame rate due to lack of driver support for diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.h b/panda/src/wdxdisplay/wdxGraphicsWindow.h index 60dded0a56..a8275ff2ae 100644 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.h +++ b/panda/src/wdxdisplay/wdxGraphicsWindow.h @@ -109,6 +109,7 @@ private: typedef enum { NotAdjusting,MovingOrResizing,Resizing } WindowAdjustType; WindowAdjustType _WindowAdjustingType; bool _bIsLowVidMemCard; + DWORD _MaxAvailVidMem; bool _bLoadedCustomCursor; HCURSOR _hMouseCursor; bool _bSizeIsMaximized; @@ -121,6 +122,7 @@ private: bool _active_minimized_fullscreen; bool _return_control_to_app; int _depth_buffer_bpp; + HINSTANCE _hDDraw_DLL; public: static TypeHandle get_class_type(void);