mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
fix resizing on 8MB cards
This commit is contained in:
parent
0b2dc96d80
commit
b836bfd8d0
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;i<numsizes;i++,pCurDim+=2) {
|
||||
DWORD xsize=pCurDim[0];
|
||||
DWORD ysize=pCurDim[1];
|
||||
@ -1199,7 +1200,26 @@ verify_window_sizes(unsigned int numsizes,unsigned int *dimen) {
|
||||
|
||||
if(_bIsLowVidMemCard)
|
||||
bIsGoodMode=(((float)xsize*(float)ysize)<=(float)(640*480));
|
||||
else bIsGoodMode=((DMI.supportedBitDepths & (DDBD_16 | DDBD_24 | DDBD_32))!=0);
|
||||
else if(DMI.supportedBitDepths & (DDBD_16 | DDBD_24 | DDBD_32)) {
|
||||
// assume user is testing fullscreen, not windowed, so use the dwTotal value
|
||||
// see if 3 scrnbufs (front/back/z)at 16bpp at xsize*ysize will fit with a few
|
||||
// extra megs for texmem
|
||||
|
||||
// 8MB Rage Pro says it has 6.8 megs Total free and will run at 1024x768, so
|
||||
// formula makes it so that is OK
|
||||
|
||||
#define REQD_TEXMEM 1800000.0f
|
||||
|
||||
if(_MaxAvailVidMem==0) {
|
||||
//assume buggy drivers return bad val of 0 and everything will be OK
|
||||
bIsGoodMode=true;
|
||||
} else {
|
||||
bIsGoodMode = ((((float)xsize*(float)ysize)*6+REQD_TEXMEM) < (float)_MaxAvailVidMem);
|
||||
}
|
||||
}
|
||||
|
||||
wdxdisplay_cat.fatal() << "XXXXXXXXXXXXXXXXXXXXX: " << ((1024.0f*768.0f)*6+REQD_TEXMEM)
|
||||
<< " " << _MaxAvailVidMem << endl;
|
||||
|
||||
if(bIsGoodMode)
|
||||
num_valid_modes++;
|
||||
@ -1293,23 +1313,26 @@ dx_setup() {
|
||||
|
||||
// Check for DirectX 7 by looking for DirectDrawCreateEx
|
||||
|
||||
HINSTANCE DDHinst = LoadLibrary("ddraw.dll");
|
||||
if(DDHinst == 0) {
|
||||
_hDDraw_DLL = LoadLibrary("ddraw.dll");
|
||||
if(_hDDraw_DLL == 0) {
|
||||
wdxdisplay_cat.fatal() << "can't locate DDRAW.DLL!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Note: I dont want to mess with manually doing FreeLibrary(ddraw.dll) for now. The OS will clean
|
||||
// this up when the app exits, if we need to I'll add this later.
|
||||
|
||||
typedef HRESULT (WINAPI * LPDIRECTDRAWCREATEEX)(GUID FAR * lpGuid, LPVOID *lplpDD, REFIID iid,IUnknown FAR *pUnkOuter);
|
||||
|
||||
// load all ddraw exports dynamically to avoid static link to ddraw.dll, in case system doesnt have it
|
||||
|
||||
LPDIRECTDRAWCREATEEX pDDCreateEx = (LPDIRECTDRAWCREATEEX) GetProcAddress(DDHinst,"DirectDrawCreateEx");
|
||||
LPDIRECTDRAWCREATEEX pDDCreateEx = (LPDIRECTDRAWCREATEEX) GetProcAddress(_hDDraw_DLL,"DirectDrawCreateEx");
|
||||
if(pDDCreateEx == NULL) {
|
||||
wdxdisplay_cat.fatal() << "Panda currently requires at least DirectX 7.0!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LPDIRECTDRAWENUMERATEEX pDDEnumEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(DDHinst,"DirectDrawEnumerateEx");
|
||||
LPDIRECTDRAWENUMERATEEX pDDEnumEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(_hDDraw_DLL,"DirectDrawEnumerateExA");
|
||||
if(pDDEnumEx == NULL) {
|
||||
wdxdisplay_cat.fatal() << "GetProcAddr failed for DirectDrawEnumerateEx!\n";
|
||||
exit(1);
|
||||
@ -1339,8 +1362,6 @@ dx_setup() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
FreeLibrary(DDHinst); //undo LoadLib above, decrement ddraw.dll refcnt (after DDrawCreate, since dont want to unload/reload)
|
||||
|
||||
pDD->GetDeviceIdentifier(&_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() << " "<<dwFree <<" Available VidMem is under "<< LOWVIDMEMTHRESHOLD <<", using 640x480 16bpp rendertargets to save tex vidmem.\n";
|
||||
wdxdisplay_cat.debug() << " " << dwVidMemFree << " Available VidMem is under " << LOWVIDMEMTHRESHOLD <<", using 640x480 16bpp rendertargets to save tex vidmem.\n";
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -1489,25 +1514,20 @@ dx_setup() {
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
DWORD SCL_FLAGS = SCL_FPUFlag | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT;
|
||||
|
||||
if(FAILED(hr = pDD->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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user