From daf3f0d00bc9eddf63c5c861dd49bc5c43abf410 Mon Sep 17 00:00:00 2001 From: "Asad M. Zaman" Date: Wed, 17 Mar 2004 21:04:44 +0000 Subject: [PATCH] single gsg multiple windows: dx9 support --- panda/src/dxgsg9/dxGraphicsDevice9.cxx | 6 +-- panda/src/dxgsg9/dxGraphicsDevice9.h | 2 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 32 ++++++++------ panda/src/dxgsg9/wdxGraphicsPipe9.cxx | 4 +- panda/src/dxgsg9/wdxGraphicsWindow9.cxx | 42 +++++++++++++------ panda/src/dxgsg9/wdxGraphicsWindow9.h | 1 + 6 files changed, 56 insertions(+), 31 deletions(-) diff --git a/panda/src/dxgsg9/dxGraphicsDevice9.cxx b/panda/src/dxgsg9/dxGraphicsDevice9.cxx index d1ed91a28e..4f741856be 100755 --- a/panda/src/dxgsg9/dxGraphicsDevice9.cxx +++ b/panda/src/dxgsg9/dxGraphicsDevice9.cxx @@ -29,9 +29,9 @@ DXGraphicsDevice9:: DXGraphicsDevice9(wdxGraphicsPipe9 *pipe) : GraphicsDevice(pipe) { - _pScrn = NULL; - _pD3DDevice = NULL; - _pSwapChain = NULL; + ZeroMemory(&_Scrn,sizeof(_Scrn)); + _pD3DDevice = NULL; + _pSwapChain = NULL; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg9/dxGraphicsDevice9.h b/panda/src/dxgsg9/dxGraphicsDevice9.h index 64abcadbee..cd3d260cea 100755 --- a/panda/src/dxgsg9/dxGraphicsDevice9.h +++ b/panda/src/dxgsg9/dxGraphicsDevice9.h @@ -38,7 +38,7 @@ public: DXGraphicsDevice9(wdxGraphicsPipe9 *pipe); ~DXGraphicsDevice9(); - DXScreenData *_pScrn; + DXScreenData _Scrn; LPDIRECT3DDEVICE9 _pD3DDevice; // same as pScrn->_pD3DDevice, cached for spd IDirect3DSwapChain9 *_pSwapChain; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 3a1bff479c..95d4d4fdaf 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -4782,6 +4782,7 @@ void DXGraphicsStateGuardian9::set_render_target() { _pD3DDevice->GetDepthStencilSurface(&pStencil); _pD3DDevice->SetDepthStencilSurface(pStencil); + _pD3DDevice->SetRenderTarget(0, pBack); if (pBack) pBack->Release(); if (pStencil) @@ -4823,40 +4824,47 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *pPresParams, DXScreenData **pScrn) { _pScrn->pD3D9->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; - LPDIRECT3DSURFACE9 pDeviceBack; - _pD3DDevice->GetBackBuffer(0, 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) ) { + + wdxdisplay9_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(); + wdxdisplay9_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; } return hr; diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index bca8c23ad4..2c9155bdbc 100755 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -779,8 +779,8 @@ make_device(void *scrn) { // FrameBufferProperties really belongs as part of the window/renderbuffer specification // put here because of GLX multithreading requirement PT(DXGraphicsDevice9) device = new DXGraphicsDevice9(this); - device->_pScrn = (DXScreenData*) scrn; - device->_pD3DDevice = device->_pScrn->pD3DDevice; + memcpy(&device->_Scrn, scrn, sizeof(device->_Scrn)); + device->_pD3DDevice = device->_Scrn.pD3DDevice; _device = device; wdxdisplay9_cat.error() << "walla: device" << device << "\n"; diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx index f290308f0c..e3776eb53f 100755 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx @@ -414,6 +414,20 @@ support_overlay_window(bool flag) { _dxgsg->support_overlay_window(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 wdxGraphicsWindow9:: +close_window() { + wdxdisplay9_cat.debug() << "wdx closed window\n"; + if (multiple_windows) + _dxgsg->release_swap_chain(&_wcontext); + WinGraphicsWindow::close_window(); +} #if 1 ////////////////////////////////////////////////////////////////// @@ -1531,16 +1545,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; wdxdisplay9_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)) { wdxdisplay9_cat.error() @@ -1559,7 +1574,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; wdxdisplay9_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n"; init_resized_window(); return bRetval; @@ -1635,7 +1651,7 @@ init_resized_window() { hr = _wcontext.pD3DDevice->EvictManagedResources(); if (FAILED(hr)) { wdxdisplay9_cat.error() - << "ResourceManagerDiscardBytes failed for device #" + << "EvictManagedResources failed for device #" << _wcontext.CardIDNum << D3DERRORSTRING(hr); } @@ -1760,6 +1776,8 @@ open_window(void) { // In that case just create an additional swapchain for this window if (dxgsg->get_pipe()->get_device() == NULL) { + wdxdisplay9_cat.debug() << "device is null \n"; + if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) return false; dxgsg->get_pipe()->make_device((void*)(&_wcontext)); @@ -1772,23 +1790,21 @@ open_window(void) { } else { // fill in the DXScreenData from dxdevice here and change the // reference to hWnd. + wdxdisplay9_cat.debug() << "device is not null\n"; + dxdev = (DXGraphicsDevice9*)dxgsg->get_pipe()->get_device(); props = get_properties(); - memcpy(&_wcontext,dxdev->_pScrn,sizeof(DXScreenData)); + memcpy(&_wcontext,&dxdev->_Scrn,sizeof(DXScreenData)); _wcontext.hWnd = _hWnd; _wcontext.PresParams.hDeviceWindow = _hWnd; _wcontext.PresParams.BackBufferWidth = props.get_x_size(); _wcontext.PresParams.BackBufferHeight = props.get_y_size(); - wdxdisplay9_cat.debug()<<"device width "<<_wcontext.PresParams.BackBufferWidth<<"\n"; - - init_resized_window(); - - if (wdxdisplay9_cat.is_debug()) { - wdxdisplay9_cat.debug() << "Current device is " << dxdev << "\n"; - } + //wdxdisplay9_cat.debug()<<"device width "<<_wcontext.PresParams.BackBufferWidth<<"\n"; + //wdxdisplay9_cat.debug()<<"debug pSwapChain "<<_wcontext.pSwapChain<<"\n"; dxgsg->create_swap_chain(&_wcontext); + init_resized_window(); } wdxdisplay9_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n"; return true; diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.h b/panda/src/dxgsg9/wdxGraphicsWindow9.h index 15c09e9fed..3143e2a656 100755 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.h +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.h @@ -43,6 +43,7 @@ public: const string &name); virtual ~wdxGraphicsWindow9(); 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);