diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index bab25ce2df..4af15cf8fb 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -625,6 +625,7 @@ clear(DrawableRegion *clearable) { << "Unable to clear stencil buffer; removing.\n"; // This is really hacky code. ((FrameBufferProperties *)_current_properties)->set_stencil_bits(0); + _supports_stencil = false; } } } @@ -742,7 +743,17 @@ prepare_lens() { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: begin_frame(Thread *current_thread) { - return GraphicsStateGuardian::begin_frame(current_thread); + if (!GraphicsStateGuardian::begin_frame(current_thread)) { + return false; + } + + if (_d3d_device == NULL) { + dxgsg8_cat.debug() + << this << "::begin_frame(): no device.\n"; + return false; + } + + return true; } //////////////////////////////////////////////////////////////////// @@ -1793,8 +1804,11 @@ reset() { // TransformState::make_identity()); // want gsg to pass all state settings down so any non-matching defaults we set here get overwritten - assert(_screen->_d3d8 != NULL); - assert(_d3d_device != NULL); + if (_d3d_device == NULL) { + return; + } + + nassertv(_screen->_d3d8 != NULL); D3DCAPS8 d3d_caps; _d3d_device->GetDeviceCaps(&d3d_caps); @@ -1830,7 +1844,30 @@ reset() { if (support_stencil) { int min_stencil = D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR; if ((d3d_caps.StencilCaps & min_stencil) == min_stencil) { - _supports_stencil = true; + if (dxgsg8_cat.is_debug()) { + dxgsg8_cat.debug() + << "Checking for stencil; mode = " + << D3DFormatStr(_screen->_presentation_params.AutoDepthStencilFormat) + << "\n"; + } + switch (_screen->_presentation_params.AutoDepthStencilFormat) { + // These are the only formats that support stencil. + case D3DFMT_D15S1: + case D3DFMT_D24S8: + case D3DFMT_D24X4S4: + _supports_stencil = true; + if (dxgsg8_cat.is_debug()) { + dxgsg8_cat.debug() + << "Stencils supported.\n"; + } + break; + + default: + if (dxgsg8_cat.is_debug()) { + dxgsg8_cat.debug() + << "Stencils NOT supported.\n"; + } + } } } @@ -1972,7 +2009,7 @@ reset() { } else { // every card is going to have vertex fog, since it's implemented // in d3d runtime. - assert((_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0); + nassertv((_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0); // vertex fog may look crappy if you have large polygons in the // foreground and they get clipped, so you may want to disable it @@ -3474,6 +3511,10 @@ set_context(DXScreenData *new_context) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: set_render_target() { + if (_d3d_device == NULL) { + return; + } + LPDIRECT3DSURFACE8 back = NULL, stencil = NULL; if (!_swap_chain) //maybe fullscreen mode or main/single window @@ -3699,9 +3740,9 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params, DXScreenData **screen) { HRESULT hr; - assert(IS_VALID_PTR(presentation_params)); - assert(IS_VALID_PTR(_screen->_d3d8)); - assert(IS_VALID_PTR(_d3d_device)); + nassertr(IS_VALID_PTR(presentation_params), E_FAIL); + nassertr(IS_VALID_PTR(_screen->_d3d8), E_FAIL); + nassertr(IS_VALID_PTR(_d3d_device), E_FAIL); // for windowed mode make sure our format matches the desktop fmt, // in case the desktop mode has been changed @@ -3816,10 +3857,13 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params, bool DXGraphicsStateGuardian8:: check_cooperative_level() { bool bDoReactivateWindow = false; + if (_d3d_device == NULL) { + return false; + } HRESULT hr = _d3d_device->TestCooperativeLevel(); if (SUCCEEDED(hr)) { - assert(SUCCEEDED(_last_testcooplevel_result)); + nassertr(SUCCEEDED(_last_testcooplevel_result), false); return true; } diff --git a/panda/src/dxgsg8/dxInput8.cxx b/panda/src/dxgsg8/dxInput8.cxx index 29b494c9c1..cd583ed5cb 100644 --- a/panda/src/dxgsg8/dxInput8.cxx +++ b/panda/src/dxgsg8/dxInput8.cxx @@ -126,7 +126,7 @@ bool DInput8Info::CreateJoystickOrPad(HWND _window) { goto handle_error; } - assert(pJoyDevice!=NULL); + nassertr(pJoyDevice!=NULL, false); _DeviceList.push_back(pJoyDevice); // Set the data format to "simple joystick" - a predefined data format @@ -143,7 +143,7 @@ bool DInput8Info::CreateJoystickOrPad(HWND _window) { // must be called AFTER SetDataFormat to get all the proper flags DX_DECLARE_CLEAN(DIDEVCAPS, DIDevCaps); hr = pJoyDevice->GetCapabilities(&DIDevCaps); - assert(SUCCEEDED(hr)); + nassertr(SUCCEEDED(hr), false); _DevCaps.push_back(DIDevCaps); @@ -214,7 +214,7 @@ BOOL CALLBACK EnumObjectsCallbackJoystick( const DIDEVICEOBJECTINSTANCE* pdidoi, bool DInput8Info::ReadJoystick(int devnum, DIJOYSTATE2 &js) { LPDIRECTINPUTDEVICE8 pJoystick = _DeviceList[devnum]; - assert(pJoystick!=NULL); + nassertr(pJoystick!=NULL, false); HRESULT hr; char *errstr; diff --git a/panda/src/dxgsg8/wdxGraphicsPipe8.cxx b/panda/src/dxgsg8/wdxGraphicsPipe8.cxx index 782f37e365..57e5f3710d 100644 --- a/panda/src/dxgsg8/wdxGraphicsPipe8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsPipe8.cxx @@ -263,7 +263,7 @@ find_all_card_memavails() { ZeroMemory(&ZeroGUID, sizeof(GUID)); if (_card_ids.size() > 1) { - assert(IsEqualGUID(ZeroGUID, _card_ids[0].DX7_DeviceGUID)); + nassertr(IsEqualGUID(ZeroGUID, _card_ids[0].DX7_DeviceGUID), false); // delete enum of primary display (always the first), since it is // duplicated by explicit entry _card_ids.erase(_card_ids.begin()); @@ -439,10 +439,18 @@ bool wdxGraphicsPipe8:: find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode, D3DFORMAT *pBestFmt, bool bWantStencil, bool bForce16bpp, bool bVerboseMode) const { - // list fmts in order of preference -#define NUM_TEST_ZFMTS 3 - static D3DFORMAT NoStencilPrefList[NUM_TEST_ZFMTS] = {D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16}; - static D3DFORMAT StencilPrefList[NUM_TEST_ZFMTS] = {D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D15S1}; + if (dxgsg8_cat.is_debug()) { + bVerboseMode = true; + } + + // list formats to try in order of preference. + +#define NUM_TEST_ZFMTS 6 +#define FIRST_NON_STENCIL_ZFMT 3 + static D3DFORMAT FormatPrefList[NUM_TEST_ZFMTS] = { + D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D15S1, // with stencil + D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16 // without stencil + }; // do not use Display._display_mode since that is probably not set yet, use Test_display_mode instead @@ -458,9 +466,9 @@ find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode, << "FindBestDepthFmt: bSelectOnly16bpp: " << bOnlySelect16bpp << endl; } - for (int i = 0; i < NUM_TEST_ZFMTS; i++) { - D3DFORMAT TestDepthFmt = - (bWantStencil ? StencilPrefList[i] : NoStencilPrefList[i]); + int first_format = (bWantStencil ? 0 : FIRST_NON_STENCIL_ZFMT); + for (int i = first_format; i < NUM_TEST_ZFMTS; i++) { + D3DFORMAT TestDepthFmt = FormatPrefList[i]; if (bOnlySelect16bpp && !IS_16BPP_ZBUFFER(TestDepthFmt)) { continue; @@ -508,7 +516,6 @@ find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode, << "unexpected CheckDepthStencilMatch failure for " << D3DFormatStr(Test_display_mode.Format) << ", " << D3DFormatStr(TestDepthFmt) << endl; - exit(1); } } } @@ -566,7 +573,7 @@ search_for_valid_displaymode(DXScreenData &scrn, bool bForce16bppZBuffer, bool bVerboseMode) { - assert(IS_VALID_PTR(scrn._d3d8)); + nassertv(IS_VALID_PTR(scrn._d3d8)); HRESULT hr; *pSuggestedPixFmt = D3DFMT_UNKNOWN; diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx index d5f24faba8..762c7d73f5 100644 --- a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx @@ -246,11 +246,16 @@ verify_window_sizes(int numsizes, int *dimen) { //////////////////////////////////////////////////////////////////// void wdxGraphicsWindow8:: close_window() { - wdxdisplay8_cat.debug() << "wdx closed window\n"; + if (wdxdisplay8_cat.is_debug()) { + wdxdisplay8_cat.debug() + << "wdxGraphicsWindow8::close_window() " << this << "\n"; + } + if (_gsg != (GraphicsStateGuardian*)NULL) { _gsg.clear(); _active = false; } + _dxgsg->release_swap_chain(&_wcontext); WinGraphicsWindow::close_window(); } @@ -286,6 +291,15 @@ open_window() { return false; } + // Ensure the window properties get set to the actual size of the + // window. + { + WindowProperties resized_props; + resized_props.set_size(_wcontext._display_mode.Width, + _wcontext._display_mode.Height); + _properties.add_properties(resized_props); + } + wdxdisplay8_cat.debug() << "_wcontext._window is " << _wcontext._window << "\n"; if (!WinGraphicsWindow::open_window()) { return false; @@ -309,8 +323,8 @@ open_window() { wdxdisplay8_cat.debug() << "device width " << _wcontext._display_mode.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"; + wdxdisplay8_cat.error() << "Unable to create window with specified parameters.\n"; + close_window(); return false; } _dxgsg->get_pipe()->make_device((void*)(&_wcontext)); @@ -536,10 +550,11 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer PRINT_REFCNT(wdxdisplay8, _d3d8); - assert(_d3d8 != NULL); - assert(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION); + nassertr(_d3d8 != NULL, false); + nassertr(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION, false); presentation_params->BackBufferFormat = display._display_mode.Format; // dont need dest alpha, so just use adapter format + cerr << "attempting " << D3DFormatStr(presentation_params->BackBufferFormat) << "\n"; bool do_sync = sync_video; @@ -691,7 +706,7 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD; } - //assert((dwRenderWidth == presentation_params->BackBufferWidth)&&(dwRenderHeight == presentation_params->BackBufferHeight)); + //nassertv((dwRenderWidth == presentation_params->BackBufferWidth)&&(dwRenderHeight == presentation_params->BackBufferHeight)); hr = _d3d8->CreateDevice(display._card_id, D3DDEVTYPE_HAL, _hWnd, dwBehaviorFlags, presentation_params, &display._d3d_device); @@ -759,7 +774,6 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer return true; Fallback_to_16bpp_buffers: - if ((!IS_16BPP_DISPLAY_FORMAT(presentation_params->BackBufferFormat)) && (display._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) { // fallback strategy, if we trying >16bpp, fallback to 16bpp buffers @@ -903,14 +917,14 @@ choose_device() { bool wdxGraphicsWindow8:: search_for_device(wdxGraphicsPipe8 *dxpipe, DXDeviceInfo *device_info) { - assert(dxpipe != NULL); + nassertr(dxpipe != NULL, false); WindowProperties properties = get_properties(); DWORD dwRenderWidth = properties.get_x_size(); DWORD dwRenderHeight = properties.get_y_size(); HRESULT hr; LPDIRECT3D8 _d3d8 = dxpipe->__d3d8; - assert(_dxgsg != NULL); + nassertr(_dxgsg != NULL, false); _wcontext._d3d8 = _d3d8; _wcontext._is_dx8_1 = dxpipe->__is_dx8_1; _wcontext._card_id = device_info->cardID; // could this change by end? @@ -1145,8 +1159,8 @@ init_resized_window() { DWORD newWidth = _wcontext._presentation_params.BackBufferWidth; DWORD newHeight = _wcontext._presentation_params.BackBufferHeight; - assert((newWidth != 0) && (newHeight != 0)); - assert(_wcontext._window != NULL); + nassertv((newWidth != 0) && (newHeight != 0)); + nassertv(_wcontext._window != NULL); if (_wcontext._presentation_params.Windowed) { POINT ul, lr; @@ -1169,7 +1183,7 @@ init_resized_window() { } // clear window to black ASAP - assert(_wcontext._window != NULL); + nassertv(_wcontext._window != NULL); ClearToBlack(_wcontext._window, get_properties()); // clear textures and VB's out of video&AGP mem, so cache is reset diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 128be5a954..15927d6034 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -908,6 +908,7 @@ clear(DrawableRegion *clearable) { << "Unable to clear stencil buffer; removing.\n"; // This is really hacky code. ((FrameBufferProperties *)_current_properties)->set_stencil_bits(0); + _supports_stencil = false; } } } @@ -2483,7 +2484,30 @@ reset() { if (support_stencil) { int min_stencil = D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR; if ((d3d_caps.StencilCaps & min_stencil) == min_stencil) { - _supports_stencil = true; + if (dxgsg9_cat.is_debug()) { + dxgsg9_cat.debug() + << "Checking for stencil; mode = " + << D3DFormatStr(_screen->_presentation_params.AutoDepthStencilFormat) + << "\n"; + } + switch (_screen->_presentation_params.AutoDepthStencilFormat) { + // These are the only formats that support stencil. + case D3DFMT_D15S1: + case D3DFMT_D24S8: + case D3DFMT_D24X4S4: + _supports_stencil = true; + if (dxgsg9_cat.is_debug()) { + dxgsg9_cat.debug() + << "Stencils supported.\n"; + } + break; + + default: + if (dxgsg9_cat.is_debug()) { + dxgsg9_cat.debug() + << "Stencils NOT supported.\n"; + } + } } } diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index 8ba6bc761c..b960a7795e 100755 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -441,10 +441,14 @@ find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode, bVerboseMode = true; } - // list fmts in order of preference -#define NUM_TEST_ZFMTS 3 - static D3DFORMAT NoStencilPrefList[NUM_TEST_ZFMTS] = {D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16}; - static D3DFORMAT StencilPrefList[NUM_TEST_ZFMTS] = {D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D15S1}; + // list formats to try in order of preference. + +#define NUM_TEST_ZFMTS 6 +#define FIRST_NON_STENCIL_ZFMT 3 + static D3DFORMAT FormatPrefList[NUM_TEST_ZFMTS] = { + D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D15S1, // with stencil + D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16 // without stencil + }; // do not use Display._display_mode since that is probably not set yet, use Test_display_mode instead @@ -460,9 +464,9 @@ find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode, << "FindBestDepthFmt: bSelectOnly16bpp: " << bOnlySelect16bpp << endl; } - for (int i = 0; i < NUM_TEST_ZFMTS; i++) { - D3DFORMAT TestDepthFmt = - (bWantStencil ? StencilPrefList[i] : NoStencilPrefList[i]); + int first_format = (bWantStencil ? 0 : FIRST_NON_STENCIL_ZFMT); + for (int i = first_format; i < NUM_TEST_ZFMTS; i++) { + D3DFORMAT TestDepthFmt = FormatPrefList[i]; if (bOnlySelect16bpp && !IS_16BPP_ZBUFFER(TestDepthFmt)) { continue; diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx index 230f1d884c..5ca1517ca3 100755 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx @@ -285,6 +285,8 @@ open_window() { if (_gsg == 0) { _dxgsg = new DXGraphicsStateGuardian9(_pipe); _gsg = _dxgsg; + } else { + DCAST_INTO_R(_dxgsg, _gsg, false); } if (!choose_device()) { @@ -585,33 +587,26 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer do_sync = false; } - bool check_device_format; + presentation_params->BackBufferFormat = display._display_mode.Format; // check for D3DFMT_A8R8G8B8 first - check_device_format = false; if (bWantAlpha) { - presentation_params->BackBufferFormat = D3DFMT_A8R8G8B8; - // verify the rendertarget fmt - if (FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET, - D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) { - wdxdisplay9_cat.error() << "adpater #" << adapter << " CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl; - } - else { - check_device_format = true; + if (!FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET, + D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8))) { + if (!FAILED(_d3d9->CheckDeviceType(adapter, device_type, display._display_mode.Format, D3DFMT_A8R8G8B8, + is_fullscreen()))) { + // We can accept D3DFMT_A8R8G8B8, so use it. + presentation_params->BackBufferFormat = D3DFMT_A8R8G8B8; + } } } // check for same format as display_mode - if (check_device_format == false) { - presentation_params->BackBufferFormat = display._display_mode.Format; - // verify the rendertarget fmt - if (FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET, - D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) { - wdxdisplay9_cat.error() << "adapter #" << adapter << " CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl; - } - else { - check_device_format = true; - } + // verify the rendertarget fmt + if (FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET, + D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) { + wdxdisplay9_cat.error() << "adapter #" << adapter << " CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl; + goto Fallback_to_16bpp_buffers; } if (FAILED(_d3d9->CheckDeviceType(adapter, device_type, display._display_mode.Format, presentation_params->BackBufferFormat, @@ -844,7 +839,6 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer return true; Fallback_to_16bpp_buffers: - if ((!IS_16BPP_DISPLAY_FORMAT(presentation_params->BackBufferFormat)) && (display._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) { // fallback strategy, if we trying >16bpp, fallback to 16bpp buffers