diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index 3c917691d2..effad09c8f 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -64,12 +64,6 @@ const string threading_model = config_display.GetString("threading-model", ""); // until an explicit call to flip_frame() or the next render_frame(). const bool auto_flip = config_display.GetBool("auto-flip", true); -// This indicates if you want multiple window support for same GSG -const bool multiple_windows = config_display.GetBool("multiple-windows", false); - -// This indicates if you want window_and_fullscreen support for same GSG -const bool window_and_fullscreen = config_display.GetBool("window-and-fullscreen", false); - // Set this true to yield the timeslice at the end of the frame to be // more polite to other applications that are trying to run. const bool yield_timeslice = config_display.GetBool("yield-timeslice", false); diff --git a/panda/src/display/config_display.h b/panda/src/display/config_display.h index 7cbdf0fa21..9255834845 100644 --- a/panda/src/display/config_display.h +++ b/panda/src/display/config_display.h @@ -45,10 +45,6 @@ extern const bool show_buffers; extern const bool prefer_parasite_buffer; extern const bool prefer_single_buffer; -extern EXPCL_PANDA const bool multiple_windows; - -extern EXPCL_PANDA const bool window_and_fullscreen; - extern EXPCL_PANDA void init_libdisplay(); #endif /* CONFIG_DISPLAY_H */ diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 573ef9b237..6a8d9de151 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -965,7 +965,14 @@ do_clear(const RenderBuffer &buffer) { _depth_clear_value, (DWORD)_stencil_clear_value); if(FAILED(hr)) { dxgsg8_cat.error() << "clear_buffer failed: Clear returned " << D3DERRORSTRING(hr); - throw_event("panda3d-render-error"); + // before throwing the event, lets try a 0 flag + dxgsg8_cat.error() << "trying with no flag\n"; + hr = _pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, _d3dcolor_clear_value, + _depth_clear_value, (DWORD)_stencil_clear_value); + if (FAILED(hr)) { + dxgsg8_cat.error() << "clear_buffer failed again: Clear returned " << D3DERRORSTRING(hr); + // throw_event("panda3d-render-error"); + } } /* The following line will cause the background to always clear to a medium red _color_clear_value[0] = .5; @@ -1001,7 +1008,7 @@ prepare_display_region() { dxgsg8_cat.error() << "SetViewport(" << l << ", " << u << ", " << w << ", " << h << ") failed" << D3DERRORSTRING(hr); -#if 0 +#if 1 D3DVIEWPORT8 vp_old; _pD3DDevice->GetViewport( &vp_old ); dxgsg8_cat.error() @@ -4541,7 +4548,7 @@ set_context(DXScreenData *pNewContextData) { //wdxdisplay8_cat.debug() << "SwapChain = "<< _pSwapChain << "\n"; } -void DXGraphicsStateGuardian8:: +bool DXGraphicsStateGuardian8:: create_swap_chain(DXScreenData *pNewContextData) { // Instead of creating a device and rendering as d3ddevice->present() // we should render using SwapChain->present(). This is done to support @@ -4550,17 +4557,25 @@ create_swap_chain(DXScreenData *pNewContextData) { HRESULT hr; hr = pNewContextData->pD3DDevice->CreateAdditionalSwapChain(&pNewContextData->PresParams, &pNewContextData->pSwapChain); - if (FAILED(hr)) + if (FAILED(hr)) { wdxdisplay8_cat.debug() << "Swapchain creation failed :"<pSwapChain->Release(); - if (FAILED(hr)) - wdxdisplay8_cat.debug() << "Swapchain release failed:" << D3DERRORSTRING(hr) << "\n"; + if (pNewContextData->pSwapChain) { + hr = pNewContextData->pSwapChain->Release(); + if (FAILED(hr)) { + wdxdisplay8_cat.debug() << "Swapchain release failed:" << D3DERRORSTRING(hr) << "\n"; + return false; + } + } + return true; } bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 8c1fbbb867..887e15a613 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -362,8 +362,8 @@ public: void support_overlay_window(bool flag); - void create_swap_chain (DXScreenData *pNewContextData); - void release_swap_chain (DXScreenData *pNewContextData); + bool create_swap_chain (DXScreenData *pNewContextData); + bool release_swap_chain (DXScreenData *pNewContextData); void copy_pres_reset(DXScreenData *pNewContextData); private: diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx index 1f5288f451..8505d5eb43 100644 --- a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx @@ -424,8 +424,7 @@ support_overlay_window(bool flag) { void wdxGraphicsWindow8:: close_window() { wdxdisplay8_cat.debug() << "wdx closed window\n"; - if (multiple_windows) - _dxgsg->release_swap_chain(&_wcontext); + _dxgsg->release_swap_chain(&_wcontext); WinGraphicsWindow::close_window(); } @@ -674,6 +673,8 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer RECT view_rect; HRESULT hr; + wdxdisplay8_cat.debug()<<"Display Width "<< dwRenderWidth<<" and PresParam Width "<<_wcontext.PresParams.BackBufferWidth<<"\n"; + // BUGBUG: need to change panda to put frame buffer properties with GraphicsWindow, not GSG!! int frame_buffer_mode = _gsg->get_properties().get_frame_buffer_mode(); bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0); @@ -842,7 +843,7 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; } - // assert((dwRenderWidth==pPresParams->BackBufferWidth)&&(dwRenderHeight==pPresParams->BackBufferHeight)); + //assert((dwRenderWidth==pPresParams->BackBufferWidth)&&(dwRenderHeight==pPresParams->BackBufferHeight)); hr = pD3D8->CreateDevice(Display.CardIDNum, D3DDEVTYPE_HAL, _hWnd, dwBehaviorFlags, pPresParams, &Display.pD3DDevice); @@ -1755,15 +1756,11 @@ open_window(void) { DXGraphicsStateGuardian8 *dxgsg; DCAST_INTO_R(dxgsg,_gsg,false); WindowProperties props; + bool discard_device = false; if(!choose_device()) { return false; } - if (dxgsg->get_pipe()->get_device() && !multiple_windows && !window_and_fullscreen) { - wdxdisplay8_cat.error() - << "Could not create window; multiple window support not enabled.\n"; - return false; - } wdxdisplay8_cat.debug() << "_wcontext.hWnd is " << _wcontext.hWnd << "\n"; if (!WinGraphicsWindow::open_window()) { @@ -1777,36 +1774,44 @@ open_window(void) { // call may be an extension to create multiple windows on same device // In that case just create an additional swapchain for this window - if (dxgsg->get_pipe()->get_device() == NULL || window_and_fullscreen) { - wdxdisplay8_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)); - dxgsg->copy_pres_reset(&_wcontext); - if (multiple_windows) { - // then we have no choice but to waste a framebuffer + while(1) { + if (dxgsg->get_pipe()->get_device() == NULL || discard_device) { + wdxdisplay8_cat.debug() << "device is null or fullscreen\n"; + + wdxdisplay8_cat.debug()<<"device width "<<_wcontext.DisplayMode.Width<<"\n"; + if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) { + // just crash here + wdxdisplay8_cat.error() << "fatal: must be trying to create two fullscreen windows: not supported\n"; + exit(1); //return false; + } + dxgsg->get_pipe()->make_device((void*)(&_wcontext)); + dxgsg->copy_pres_reset(&_wcontext); dxgsg->create_swap_chain(&_wcontext); + break; + + } else { + // fill in the DXScreenData from dxdevice here and change the + // reference to hWnd. + wdxdisplay8_cat.debug() << "device is not null\n"; + + dxdev = (DXGraphicsDevice8*)dxgsg->get_pipe()->get_device(); + props = get_properties(); + memcpy(&_wcontext,&dxdev->_Scrn,sizeof(DXScreenData)); + + _wcontext.PresParams.Windowed = !is_fullscreen(); + _wcontext.PresParams.hDeviceWindow = _wcontext.hWnd = _hWnd; + _wcontext.PresParams.BackBufferWidth = _wcontext.DisplayMode.Width = props.get_x_size(); + _wcontext.PresParams.BackBufferHeight = _wcontext.DisplayMode.Height = props.get_y_size(); + + wdxdisplay8_cat.debug()<<"device width "<<_wcontext.PresParams.BackBufferWidth<<"\n"; + //wdxdisplay8_cat.debug()<<"debug pSwapChain "<<_wcontext.pSwapChain<<"\n"; + if (!dxgsg->create_swap_chain(&_wcontext)) { + discard_device = true; + continue; // try again + } + init_resized_window(); + break; } - - } else { - // fill in the DXScreenData from dxdevice here and change the - // reference to hWnd. - wdxdisplay8_cat.debug() << "device is not null\n"; - - dxdev = (DXGraphicsDevice8*)dxgsg->get_pipe()->get_device(); - props = get_properties(); - - 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(); - - //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(); } wdxdisplay8_cat.debug() << "swapchain is " << _wcontext.pSwapChain << "\n"; return true; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 03d14e23dd..03980da973 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -4541,35 +4541,45 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { void DXGraphicsStateGuardian9:: set_context(DXScreenData *pNewContextData) { - // dont do copy from window since dx_init sets fields too. - // simpler to keep all of it in one place, so use ptr to window struct - - assert(pNewContextData!=NULL); - _pScrn = pNewContextData; - _pD3DDevice = _pScrn->pD3DDevice; //copy this one field for speed of deref - _pSwapChain = _pScrn->pSwapChain; //copy this one field for speed of deref - - //wdxdisplay9_cat.debug() << "SwapChain = "<< _pSwapChain << "\n"; + // dont do copy from window since dx_init sets fields too. + // simpler to keep all of it in one place, so use ptr to window struct + + assert(pNewContextData!=NULL); + _pScrn = pNewContextData; + _pD3DDevice = _pScrn->pD3DDevice; //copy this one field for speed of deref + _pSwapChain = _pScrn->pSwapChain; //copy this one field for speed of deref + + //wdxdisplay9_cat.debug() << "SwapChain = "<< _pSwapChain << "\n"; } -void DXGraphicsStateGuardian9:: +bool DXGraphicsStateGuardian9:: create_swap_chain(DXScreenData *pNewContextData) { - // Instead of creating a device and rendering as d3ddevice->present() - // we should render using SwapChain->present(). This is done to support - // multiple windows rendering. For that purpose, we need to set additional - // swap chains here. - - HRESULT hr; - hr = pNewContextData->pD3DDevice->CreateAdditionalSwapChain(&pNewContextData->PresParams, &pNewContextData->pSwapChain); - if (FAILED(hr)) - wdxdisplay9_cat.debug() << "Swapchain creation failed :"<present() + // we should render using SwapChain->present(). This is done to support + // multiple windows rendering. For that purpose, we need to set additional + // swap chains here. + + HRESULT hr; + hr = pNewContextData->pD3DDevice->CreateAdditionalSwapChain(&pNewContextData->PresParams, &pNewContextData->pSwapChain); + if (FAILED(hr)) { + wdxdisplay9_cat.debug() << "Swapchain creation failed :"<pSwapChain->Release(); + // Release the swap chain on this DXScreenData + HRESULT hr; + if (pNewContextData->pSwapChain) { + hr = pNewContextData->pSwapChain->Release(); + if (FAILED(hr)) { + wdxdisplay9_cat.debug() << "Swapchain release failed:" << D3DERRORSTRING(hr) << "\n"; + return false; + } + } + return true; } bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index c35d9dc13c..6fab36a189 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -365,8 +365,8 @@ public: void support_overlay_window(bool flag); - void create_swap_chain (DXScreenData *pNewContextData); - void release_swap_chain (DXScreenData *pNewContextData); + bool create_swap_chain (DXScreenData *pNewContextData); + bool release_swap_chain (DXScreenData *pNewContextData); void copy_pres_reset(DXScreenData *pNewContextData); private: diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx index 6a77cfb6d2..a0c6840521 100755 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx @@ -424,8 +424,7 @@ support_overlay_window(bool flag) { void wdxGraphicsWindow9:: close_window() { wdxdisplay9_cat.debug() << "wdx closed window\n"; - if (multiple_windows) - _dxgsg->release_swap_chain(&_wcontext); + _dxgsg->release_swap_chain(&_wcontext); WinGraphicsWindow::close_window(); } @@ -1753,15 +1752,11 @@ open_window(void) { DXGraphicsStateGuardian9 *dxgsg; DCAST_INTO_R(dxgsg,_gsg,false); WindowProperties props; + bool discard_device = false; if(!choose_device()) { return false; } - if (dxgsg->get_pipe()->get_device() && !multiple_windows && !window_and_fullscreen) { - wdxdisplay9_cat.error() - << "Could not create window; multiple window support not enabled.\n"; - return false; - } wdxdisplay9_cat.debug() << "_wcontext.hWnd is " << _wcontext.hWnd << "\n"; if (!WinGraphicsWindow::open_window()) { @@ -1775,36 +1770,44 @@ open_window(void) { // call may be an extension to create multiple windows on same device // In that case just create an additional swapchain for this window - if (dxgsg->get_pipe()->get_device() == NULL || window_and_fullscreen) { - wdxdisplay9_cat.debug() << "device is null \n"; + while(1) { + if (dxgsg->get_pipe()->get_device() == NULL || discard_device) { + wdxdisplay9_cat.debug() << "device is null or fullscreen\n"; - if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) - return false; - dxgsg->get_pipe()->make_device((void*)(&_wcontext)); - dxgsg->copy_pres_reset(&_wcontext); - if (multiple_windows) { - // then we have no choice but to waste a framebuffer + wdxdisplay9_cat.debug()<<"device width "<<_wcontext.DisplayMode.Width<<"\n"; + if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) { + // just crash here + wdxdisplay9_cat.error() << "fatal: must be trying to create two fullscreen windows: not supported\n"; + exit(1);//return false; + } + dxgsg->get_pipe()->make_device((void*)(&_wcontext)); + dxgsg->copy_pres_reset(&_wcontext); dxgsg->create_swap_chain(&_wcontext); + break; + + } 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->_Scrn,sizeof(DXScreenData)); + + _wcontext.PresParams.Windowed = !is_fullscreen(); + _wcontext.PresParams.hDeviceWindow = _wcontext.hWnd = _hWnd; + _wcontext.PresParams.BackBufferWidth = _wcontext.DisplayMode.Width = props.get_x_size(); + _wcontext.PresParams.BackBufferHeight = _wcontext.DisplayMode.Height = props.get_y_size(); + + wdxdisplay9_cat.debug()<<"device width "<<_wcontext.PresParams.BackBufferWidth<<"\n"; + //wdxdisplay9_cat.debug()<<"debug pSwapChain "<<_wcontext.pSwapChain<<"\n"; + if (!dxgsg->create_swap_chain(&_wcontext)) { + discard_device = true; + continue; //try again + } + init_resized_window(); + break; } - - } 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->_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"; - //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;