From f9dc7178e8e79f41623eb5891865279bd2bf162a Mon Sep 17 00:00:00 2001 From: "Asad M. Zaman" Date: Wed, 17 Mar 2004 20:05:39 +0000 Subject: [PATCH] single gsg multiple window: fixed all known bugs --- panda/src/dxgsg8/dxGraphicsDevice8.cxx | 6 +- panda/src/dxgsg8/dxGraphicsDevice8.h | 4 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 61 +++++++++++++------ panda/src/dxgsg8/wdxGraphicsPipe8.cxx | 6 +- panda/src/dxgsg8/wdxGraphicsPipe8.h | 4 +- panda/src/dxgsg8/wdxGraphicsWindow8.cxx | 58 ++++++++++++++---- panda/src/dxgsg8/wdxGraphicsWindow8.h | 1 + 7 files changed, 100 insertions(+), 40 deletions(-) diff --git a/panda/src/dxgsg8/dxGraphicsDevice8.cxx b/panda/src/dxgsg8/dxGraphicsDevice8.cxx index ad7ec75f46..7c05af1880 100644 --- a/panda/src/dxgsg8/dxGraphicsDevice8.cxx +++ b/panda/src/dxgsg8/dxGraphicsDevice8.cxx @@ -29,9 +29,9 @@ DXGraphicsDevice8:: DXGraphicsDevice8(wdxGraphicsPipe8 *pipe) : GraphicsDevice(pipe) { - _pScrn = NULL; - _pD3DDevice = NULL; - _pSwapChain = NULL; + ZeroMemory(&_Scrn,sizeof(_Scrn)); + _pD3DDevice = NULL; + _pSwapChain = NULL; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg8/dxGraphicsDevice8.h b/panda/src/dxgsg8/dxGraphicsDevice8.h index 8003587a70..13d3d1b33a 100755 --- a/panda/src/dxgsg8/dxGraphicsDevice8.h +++ b/panda/src/dxgsg8/dxGraphicsDevice8.h @@ -38,8 +38,8 @@ public: DXGraphicsDevice8(wdxGraphicsPipe8 *pipe); ~DXGraphicsDevice8(); - DXScreenData *_pScrn; - LPDIRECT3DDEVICE8 _pD3DDevice; // same as pScrn->_pD3DDevice, cached for spd + DXScreenData _Scrn; + LPDIRECT3DDEVICE8 _pD3DDevice; // same as Scrn._pD3DDevice, cached for spd IDirect3DSwapChain8 *_pSwapChain; #if 0 diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index f6e204f1bf..63b5588660 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -997,11 +997,24 @@ prepare_display_region() { D3DVIEWPORT8 vp = { l, u, w, h, 0.0f, 1.0f }; HRESULT hr = _pD3DDevice->SetViewport( &vp ); if (FAILED(hr)) { + dxgsg8_cat.error() + << "pScrn_SwapChain = " << _pScrn->pSwapChain << " SwapChain = " << _pSwapChain << "\n"; dxgsg8_cat.error() << "SetViewport(" << l << ", " << u << ", " << w << ", " << h << ") failed" << D3DERRORSTRING(hr); - throw_event("panda3d-render-error"); - nassertv(false); +#if 0 + D3DVIEWPORT8 vp_old; + _pD3DDevice->GetViewport( &vp_old ); + dxgsg8_cat.error() + << "GetViewport(" << vp_old.X << ", " << vp_old.Y << ", " << vp_old.Width << ", " + << vp_old.Height << ") returned: Trying to set that vp---->\n"; + hr = _pD3DDevice->SetViewport( &vp_old ); +#endif + if (FAILED(hr)) { + dxgsg8_cat.error() << "Failed again\n"; + throw_event("panda3d-render-error"); + nassertv(false); + } } // Note: for DX9, also change scissor clipping state here } @@ -4522,6 +4535,7 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { // unsafe to do the D3D releases after exit() called, since DLL_PROCESS_DETACH // msg already delivered to d3d.dll and it's unloaded itself + wdxdisplay8_cat.debug() << "called dx_cleanup\n"; free_nondx_resources(); PRINT_REFCNT(dxgsg8,_pD3DDevice); @@ -4555,7 +4569,7 @@ set_context(DXScreenData *pNewContextData) { _pD3DDevice = _pScrn->pD3DDevice; //copy this one field for speed of deref _pSwapChain = _pScrn->pSwapChain; //copy this one field for speed of deref - // wdxdisplay8_cat.debug() << "SwapChain = "<< _pSwapChain << "\n"; + //wdxdisplay8_cat.debug() << "SwapChain = "<< _pSwapChain << "\n"; } void DXGraphicsStateGuardian8:: @@ -4569,13 +4583,15 @@ create_swap_chain(DXScreenData *pNewContextData) { hr = pNewContextData->pD3DDevice->CreateAdditionalSwapChain(&pNewContextData->PresParams, &pNewContextData->pSwapChain); if (FAILED(hr)) wdxdisplay8_cat.debug() << "Swapchain creation failed :"<pSwapChain->Release(); + HRESULT hr; + hr = pNewContextData->pSwapChain->Release(); + if (FAILED(hr)) + wdxdisplay8_cat.debug() << "Swapchain release failed:" << D3DERRORSTRING(hr) << "\n"; } bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { @@ -4808,42 +4824,53 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *pPresParams, DXScreenData **pScrn) { _pScrn->pD3D8->GetAdapterDisplayMode(_pScrn->CardIDNum, &_pScrn->DisplayMode); pPresParams->BackBufferFormat = _pScrn->DisplayMode.Format; } - // here we have to look at the device's frame buffer dimension - // if current window's dimension is bigger than device's frame buffer + // here we have to look at the _PresReset frame buffer dimension + // if current window's dimension is bigger than _PresReset // we have to reset the device before creating new swapchain. // inorder to reset properly, we need to release all swapchains - D3DSURFACE_DESC DeviceDesc; - LPDIRECT3DSURFACE8 pDeviceBack; - _pD3DDevice->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&pDeviceBack); - pDeviceBack->GetDesc(&DeviceDesc); - pDeviceBack->Release(); + if ( !(_pScrn->pSwapChain) - || (DeviceDesc.Width < pPresParams->BackBufferWidth) - || (DeviceDesc.Height < pPresParams->BackBufferHeight) ) { + || (_PresReset.BackBufferWidth < pPresParams->BackBufferWidth) + || (_PresReset.BackBufferHeight < pPresParams->BackBufferHeight) ) { + + wdxdisplay8_cat.debug() << "Swpachain = " << _pScrn->pSwapChain << " _PresReset = " + << _PresReset.BackBufferWidth << "x" << _PresReset.BackBufferHeight << "pPresParams = " + << pPresParams->BackBufferWidth << "x" << pPresParams->BackBufferHeight << "\n"; get_engine()->reset_all_windows(false);// reset old swapchain by releasing - _PresReset.BackBufferWidth = pPresParams->BackBufferWidth; - _PresReset.BackBufferHeight = pPresParams->BackBufferHeight; + _PresReset.BackBufferWidth = max(_PresReset.BackBufferWidth, pPresParams->BackBufferWidth); + _PresReset.BackBufferHeight = max(_PresReset.BackBufferHeight, pPresParams->BackBufferHeight); hr=_pD3DDevice->Reset(&_PresReset); if (FAILED(hr)) { return hr; } get_engine()->reset_all_windows(true);// reset with new swapchains by creating + + *pScrn = NULL; + if(pPresParams!=&_pScrn->PresParams) + memcpy(&_pScrn->PresParams,pPresParams,sizeof(D3DPRESENT_PARAMETERS)); + return hr; } + // release the old swapchain and create a new one if (_pScrn->pSwapChain) { _pScrn->pSwapChain->Release(); + wdxdisplay8_cat.debug() << "SwapChain " << _pScrn->pSwapChain << " is released\n"; _pScrn->pSwapChain = NULL; hr=_pD3DDevice->CreateAdditionalSwapChain(pPresParams,&_pScrn->pSwapChain); } if(SUCCEEDED(hr)) { if(pPresParams!=&_pScrn->PresParams) memcpy(&_pScrn->PresParams,pPresParams,sizeof(D3DPRESENT_PARAMETERS)); - if (pScrn) + if (pScrn) { *pScrn = _pScrn; + wdxdisplay8_cat.debug() << "_pScrn = " << _pScrn << ", _pScrn_device = " << _pScrn->pD3DDevice << "\n"; + } } + else + while(1); return hr; } diff --git a/panda/src/dxgsg8/wdxGraphicsPipe8.cxx b/panda/src/dxgsg8/wdxGraphicsPipe8.cxx index 7d8c2a80ac..8ac9d7aed9 100644 --- a/panda/src/dxgsg8/wdxGraphicsPipe8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsPipe8.cxx @@ -396,7 +396,7 @@ find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &TestDisplayMode, *pBestFmt = D3DFMT_UNKNOWN; HRESULT hr; - // nvidia likes zbuf depth to match rendertarget depth + // nvidia likes zbuf depth to match rendertarget depth bool bOnlySelect16bpp = (bForce16bpp || (IS_NVIDIA(Display.DXDeviceID) && IS_16BPP_DISPLAY_FORMAT(TestDisplayMode.Format))); @@ -760,8 +760,8 @@ search_for_valid_displaymode(DXScreenData &scrn, PT(GraphicsDevice) wdxGraphicsPipe8:: make_device(void *scrn) { PT(DXGraphicsDevice8) device = new DXGraphicsDevice8(this); - device->_pScrn = (DXScreenData*) scrn; - device->_pD3DDevice = device->_pScrn->pD3DDevice; + memcpy(&device->_Scrn, scrn, sizeof(device->_Scrn)); + device->_pD3DDevice = device->_Scrn.pD3DDevice; _device = device; wdxdisplay8_cat.error() << "walla: device" << device << "\n"; diff --git a/panda/src/dxgsg8/wdxGraphicsPipe8.h b/panda/src/dxgsg8/wdxGraphicsPipe8.h index b222a64b2c..2701c89418 100644 --- a/panda/src/dxgsg8/wdxGraphicsPipe8.h +++ b/panda/src/dxgsg8/wdxGraphicsPipe8.h @@ -54,7 +54,7 @@ public: bool find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &TestDisplayMode, D3DFORMAT *pBestFmt, bool bWantStencil, - bool bForce16bpp, bool bVerboseMode = false) const; + bool bForce16bpp, bool bVerboseMode = true) const; void search_for_valid_displaymode(DXScreenData &scrn, UINT RequestedX_Size, UINT RequestedY_Size, @@ -63,7 +63,7 @@ public: bool *pCouldntFindAnyValidZBuf, D3DFORMAT *pSuggestedPixFmt, bool bForce16bppZBuffer, - bool bVerboseMode = false); + bool bVerboseMode = true); bool special_check_fullscreen_resolution(DXScreenData &scrn, UINT x_size,UINT y_size); diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx index b7f71c12d2..94130c761f 100644 --- a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx @@ -108,7 +108,7 @@ make_current(void) { // reset() requires having a current context.) dxgsg->reset_if_new(); - // wdxdisplay8_cat.debug() << "this is " << this << "\n"; + //wdxdisplay8_cat.debug() << "this is " << _wcontext.pSwapChain << "\n"; } /* BUGBUG: need to reinstate these methods ASAP. they were incorrectly moved from the GraphicsWindow to the GSG @@ -414,6 +414,21 @@ support_overlay_window(bool flag) { } } +////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow::close_window +// Access: Public +// Description: Some cleanup is necessary for directx closeup of window. +// Handle close window events for this particular +// window. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow8:: +close_window() { + wdxdisplay8_cat.debug() << "wdx closed window\n"; + if (multiple_windows) + _dxgsg->release_swap_chain(&_wcontext); + WinGraphicsWindow::close_window(); +} + #if 1 ////////////////////////////////////////////////////////////////// // Function: WinGraphicsWindow::window_proc @@ -1520,16 +1535,17 @@ reset_device_resize_window(UINT new_xsize, UINT new_ysize) { DXScreenData *pScrn; D3DPRESENT_PARAMETERS d3dpp; memcpy(&d3dpp, &_wcontext.PresParams, sizeof(D3DPRESENT_PARAMETERS)); - d3dpp.BackBufferWidth = new_xsize; - d3dpp.BackBufferHeight = new_ysize; + _wcontext.PresParams.BackBufferWidth = new_xsize; + _wcontext.PresParams.BackBufferHeight = new_ysize; make_current(); - HRESULT hr = _dxgsg->reset_d3d_device(&d3dpp, &pScrn); - + HRESULT hr = _dxgsg->reset_d3d_device(&_wcontext.PresParams, &pScrn); + if (FAILED(hr)) { bRetval = false; wdxdisplay8_cat.error() << "reset_device_resize_window Reset() failed" << D3DERRORSTRING(hr); if (hr == D3DERR_OUTOFVIDEOMEMORY) { + memcpy(&_wcontext.PresParams, &d3dpp, sizeof(D3DPRESENT_PARAMETERS)); hr = _dxgsg->reset_d3d_device(&_wcontext.PresParams, &pScrn); if (FAILED(hr)) { wdxdisplay8_cat.error() @@ -1548,7 +1564,8 @@ reset_device_resize_window(UINT new_xsize, UINT new_ysize) { } } // before you init_resized_window you need to copy certain changes to _wcontext - _wcontext.pSwapChain = pScrn->pSwapChain; + if (pScrn) + _wcontext.pSwapChain = pScrn->pSwapChain; wdxdisplay8_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n"; init_resized_window(); return bRetval; @@ -1620,6 +1637,9 @@ init_resized_window() { assert(_wcontext.hWnd!=NULL); ClearToBlack(_wcontext.hWnd, get_properties()); + //wdxdisplay8_cat.debug() << "wcontext = " << &_wcontext << " and device = " << _wcontext.pD3DDevice << "\n"; + +#if 0 // clear textures and VB's out of video&AGP mem, so cache is reset hr = _wcontext.pD3DDevice->ResourceManagerDiscardBytes(0); if (FAILED(hr)) { @@ -1627,6 +1647,7 @@ init_resized_window() { << "ResourceManagerDiscardBytes failed for device #" << _wcontext.CardIDNum << D3DERRORSTRING(hr); } +#endif _dxgsg->set_context(&_wcontext); // Note: dx_init will fill in additional fields in _wcontext, like supportedtexfmts @@ -1749,6 +1770,11 @@ open_window(void) { // In that case just create an additional swapchain for this window if (dxgsg->get_pipe()->get_device() == NULL) { + + if (wdxdisplay8_cat.is_debug()) { + wdxdisplay8_cat.debug() << "device is null \n"; + } + create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer); dxgsg->get_pipe()->make_device((void*)(&_wcontext)); dxgsg->copy_pres_reset(&_wcontext); @@ -1760,23 +1786,29 @@ open_window(void) { } else { // fill in the DXScreenData from dxdevice here and change the // reference to hWnd. + if (wdxdisplay8_cat.is_debug()) { + wdxdisplay8_cat.debug() << "device is not null\n"; + } dxdev = (DXGraphicsDevice8*)dxgsg->get_pipe()->get_device(); props = get_properties(); - memcpy(&_wcontext,dxdev->_pScrn,sizeof(DXScreenData)); + wdxdisplay8_cat.debug() << "dxdev_pScrn = " << &dxdev->_Scrn << ", _pScrn_device = " << dxdev->_Scrn.pD3DDevice + << ", dxdev_device = " << dxdev->_pD3DDevice << "\n"; + wdxdisplay8_cat.debug() << "_wcontext = " << &_wcontext << ", device = " << _wcontext.pD3DDevice << "\n"; + + memcpy(&_wcontext,&dxdev->_Scrn,sizeof(DXScreenData)); _wcontext.hWnd = _hWnd; + // _wcontext.pD3DDevice = dxdev->_pD3DDevice; // copy the current device _wcontext.PresParams.hDeviceWindow = _hWnd; _wcontext.PresParams.BackBufferWidth = props.get_x_size(); _wcontext.PresParams.BackBufferHeight = props.get_y_size(); - wdxdisplay8_cat.debug()<<"device width "<<_wcontext.PresParams.BackBufferWidth<<"\n"; - + //wdxdisplay8_cat.debug()<<"device width "<<_wcontext.PresParams.BackBufferWidth<<"\n"; + //wdxdisplay8_cat.debug()<<"debug pSwapChain "<<_wcontext.pSwapChain<<"\n"; + dxgsg->create_swap_chain(&_wcontext); init_resized_window(); - if (wdxdisplay8_cat.is_debug()) { - wdxdisplay8_cat.debug() << "Current device is " << dxdev << "\n"; - } - dxgsg->create_swap_chain(&_wcontext); + //wdxdisplay8_cat.debug() << "Current device is " << dxdev << "\n"; } wdxdisplay8_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n"; return true; diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.h b/panda/src/dxgsg8/wdxGraphicsWindow8.h index 8f779425c9..c355e96153 100644 --- a/panda/src/dxgsg8/wdxGraphicsWindow8.h +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.h @@ -43,6 +43,7 @@ public: const string &name); virtual ~wdxGraphicsWindow8(); virtual bool open_window(void); + virtual void close_window(void); virtual void reset_window(bool swapchain); virtual int verify_window_sizes(int numsizes, int *dimen);