38 const std::string &name,
51 _depth_buffer_bpp = 0;
52 _awaiting_restore =
false;
53 ZeroMemory(&_wcontext,
sizeof(_wcontext));
60~wdxGraphicsWindow9() {
66void wdxGraphicsWindow9::
70 _dxgsg->set_context(&_wcontext);
87 begin_frame_spam(mode);
88 if (_gsg ==
nullptr) {
93 if (wdxdisplay9_cat.is_spam()) {
94 wdxdisplay9_cat.spam()
95 <<
"Not drawing " <<
this <<
": unexposed.\n";
100 if (_awaiting_restore) {
103 if (!_dxgsg->check_cooperative_level()) {
107 _awaiting_restore =
false;
108 init_resized_window();
113 if (mode == FM_render) {
114 clear_cube_map_selection();
118 bool return_val = _gsg->begin_frame(current_thread);
119 _dxgsg->set_render_target();
130 end_frame_spam(mode);
131 nassertv(_gsg !=
nullptr);
133 if (mode == FM_render) {
137 _gsg->end_frame(current_thread);
139 if (mode == FM_render) {
141 clear_cube_map_selection();
155 _dxgsg->show_frame();
173 nassertr(IS_VALID_PTR(_dxgsg), 0);
175 int num_valid_modes = 0;
178 DCAST_INTO_R(dxpipe, _pipe, 0);
183 int *pCurDim = dimen;
185 for (
int i = 0; i < numsizes; i++, pCurDim += 2) {
186 int x_size = pCurDim[0];
187 int y_size = pCurDim[1];
189 bool bIsGoodMode =
false;
190 bool CouldntFindAnyValidZBuf;
191 D3DFORMAT newPixFmt = D3DFMT_UNKNOWN;
198 if (_wcontext._is_low_memory_card) {
199 bIsGoodMode = ((x_size == 640) && (y_size == 480));
202 (_wcontext, x_size, y_size, _wcontext._presentation_params.EnableAutoDepthStencil !=
false,
203 IS_STENCIL_FORMAT(_wcontext._presentation_params.AutoDepthStencilFormat),
204 &_wcontext._supported_screen_depths_mask,
205 &CouldntFindAnyValidZBuf, &newPixFmt, dx_force_16bpp_zbuffer,
true);
206 bIsGoodMode = (newPixFmt != D3DFMT_UNKNOWN);
218 if (wdxdisplay9_cat.is_spam()) {
219 wdxdisplay9_cat.spam()
220 <<
"Fullscrn Mode (" << x_size <<
", " << y_size <<
")\t"
221 << (bIsGoodMode ?
"V" :
"Inv") <<
"alid\n";
225 return num_valid_modes;
232void wdxGraphicsWindow9::
234 if (wdxdisplay9_cat.is_debug()) {
235 wdxdisplay9_cat.debug()
236 <<
"wdxGraphicsWindow9::close_window() " <<
this <<
"\n";
239 if (_gsg !=
nullptr) {
245 _dxgsg->release_swap_chain(&_wcontext);
247 WinGraphicsWindow::close_window();
254bool wdxGraphicsWindow9::
263 bool discard_device = always_discard_device;
269 DCAST_INTO_R(_dxgsg, _gsg,
false);
272 if (!choose_device()) {
279 resized_props.
set_size(_wcontext._display_mode.Width,
280 _wcontext._display_mode.Height);
281 _properties.add_properties(resized_props);
284 wdxdisplay9_cat.debug() <<
"_wcontext._window is " << _wcontext._window <<
"\n";
285 if (!WinGraphicsWindow::open_window()) {
288 _wcontext._window = _hWnd;
290 wdxdisplay9_cat.debug() <<
"_wcontext._window is " << _wcontext._window <<
"\n";
297 if (_dxgsg->
get_pipe()->get_device() ==
nullptr || discard_device) {
298 wdxdisplay9_cat.debug() <<
"device is null or fullscreen\n";
301 if (_dxgsg->
get_pipe()->get_device()) {
302 _dxgsg->dx_cleanup();
305 wdxdisplay9_cat.debug() <<
"device width " << _wcontext._display_mode.Width <<
"\n";
306 if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) {
307 wdxdisplay9_cat.error() <<
"Unable to create window with specified parameters.\n";
311 _dxgsg->
get_pipe()->make_device((
void*)(&_wcontext));
312 _dxgsg->copy_pres_reset(&_wcontext);
313 _dxgsg->create_swap_chain(&_wcontext);
319 wdxdisplay9_cat.debug() <<
"device is not null\n";
322 memcpy(&_wcontext, &dxdev->_Scrn,
sizeof(
DXScreenData));
325 _wcontext._presentation_params.hDeviceWindow = _wcontext._window = _hWnd;
326 _wcontext._presentation_params.BackBufferWidth = _wcontext._display_mode.Width = _properties.get_x_size();
327 _wcontext._presentation_params.BackBufferHeight = _wcontext._display_mode.Height = _properties.get_y_size();
329 wdxdisplay9_cat.debug() <<
"device width " << _wcontext._presentation_params.BackBufferWidth <<
"\n";
330 if (!_dxgsg->create_swap_chain(&_wcontext)) {
331 discard_device =
true;
334 init_resized_window();
338 wdxdisplay9_cat.debug() <<
"swapchain is " << _wcontext._swap_chain <<
"\n";
348void wdxGraphicsWindow9::
349reset_window(
bool swapchain) {
351 if (_wcontext._swap_chain) {
352 _dxgsg->create_swap_chain(&_wcontext);
353 wdxdisplay9_cat.debug() <<
"created swapchain " << _wcontext._swap_chain <<
"\n";
357 if (_wcontext._swap_chain) {
358 _dxgsg->release_swap_chain(&_wcontext);
359 wdxdisplay9_cat.debug() <<
"released swapchain " << _wcontext._swap_chain <<
"\n";
370void wdxGraphicsWindow9::
376 if (_dxgsg !=
nullptr) {
377 _awaiting_restore =
true;
385void wdxGraphicsWindow9::
388 WinGraphicsWindow::handle_reshape();
390 if (_dxgsg !=
nullptr && _dxgsg->_d3d_device !=
nullptr) {
396 if (_wcontext._presentation_params.BackBufferWidth != x_size ||
397 _wcontext._presentation_params.BackBufferHeight != y_size) {
398 bool resize_succeeded = reset_device_resize_window(x_size, y_size);
400 if (wdxdisplay9_cat.is_debug()) {
401 if (!resize_succeeded) {
402 wdxdisplay9_cat.debug()
403 <<
"windowed_resize to size: (" << x_size <<
", " << y_size
404 <<
") failed due to out-of-memory\n";
408 wdxdisplay9_cat.debug()
409 <<
"windowed_resize to origin: (" << x_origin <<
", "
410 << y_origin <<
"), size: (" << x_size
411 <<
", " << y_size <<
")\n";
421bool wdxGraphicsWindow9::
422do_fullscreen_resize(
int x_size,
int y_size) {
423 if (!WinGraphicsWindow::do_fullscreen_resize(x_size, y_size)) {
427 bool bCouldntFindValidZBuf;
429 bool bNeedZBuffer = (_wcontext._presentation_params.EnableAutoDepthStencil !=
false);
430 bool bNeedStencilBuffer = IS_STENCIL_FORMAT(_wcontext._presentation_params.AutoDepthStencilFormat);
433 DCAST_INTO_R(dxpipe, _pipe,
false);
435 bool bIsGoodMode =
false;
436 bool bResizeSucceeded =
false;
442 if (_wcontext._is_low_memory_card && (!((x_size == 640) && (y_size == 480)))) {
443 wdxdisplay9_cat.error() <<
"resize() failed: will not try to resize low vidmem device #" << _wcontext._card_id <<
" to non-640x480!\n";
444 return bResizeSucceeded;
451 bNeedZBuffer, bNeedStencilBuffer,
452 &_wcontext._supported_screen_depths_mask,
453 &bCouldntFindValidZBuf,
454 &pixFmt, dx_force_16bpp_zbuffer,
true);
455 bIsGoodMode = (pixFmt != D3DFMT_UNKNOWN);
458 wdxdisplay9_cat.error() <<
"resize() failed: "
459 << (bCouldntFindValidZBuf ?
"Couldnt find valid zbuffer format to go with FullScreen mode" :
"No supported FullScreen modes")
460 <<
" at " << x_size <<
"x" << y_size <<
" for device #" << _wcontext._card_id << endl;
461 return bResizeSucceeded;
466 _wcontext._display_mode.Width = x_size;
467 _wcontext._display_mode.Height = y_size;
468 _wcontext._display_mode.Format = pixFmt;
469 _wcontext._display_mode.RefreshRate = D3DPRESENT_RATE_DEFAULT;
473 bResizeSucceeded = reset_device_resize_window(x_size, y_size);
475 if (!bResizeSucceeded) {
476 wdxdisplay9_cat.error() <<
"resize() failed with OUT-OF-MEMORY error!\n";
478 if ((!IS_16BPP_DISPLAY_FORMAT(_wcontext._presentation_params.BackBufferFormat)) &&
479 (_wcontext._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) {
481 _wcontext._display_mode.Format = ((_wcontext._supported_screen_depths_mask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5);
482 dx_force_16bpp_zbuffer =
true;
483 if (wdxdisplay9_cat.info())
484 wdxdisplay9_cat.info() <<
"CreateDevice failed with out-of-vidmem, retrying w/16bpp buffers on device #" << _wcontext._card_id << endl;
486 bResizeSucceeded = reset_device_resize_window(x_size, y_size);
490 return bResizeSucceeded;
499bool wdxGraphicsWindow9::
500create_screen_buffers_and_device(
DXScreenData &display,
bool force_16bpp_zbuffer) {
502 DCAST_INTO_R(dxpipe, _pipe,
false);
504 DWORD dwRenderWidth = display._display_mode.Width;
505 DWORD dwRenderHeight = display._display_mode.Height;
506 DWORD dwBehaviorFlags = 0x0;
507 LPDIRECT3D9 _d3d9 = display._d3d9;
508 D3DCAPS9 *pD3DCaps = &display._d3dcaps;
509 D3DPRESENT_PARAMETERS* presentation_params = &display._presentation_params;
512 D3DDEVTYPE device_type;
515 adapter = display._card_id;
516 device_type = D3DDEVTYPE_HAL;
519 if (dx_use_nvperfhud) {
523 total_adapters = _d3d9 -> GetAdapterCount ( );
524 for (adapter_id = 0; adapter_id < total_adapters; adapter_id++) {
525 D3DADAPTER_IDENTIFIER9 identifier;
527 _d3d9 -> GetAdapterIdentifier (adapter_id, 0, &identifier);
528 if (strcmp (
"NVIDIA NVPerfHUD", identifier.Description) == 0) {
529 adapter = adapter_id;
530 device_type = D3DDEVTYPE_REF;
536 wdxdisplay9_cat.debug() <<
"Display Width " << dwRenderWidth <<
" and PresParam Width " << _wcontext._presentation_params.BackBufferWidth <<
"\n";
540 bool bWantStencil = (_fb_properties.get_stencil_bits() > 0);
541 bool bWantAlpha = (_fb_properties.get_alpha_bits() > 0);
543 PRINT_REFCNT(wdxdisplay9, _d3d9);
545 nassertr(_d3d9 !=
nullptr,
false);
546 nassertr(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION,
false);
548 bool do_sync = sync_video;
550 if (do_sync && !(pD3DCaps->Caps & D3DCAPS_READ_SCANLINE)) {
551 wdxdisplay9_cat.info()
552 <<
"HW doesnt support syncing to vertical refresh, ignoring sync-video\n";
556 presentation_params->BackBufferFormat = display._display_mode.Format;
560 if (!FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
561 D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8))) {
562 if (!FAILED(_d3d9->CheckDeviceType(adapter, device_type, display._display_mode.Format, D3DFMT_A8R8G8B8,
565 presentation_params->BackBufferFormat = D3DFMT_A8R8G8B8;
571 if (FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
572 D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) {
573 wdxdisplay9_cat.error() <<
"adapter #" << adapter <<
" CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
574 goto Fallback_to_16bpp_buffers;
577 if (FAILED(_d3d9->CheckDeviceType(adapter, device_type, display._display_mode.Format, presentation_params->BackBufferFormat,
579 wdxdisplay9_cat.error() <<
"adapter #" << adapter <<
" CheckDeviceType failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
580 goto Fallback_to_16bpp_buffers;
583 if (display._presentation_params.EnableAutoDepthStencil) {
584 if (!dxpipe->find_best_depth_format(display, display._display_mode,
585 &display._presentation_params.AutoDepthStencilFormat,
586 bWantStencil,
false)) {
587 wdxdisplay9_cat.error()
588 <<
"find_best_depth_format failed in CreateScreenBuffers for device #"
590 goto Fallback_to_16bpp_buffers;
592 _depth_buffer_bpp = D3DFMT_to_DepthBits(display._presentation_params.AutoDepthStencilFormat);
594 _depth_buffer_bpp = 0;
599 int supported_multisamples = 0;
600 if (framebuffer_multisample.
get_value()){
601 supported_multisamples = multisamples.
get_value();
604 while (supported_multisamples > 1){
606 hr = _d3d9->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, display._display_mode.Format,
607 is_fullscreen(), D3DMULTISAMPLE_TYPE(supported_multisamples),
nullptr);
609 supported_multisamples--;
613 if (display._presentation_params.EnableAutoDepthStencil) {
614 hr = _d3d9->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, display._presentation_params.AutoDepthStencilFormat,
615 is_fullscreen(), D3DMULTISAMPLE_TYPE(supported_multisamples),
nullptr);
617 supported_multisamples--;
622 presentation_params->MultiSampleType = D3DMULTISAMPLE_TYPE(supported_multisamples);
624 if (wdxdisplay9_cat.is_info())
625 wdxdisplay9_cat.info() <<
"adapter #" << adapter <<
" using multisample antialiasing level: " << supported_multisamples <<
626 ". Requested level was: " << multisamples.
get_value() << endl;
630 presentation_params->BackBufferCount = 1;
631 presentation_params->Flags = 0x0;
632 presentation_params->hDeviceWindow = display._window;
633 presentation_params->BackBufferWidth = display._display_mode.Width;
634 presentation_params->BackBufferHeight = display._display_mode.Height;
636 if (_wcontext._is_tnl_device) {
637 dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
645 dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
648 if (dx_preserve_fpu_state)
649 dwBehaviorFlags |= D3DCREATE_FPU_PRESERVE;
656 if (!SetForegroundWindow(display._window)) {
657 wdxdisplay9_cat.warning() <<
"SetForegroundWindow() failed!\n";
660 if (dx_use_multithread) {
661 dwBehaviorFlags |= D3DCREATE_MULTITHREADED;
663 if (dx_use_puredevice) {
664 dwBehaviorFlags |= D3DCREATE_PUREDEVICE;
667 if (dx_disable_driver_management) {
668 dwBehaviorFlags |= D3DCREATE_DISABLE_DRIVER_MANAGEMENT;
670 if (dx_disable_driver_management_ex) {
671 dwBehaviorFlags |= D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX;
677 presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD;
678 presentation_params->PresentationInterval = (do_sync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE);
679 presentation_params->FullScreen_RefreshRateInHz = display._display_mode.RefreshRate;
683 hr = _d3d9->CreateDevice(adapter, device_type, _hWnd,
684 dwBehaviorFlags, presentation_params, &display._d3d_device);
687 wdxdisplay9_cat.fatal() <<
"D3D CreateDevice failed for adapter #" << adapter <<
", " << D3DERRORSTRING(hr);
689 if (hr == D3DERR_OUTOFVIDEOMEMORY)
690 goto Fallback_to_16bpp_buffers;
695 SetRect(&view_rect, 0, 0, dwRenderWidth, dwRenderHeight);
700 D3DDISPLAYMODE dispmode;
701 hr = display._d3d9->GetAdapterDisplayMode(adapter, &dispmode);
704 wdxdisplay9_cat.fatal()
705 <<
"GetAdapterDisplayMode failed" << D3DERRORSTRING(hr);
709 if (dispmode.Format == D3DFMT_P8) {
710 wdxdisplay9_cat.fatal()
711 <<
"Can't run windowed in an 8-bit or less display mode" << endl;
720 presentation_params->PresentationInterval = 0;
723 presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD;
724 if (do_sync ==
false) {
725 presentation_params->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
749 hr = _d3d9->CreateDevice(adapter, device_type, _hWnd,
750 dwBehaviorFlags, presentation_params, &display._d3d_device);
753 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferWidth : " << presentation_params->BackBufferWidth << endl;
754 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferHeight : " << presentation_params->BackBufferHeight << endl;
755 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferFormat : " << presentation_params->BackBufferFormat << endl;
756 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferCount : " << presentation_params->BackBufferCount << endl;
757 wdxdisplay9_cat.warning() <<
"D3D CreateDevice failed for adapter #" << adapter << D3DERRORSTRING(hr);
758 goto Fallback_to_16bpp_buffers;
764 PRINT_REFCNT(wdxdisplay9, _wcontext._d3d_device);
766 if (presentation_params->EnableAutoDepthStencil) {
772 switch (presentation_params->AutoDepthStencilFormat)
774 case D3DFMT_D16_LOCKABLE:
795 case D3DFMT_D32F_LOCKABLE:
806 wdxdisplay9_cat.error() <<
"unknown depth stencil format " << presentation_params->AutoDepthStencilFormat;
810 _fb_properties.set_stencil_bits(stencil_bits);
811 _fb_properties.set_depth_bits(depth_bits);
813 _fb_properties.set_depth_bits(0);
814 _fb_properties.set_stencil_bits(0);
817 init_resized_window();
821 Fallback_to_16bpp_buffers:
822 if ((!IS_16BPP_DISPLAY_FORMAT(presentation_params->BackBufferFormat)) &&
823 (display._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) {
826 display._display_mode.Format = ((display._supported_screen_depths_mask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5);
828 if (wdxdisplay9_cat.info()) {
829 wdxdisplay9_cat.info()
830 <<
"CreateDevice failed with out-of-vidmem or invalid BackBufferFormat, retrying w/16bpp buffers on adapter #"
833 return create_screen_buffers_and_device(display,
true);
836 }
else if (!((dwRenderWidth == 640)&&(dwRenderHeight == 480))) {
837 if (wdxdisplay9_cat.info())
838 wdxdisplay9_cat.info() <<
"CreateDevice failed w/out-of-vidmem, retrying at 640x480 w/16bpp buffers on adapter #" << adapter << endl;
840 display._display_mode.Width = 640;
841 display._display_mode.Height = 480;
842 return create_screen_buffers_and_device(display,
true);
846 wdxdisplay9_cat.fatal()
847 <<
"Can't create any screen buffers, bailing out.\n";
858bool wdxGraphicsWindow9::
863 DCAST_INTO_R(dxpipe, _pipe,
false);
865 int num_adapters = dxpipe->__d3d9->GetAdapterCount();
866 DXDeviceInfoVec device_infos;
868 for (
int i = 0; i < num_adapters; i++) {
869 D3DADAPTER_IDENTIFIER9 adapter_info;
870 ZeroMemory(&adapter_info,
sizeof(D3DADAPTER_IDENTIFIER9));
871 hr = dxpipe->__d3d9->GetAdapterIdentifier(i, 0, &adapter_info);
873 wdxdisplay9_cat.fatal()
874 <<
"D3D GetAdapterID(" << i <<
") failed: "
875 << D3DERRORSTRING(hr) << endl;
879 LARGE_INTEGER *DrvVer = &adapter_info.DriverVersion;
881 wdxdisplay9_cat.info()
882 <<
"D3D9 Adapter[" << i <<
"]: " << adapter_info.Description
883 <<
", Driver: " << adapter_info.Driver <<
", DriverVersion: ("
884 << HIWORD(DrvVer->HighPart) <<
"." << LOWORD(DrvVer->HighPart) <<
"."
885 << HIWORD(DrvVer->LowPart) <<
"." << LOWORD(DrvVer->LowPart)
886 <<
")\nVendorID: 0x" << std::hex << adapter_info.VendorId
887 <<
" DeviceID: 0x" << adapter_info.DeviceId
888 <<
" SubsysID: 0x" << adapter_info.SubSysId
889 <<
" Revision: 0x" << adapter_info.Revision << std::dec << endl;
891 HMONITOR _monitor = dxpipe->__d3d9->GetAdapterMonitor(i);
892 if (_monitor ==
nullptr) {
893 wdxdisplay9_cat.info()
894 <<
"D3D9 Adapter[" << i <<
"]: seems to be disabled, skipping it\n";
898 DXDeviceInfo devinfo;
899 ZeroMemory(&devinfo,
sizeof(devinfo));
900 memcpy(&devinfo.guidDeviceIdentifier, &adapter_info.DeviceIdentifier,
902 strncpy(devinfo.szDescription, adapter_info.Description,
903 MAX_DEVICE_IDENTIFIER_STRING);
904 strncpy(devinfo.szDriver, adapter_info.Driver,
905 MAX_DEVICE_IDENTIFIER_STRING);
906 devinfo.VendorID = adapter_info.VendorId;
907 devinfo.DeviceID = adapter_info.DeviceId;
908 devinfo._driver_version = adapter_info.DriverVersion;
909 devinfo._monitor = _monitor;
912 device_infos.push_back(devinfo);
915 if (device_infos.empty()) {
916 wdxdisplay9_cat.error()
917 <<
"No available D3D9 devices found.\n";
923 num_adapters = (int)device_infos.size();
927 int adapter_num = D3DADAPTER_DEFAULT;
931 if (dx_preferred_device_id != -1) {
932 if (dx_preferred_device_id < 0 || dx_preferred_device_id >= num_adapters) {
933 wdxdisplay9_cat.error()
934 <<
"invalid 'dx-preferred-device-id', valid values are 0-"
935 << num_adapters - 1 <<
", using default adapter instead.\n";
937 adapter_num = dx_preferred_device_id;
942 if (adapter_num >= 0 && adapter_num < (
int)device_infos.size()) {
943 if (consider_device(dxpipe, &device_infos[adapter_num])) {
944 wdxdisplay9_cat.info()
945 <<
"Selected device " << adapter_num <<
" (of "
946 << device_infos.
size() <<
", zero-based)\n";
949 wdxdisplay9_cat.info()
950 <<
"Could not select device " << adapter_num <<
"\n";
954 for (UINT devnum = 0; devnum < device_infos.size(); ++devnum) {
955 if (consider_device(dxpipe, &device_infos[devnum])) {
956 wdxdisplay9_cat.info()
957 <<
"Chose device " << devnum <<
" (of "
958 << device_infos.size() <<
", zero-based): first one that works.\n";
963 wdxdisplay9_cat.error() <<
"no usable display devices.\n";
971bool wdxGraphicsWindow9::
974 nassertr(dxpipe !=
nullptr,
false);
976 DWORD dwRenderWidth = properties.
get_x_size();
977 DWORD dwRenderHeight = properties.
get_y_size();
979 LPDIRECT3D9 _d3d9 = dxpipe->__d3d9;
981 nassertr(_dxgsg !=
nullptr,
false);
982 _wcontext._d3d9 = _d3d9;
983 _wcontext._card_id = device_info->cardID;
985 bool bWantStencil = (_fb_properties.get_stencil_bits() > 0);
987 hr = _d3d9->GetAdapterIdentifier(device_info->cardID, 0,
988 &_wcontext._dx_device_id);
990 wdxdisplay9_cat.error()
991 <<
"D3D GetAdapterID failed" << D3DERRORSTRING(hr);
996 hr = _d3d9->GetDeviceCaps(device_info->cardID, D3DDEVTYPE_HAL, &_d3dcaps);
998 if ((hr == D3DERR_INVALIDDEVICE)||(hr == D3DERR_NOTAVAILABLE)) {
999 wdxdisplay9_cat.error()
1000 <<
"No DirectX 9 D3D-capable 3D hardware detected for device # "
1001 << device_info->cardID <<
" (" << device_info->szDescription
1004 wdxdisplay9_cat.error()
1005 <<
"GetDeviceCaps failed: " << D3DERRORSTRING(hr) << endl;
1011 memcpy(&_wcontext._d3dcaps, &_d3dcaps,
sizeof(D3DCAPS9));
1012 _wcontext._card_id = device_info->cardID;
1014 _wcontext._max_available_video_memory = UNKNOWN_VIDMEM_SIZE;
1015 _wcontext._is_low_memory_card =
false;
1020 if (_d3dcaps.MaxStreams == 0) {
1021 if (wdxdisplay9_cat.is_debug()) {
1022 wdxdisplay9_cat.debug()
1023 <<
"checking vidmem size\n";
1029 for (IDnum = 0; IDnum < dxpipe->_card_ids.size(); IDnum++) {
1030 if ((device_info->VendorID == dxpipe->_card_ids[IDnum].VendorID) &&
1031 (device_info->DeviceID == dxpipe->_card_ids[IDnum].DeviceID) &&
1032 (device_info->_monitor == dxpipe->_card_ids[IDnum]._monitor))
1036 if (IDnum < dxpipe->_card_ids.size()) {
1037 _wcontext._max_available_video_memory = dxpipe->_card_ids[IDnum]._max_available_video_memory;
1038 _wcontext._is_low_memory_card = dxpipe->_card_ids[IDnum]._is_low_memory_card;
1040 wdxdisplay9_cat.error()
1041 <<
"Error: couldnt find a CardID match in DX7 info, assuming card is not a lowmem card\n";
1045 if ((bWantStencil) && (_d3dcaps.StencilCaps == 0x0)) {
1046 wdxdisplay9_cat.fatal()
1047 <<
"Stencil ability requested, but device #" << device_info->cardID
1048 <<
" (" << _wcontext._dx_device_id.Description
1049 <<
"), has no stencil capability!\n";
1056 _wcontext._is_tnl_device =
1057 ((_d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0);
1058 _wcontext._can_use_hw_vertex_shaders =
1059 (_d3dcaps.VertexShaderVersion >= D3DVS_VERSION(1, 0));
1060 _wcontext._can_use_pixel_shaders =
1061 (_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(1, 0));
1064 ((!(_d3dcaps.RasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )) &&
1065 (_fb_properties.get_depth_bits() > 0));
1067 _wcontext._presentation_params.EnableAutoDepthStencil = bNeedZBuffer;
1069 D3DFORMAT pixFmt = D3DFMT_UNKNOWN;
1072 bool bCouldntFindValidZBuf;
1075 bNeedZBuffer, bWantStencil,
1076 &_wcontext._supported_screen_depths_mask,
1077 &bCouldntFindValidZBuf,
1078 &pixFmt, dx_force_16bpp_zbuffer,
true);
1083 if (pixFmt == D3DFMT_UNKNOWN) {
1084 wdxdisplay9_cat.error()
1085 << (bCouldntFindValidZBuf ?
"Couldnt find valid zbuffer format to go with FullScreen mode" :
"No supported FullScreen modes")
1086 <<
" at " << dwRenderWidth <<
"x" << dwRenderHeight <<
" for device #" << _wcontext._card_id << endl;
1092 D3DDISPLAYMODE dispmode;
1093 hr = _d3d9->GetAdapterDisplayMode(device_info->cardID, &dispmode);
1095 wdxdisplay9_cat.error()
1096 <<
"GetAdapterDisplayMode(" << device_info->cardID
1097 <<
") failed" << D3DERRORSTRING(hr);
1100 pixFmt = dispmode.Format;
1103 _wcontext._display_mode.Width = dwRenderWidth;
1104 _wcontext._display_mode.Height = dwRenderHeight;
1105 _wcontext._display_mode.Format = pixFmt;
1106 _wcontext._display_mode.RefreshRate = D3DPRESENT_RATE_DEFAULT;
1107 _wcontext._monitor = device_info->_monitor;
1109 if (strcmp(device_info->szDriver,
"igdumd32.dll") == 0 &&
1110 device_info->_driver_version.QuadPart <= 0x0007000e000affffLL &&
1111 dx_intel_compressed_texture_bug) {
1114 _wcontext._intel_compressed_texture_bug =
true;
1124bool wdxGraphicsWindow9::
1125reset_device_resize_window(UINT new_xsize, UINT new_ysize) {
1129 D3DPRESENT_PARAMETERS d3dpp;
1130 memcpy(&d3dpp, &_wcontext._presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
1131 _wcontext._presentation_params.BackBufferWidth = new_xsize;
1132 _wcontext._presentation_params.BackBufferHeight = new_ysize;
1134 HRESULT hr = _dxgsg->reset_d3d_device(&_wcontext._presentation_params, &screen);
1138 wdxdisplay9_cat.error()
1139 <<
"reset_device_resize_window Reset() failed" << D3DERRORSTRING(hr);
1140 if (hr == D3DERR_OUTOFVIDEOMEMORY) {
1141 memcpy(&_wcontext._presentation_params, &d3dpp,
sizeof(D3DPRESENT_PARAMETERS));
1142 hr = _dxgsg->reset_d3d_device(&_wcontext._presentation_params, &screen);
1144 wdxdisplay9_cat.error()
1145 <<
"reset_device_resize_window Reset() failed OutOfVidmem, then failed again doing Reset w/original params:" << D3DERRORSTRING(hr);
1146 throw_event(
"panda3d-render-error");
1150 if (wdxdisplay9_cat.is_info()) {
1151 wdxdisplay9_cat.info()
1152 <<
"reset of original size (" << _wcontext._presentation_params.BackBufferWidth
1153 <<
", " << _wcontext._presentation_params.BackBufferHeight <<
") succeeded\n";
1157 wdxdisplay9_cat.fatal()
1158 <<
"Can't reset device, bailing out.\n";
1159 throw_event(
"panda3d-render-error");
1166 _wcontext._swap_chain = screen->_swap_chain;
1168 wdxdisplay9_cat.debug() <<
"swapchain is " << _wcontext._swap_chain <<
"\n";
1170 init_resized_window();
1181void wdxGraphicsWindow9::
1182init_resized_window() {
1185 DWORD newWidth = _wcontext._presentation_params.BackBufferWidth;
1186 DWORD newHeight = _wcontext._presentation_params.BackBufferHeight;
1188 nassertv((newWidth != 0) && (newHeight != 0));
1189 nassertv(_wcontext._window !=
nullptr);
1191 if (_wcontext._presentation_params.Windowed) {
1198 GetClientRect(_wcontext._window, &client_rect);
1199 ul.x = client_rect.left;
1200 ul.y = client_rect.top;
1201 lr.x = client_rect.right;
1202 lr.y = client_rect.bottom;
1203 ClientToScreen(_wcontext._window, &ul);
1204 ClientToScreen(_wcontext._window, &lr);
1205 client_rect.left = ul.x;
1206 client_rect.top = ul.y;
1207 client_rect.right = lr.x;
1208 client_rect.bottom = lr.y;
1212 nassertv(_wcontext._window !=
nullptr);
1216 hr = _wcontext._d3d_device->EvictManagedResources ( );
1218 wdxdisplay9_cat.error()
1219 <<
"EvictManagedResources failed for device #"
1220 << _wcontext._card_id << D3DERRORSTRING(hr);
1226 _dxgsg->set_render_target ( );
1230 D3DCOLOR clear_color;
1232 flags = D3DCLEAR_TARGET;
1233 if (_fb_properties.get_depth_bits() > 0) {
1234 flags |= D3DCLEAR_ZBUFFER;
1236 clear_color = 0x00000000;
1237 hr = _wcontext._d3d_device-> Clear (0,
nullptr, flags, clear_color, 0.0f, 0);
1239 wdxdisplay9_cat.error()
1240 <<
"Clear failed for device"
1241 << D3DERRORSTRING(hr);
1243 hr = _wcontext._d3d_device-> Present (
nullptr,
nullptr,
nullptr,
nullptr);
1245 wdxdisplay9_cat.error()
1246 <<
"Present failed for device"
1247 << D3DERRORSTRING(hr);
1249 hr = _wcontext._d3d_device-> Clear (0,
nullptr, flags, clear_color, 0.0f, 0);
1251 wdxdisplay9_cat.error()
1252 <<
"Clear failed for device"
1253 << D3DERRORSTRING(hr);
1261int wdxGraphicsWindow9::
1262D3DFMT_to_DepthBits(D3DFORMAT fmt) {
1268 case D3DFMT_D24X4S4:
1279 wdxdisplay9_cat.debug()
1280 <<
"D3DFMT_DepthBits: unhandled D3DFMT!\n";
1289bool wdxGraphicsWindow9::
1290is_badvidmem_card(D3DADAPTER_IDENTIFIER9 *pDevID) {
1292 if (pDevID->VendorId == 0x00008086) {
This is a convenience class to specialize ConfigVariable as a boolean type.
get_value
Returns the variable's value.
size_t size() const
Returns the number of unique words in the variable.
get_value
Returns the variable's value.
A GraphicsDevice necessary for multi-window rendering in DX.
A GraphicsStateGuardian for rendering into DirectX9 contexts.
static void set_cg_device(LPDIRECT3DDEVICE9 cg_device)
Sets the global Cg device pointer.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
This class is the main interface to controlling the render process.
This is a base class for the various different classes that represent the result of a frame of render...
virtual void end_flip()
This function will be called within the draw thread after begin_flip() has been called on all windows...
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.
An object to create GraphicsOutputs that share a particular 3-D API.
Encapsulates all the communication with a particular instance of a given rendering backend.
get_pipe
Returns the graphics pipe on which this GSG was created.
void mark_new()
Marks the GSG as "new", so that the next call to reset_if_new() will be effective.
bool reset_if_new()
Calls reset() to initialize the GSG, but only if it hasn't been called yet.
get_unexposed_draw
See set_unexposed_draw().
get_properties
Returns the current properties of the window.
bool is_fullscreen() const
Returns true if the window has been opened as a fullscreen window, false otherwise.
virtual bool is_active() const
Returns true if the window is ready to be rendered into, false otherwise.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
A thread; that is, a lightweight process.
TypeHandle is the identifier used to differentiate C++ class types.
An abstract base class for glGraphicsWindow and dxGraphicsWindow (and, in general,...
A container for the various kinds of properties we might ask to have on a graphics window before we o...
int get_y_size() const
Returns size in pixels in the y dimension of the useful part of the window, not including decorations...
int get_x_size() const
Returns size in pixels in the x dimension of the useful part of the window, not including decorations...
int get_y_origin() const
Returns the y coordinate of the window's top-left corner, not including decorations.
set_size
Specifies the requested size of the window, in pixels.
int get_x_origin() const
Returns the x coordinate of the window's top-left corner, not including decorations.
This graphics pipe represents the interface for creating DirectX9 graphics windows.
bool special_check_fullscreen_resolution(DXScreenData &scrn, UINT x_size, UINT y_size)
overrides of the general estimator for known working cases
void search_for_valid_displaymode(DXScreenData &scrn, UINT RequestedX_Size, UINT RequestedY_Size, bool bWantZBuffer, bool bWantStencil, UINT *p_supported_screen_depths_mask, bool *pCouldntFindAnyValidZBuf, D3DFORMAT *pSuggestedPixFmt, bool bForce16bppZBuffer, bool bVerboseMode=false)
All ptr args are output parameters.
virtual bool begin_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread before beginning rendering for a given frame.
virtual int verify_window_sizes(int numsizes, int *dimen)
Determines which of the indicated window sizes are supported by available hardware (e....
virtual void end_flip()
This function will be called within the draw thread after begin_flip() has been called on all windows...
virtual void end_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread after rendering is completed for a given frame.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.