38 const std::string &name,
51 _depth_buffer_bpp = 0;
52 _awaiting_restore =
false;
53 ZeroMemory(&_wcontext,
sizeof(_wcontext));
60 ~wdxGraphicsWindow9() {
66 void 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;
232 void 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);
246 WinGraphicsWindow::close_window();
253 bool wdxGraphicsWindow9::
262 bool discard_device = always_discard_device;
268 DCAST_INTO_R(_dxgsg, _gsg,
false);
271 if (!choose_device()) {
278 resized_props.
set_size(_wcontext._display_mode.Width,
279 _wcontext._display_mode.Height);
280 _properties.add_properties(resized_props);
283 wdxdisplay9_cat.debug() <<
"_wcontext._window is " << _wcontext._window <<
"\n";
284 if (!WinGraphicsWindow::open_window()) {
287 _wcontext._window = _hWnd;
289 wdxdisplay9_cat.debug() <<
"_wcontext._window is " << _wcontext._window <<
"\n";
296 if (_dxgsg->
get_pipe()->get_device() ==
nullptr || discard_device) {
297 wdxdisplay9_cat.debug() <<
"device is null or fullscreen\n";
300 if (_dxgsg->
get_pipe()->get_device()) {
301 _dxgsg->dx_cleanup();
304 wdxdisplay9_cat.debug() <<
"device width " << _wcontext._display_mode.Width <<
"\n";
305 if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) {
306 wdxdisplay9_cat.error() <<
"Unable to create window with specified parameters.\n";
310 _dxgsg->
get_pipe()->make_device((
void*)(&_wcontext));
311 _dxgsg->copy_pres_reset(&_wcontext);
312 _dxgsg->create_swap_chain(&_wcontext);
318 wdxdisplay9_cat.debug() <<
"device is not null\n";
321 memcpy(&_wcontext, &dxdev->_Scrn,
sizeof(
DXScreenData));
324 _wcontext._presentation_params.hDeviceWindow = _wcontext._window = _hWnd;
325 _wcontext._presentation_params.BackBufferWidth = _wcontext._display_mode.Width = _properties.get_x_size();
326 _wcontext._presentation_params.BackBufferHeight = _wcontext._display_mode.Height = _properties.get_y_size();
328 wdxdisplay9_cat.debug() <<
"device width " << _wcontext._presentation_params.BackBufferWidth <<
"\n";
329 if (!_dxgsg->create_swap_chain(&_wcontext)) {
330 discard_device =
true;
333 init_resized_window();
337 wdxdisplay9_cat.debug() <<
"swapchain is " << _wcontext._swap_chain <<
"\n";
347 void wdxGraphicsWindow9::
348 reset_window(
bool swapchain) {
350 if (_wcontext._swap_chain) {
351 _dxgsg->create_swap_chain(&_wcontext);
352 wdxdisplay9_cat.debug() <<
"created swapchain " << _wcontext._swap_chain <<
"\n";
356 if (_wcontext._swap_chain) {
357 _dxgsg->release_swap_chain(&_wcontext);
358 wdxdisplay9_cat.debug() <<
"released swapchain " << _wcontext._swap_chain <<
"\n";
369 void wdxGraphicsWindow9::
375 if (_dxgsg !=
nullptr) {
376 _awaiting_restore =
true;
384 void wdxGraphicsWindow9::
387 WinGraphicsWindow::handle_reshape();
389 if (_dxgsg !=
nullptr && _dxgsg->_d3d_device !=
nullptr) {
395 if (_wcontext._presentation_params.BackBufferWidth != x_size ||
396 _wcontext._presentation_params.BackBufferHeight != y_size) {
397 bool resize_succeeded = reset_device_resize_window(x_size, y_size);
399 if (wdxdisplay9_cat.is_debug()) {
400 if (!resize_succeeded) {
401 wdxdisplay9_cat.debug()
402 <<
"windowed_resize to size: (" << x_size <<
", " << y_size
403 <<
") failed due to out-of-memory\n";
407 wdxdisplay9_cat.debug()
408 <<
"windowed_resize to origin: (" << x_origin <<
", "
409 << y_origin <<
"), size: (" << x_size
410 <<
", " << y_size <<
")\n";
420 bool wdxGraphicsWindow9::
421 do_fullscreen_resize(
int x_size,
int y_size) {
422 if (!WinGraphicsWindow::do_fullscreen_resize(x_size, y_size)) {
426 bool bCouldntFindValidZBuf;
428 bool bNeedZBuffer = (_wcontext._presentation_params.EnableAutoDepthStencil !=
false);
429 bool bNeedStencilBuffer = IS_STENCIL_FORMAT(_wcontext._presentation_params.AutoDepthStencilFormat);
432 DCAST_INTO_R(dxpipe, _pipe,
false);
434 bool bIsGoodMode =
false;
435 bool bResizeSucceeded =
false;
441 if (_wcontext._is_low_memory_card && (!((x_size == 640) && (y_size == 480)))) {
442 wdxdisplay9_cat.error() <<
"resize() failed: will not try to resize low vidmem device #" << _wcontext._card_id <<
" to non-640x480!\n";
443 return bResizeSucceeded;
450 bNeedZBuffer, bNeedStencilBuffer,
451 &_wcontext._supported_screen_depths_mask,
452 &bCouldntFindValidZBuf,
453 &pixFmt, dx_force_16bpp_zbuffer,
true);
454 bIsGoodMode = (pixFmt != D3DFMT_UNKNOWN);
457 wdxdisplay9_cat.error() <<
"resize() failed: "
458 << (bCouldntFindValidZBuf ?
"Couldnt find valid zbuffer format to go with FullScreen mode" :
"No supported FullScreen modes")
459 <<
" at " << x_size <<
"x" << y_size <<
" for device #" << _wcontext._card_id << endl;
460 return bResizeSucceeded;
465 _wcontext._display_mode.Width = x_size;
466 _wcontext._display_mode.Height = y_size;
467 _wcontext._display_mode.Format = pixFmt;
468 _wcontext._display_mode.RefreshRate = D3DPRESENT_RATE_DEFAULT;
472 bResizeSucceeded = reset_device_resize_window(x_size, y_size);
474 if (!bResizeSucceeded) {
475 wdxdisplay9_cat.error() <<
"resize() failed with OUT-OF-MEMORY error!\n";
477 if ((!IS_16BPP_DISPLAY_FORMAT(_wcontext._presentation_params.BackBufferFormat)) &&
478 (_wcontext._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) {
480 _wcontext._display_mode.Format = ((_wcontext._supported_screen_depths_mask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5);
481 dx_force_16bpp_zbuffer =
true;
482 if (wdxdisplay9_cat.info())
483 wdxdisplay9_cat.info() <<
"CreateDevice failed with out-of-vidmem, retrying w/16bpp buffers on device #" << _wcontext._card_id << endl;
485 bResizeSucceeded = reset_device_resize_window(x_size, y_size);
489 return bResizeSucceeded;
498 bool wdxGraphicsWindow9::
499 create_screen_buffers_and_device(
DXScreenData &display,
bool force_16bpp_zbuffer) {
501 DCAST_INTO_R(dxpipe, _pipe,
false);
503 DWORD dwRenderWidth = display._display_mode.Width;
504 DWORD dwRenderHeight = display._display_mode.Height;
505 DWORD dwBehaviorFlags = 0x0;
506 LPDIRECT3D9 _d3d9 = display._d3d9;
507 D3DCAPS9 *pD3DCaps = &display._d3dcaps;
508 D3DPRESENT_PARAMETERS* presentation_params = &display._presentation_params;
511 D3DDEVTYPE device_type;
514 adapter = display._card_id;
515 device_type = D3DDEVTYPE_HAL;
518 if (dx_use_nvperfhud) {
522 total_adapters = _d3d9 -> GetAdapterCount ( );
523 for (adapter_id = 0; adapter_id < total_adapters; adapter_id++) {
524 D3DADAPTER_IDENTIFIER9 identifier;
526 _d3d9 -> GetAdapterIdentifier (adapter_id, 0, &identifier);
527 if (strcmp (
"NVIDIA NVPerfHUD", identifier.Description) == 0) {
528 adapter = adapter_id;
529 device_type = D3DDEVTYPE_REF;
535 wdxdisplay9_cat.debug() <<
"Display Width " << dwRenderWidth <<
" and PresParam Width " << _wcontext._presentation_params.BackBufferWidth <<
"\n";
539 bool bWantStencil = (_fb_properties.get_stencil_bits() > 0);
540 bool bWantAlpha = (_fb_properties.get_alpha_bits() > 0);
542 PRINT_REFCNT(wdxdisplay9, _d3d9);
544 nassertr(_d3d9 !=
nullptr,
false);
545 nassertr(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION,
false);
547 bool do_sync = sync_video;
549 if (do_sync && !(pD3DCaps->Caps & D3DCAPS_READ_SCANLINE)) {
550 wdxdisplay9_cat.info()
551 <<
"HW doesnt support syncing to vertical refresh, ignoring sync-video\n";
555 presentation_params->BackBufferFormat = display._display_mode.Format;
559 if (!FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
560 D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8))) {
561 if (!FAILED(_d3d9->CheckDeviceType(adapter, device_type, display._display_mode.Format, D3DFMT_A8R8G8B8,
564 presentation_params->BackBufferFormat = D3DFMT_A8R8G8B8;
570 if (FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
571 D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) {
572 wdxdisplay9_cat.error() <<
"adapter #" << adapter <<
" CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
573 goto Fallback_to_16bpp_buffers;
576 if (FAILED(_d3d9->CheckDeviceType(adapter, device_type, display._display_mode.Format, presentation_params->BackBufferFormat,
578 wdxdisplay9_cat.error() <<
"adapter #" << adapter <<
" CheckDeviceType failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
579 goto Fallback_to_16bpp_buffers;
582 if (display._presentation_params.EnableAutoDepthStencil) {
583 if (!dxpipe->find_best_depth_format(display, display._display_mode,
584 &display._presentation_params.AutoDepthStencilFormat,
585 bWantStencil,
false)) {
586 wdxdisplay9_cat.error()
587 <<
"find_best_depth_format failed in CreateScreenBuffers for device #"
589 goto Fallback_to_16bpp_buffers;
591 _depth_buffer_bpp = D3DFMT_to_DepthBits(display._presentation_params.AutoDepthStencilFormat);
593 _depth_buffer_bpp = 0;
598 int supported_multisamples = 0;
599 if (framebuffer_multisample.
get_value()){
600 supported_multisamples = multisamples.
get_value();
603 while (supported_multisamples > 1){
605 hr = _d3d9->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, display._display_mode.Format,
606 is_fullscreen(), D3DMULTISAMPLE_TYPE(supported_multisamples),
nullptr);
608 supported_multisamples--;
612 if (display._presentation_params.EnableAutoDepthStencil) {
613 hr = _d3d9->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, display._presentation_params.AutoDepthStencilFormat,
614 is_fullscreen(), D3DMULTISAMPLE_TYPE(supported_multisamples),
nullptr);
616 supported_multisamples--;
621 presentation_params->MultiSampleType = D3DMULTISAMPLE_TYPE(supported_multisamples);
623 if (wdxdisplay9_cat.is_info())
624 wdxdisplay9_cat.info() <<
"adapter #" << adapter <<
" using multisample antialiasing level: " << supported_multisamples <<
625 ". Requested level was: " << multisamples.
get_value() << endl;
629 presentation_params->BackBufferCount = 1;
630 presentation_params->Flags = 0x0;
631 presentation_params->hDeviceWindow = display._window;
632 presentation_params->BackBufferWidth = display._display_mode.Width;
633 presentation_params->BackBufferHeight = display._display_mode.Height;
635 if (_wcontext._is_tnl_device) {
636 dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
644 dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
647 if (dx_preserve_fpu_state)
648 dwBehaviorFlags |= D3DCREATE_FPU_PRESERVE;
655 if (!SetForegroundWindow(display._window)) {
656 wdxdisplay9_cat.warning() <<
"SetForegroundWindow() failed!\n";
659 if (dx_use_multithread) {
660 dwBehaviorFlags |= D3DCREATE_MULTITHREADED;
662 if (dx_use_puredevice) {
663 dwBehaviorFlags |= D3DCREATE_PUREDEVICE;
666 if (dx_disable_driver_management) {
667 dwBehaviorFlags |= D3DCREATE_DISABLE_DRIVER_MANAGEMENT;
669 if (dx_disable_driver_management_ex) {
670 dwBehaviorFlags |= D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX;
676 presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD;
677 presentation_params->PresentationInterval = (do_sync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE);
678 presentation_params->FullScreen_RefreshRateInHz = display._display_mode.RefreshRate;
682 hr = _d3d9->CreateDevice(adapter, device_type, _hWnd,
683 dwBehaviorFlags, presentation_params, &display._d3d_device);
686 wdxdisplay9_cat.fatal() <<
"D3D CreateDevice failed for adapter #" << adapter <<
", " << D3DERRORSTRING(hr);
688 if (hr == D3DERR_OUTOFVIDEOMEMORY)
689 goto Fallback_to_16bpp_buffers;
694 SetRect(&view_rect, 0, 0, dwRenderWidth, dwRenderHeight);
699 D3DDISPLAYMODE dispmode;
700 hr = display._d3d9->GetAdapterDisplayMode(adapter, &dispmode);
703 wdxdisplay9_cat.fatal()
704 <<
"GetAdapterDisplayMode failed" << D3DERRORSTRING(hr);
708 if (dispmode.Format == D3DFMT_P8) {
709 wdxdisplay9_cat.fatal()
710 <<
"Can't run windowed in an 8-bit or less display mode" << endl;
719 presentation_params->PresentationInterval = 0;
722 presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD;
723 if (do_sync ==
false) {
724 presentation_params->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
748 hr = _d3d9->CreateDevice(adapter, device_type, _hWnd,
749 dwBehaviorFlags, presentation_params, &display._d3d_device);
752 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferWidth : " << presentation_params->BackBufferWidth << endl;
753 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferHeight : " << presentation_params->BackBufferHeight << endl;
754 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferFormat : " << presentation_params->BackBufferFormat << endl;
755 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferCount : " << presentation_params->BackBufferCount << endl;
756 wdxdisplay9_cat.warning() <<
"D3D CreateDevice failed for adapter #" << adapter << D3DERRORSTRING(hr);
757 goto Fallback_to_16bpp_buffers;
763 PRINT_REFCNT(wdxdisplay9, _wcontext._d3d_device);
765 if (presentation_params->EnableAutoDepthStencil) {
771 switch (presentation_params->AutoDepthStencilFormat)
773 case D3DFMT_D16_LOCKABLE:
794 case D3DFMT_D32F_LOCKABLE:
805 wdxdisplay9_cat.error() <<
"unknown depth stencil format " << presentation_params->AutoDepthStencilFormat;
809 _fb_properties.set_stencil_bits(stencil_bits);
810 _fb_properties.set_depth_bits(depth_bits);
812 _fb_properties.set_depth_bits(0);
813 _fb_properties.set_stencil_bits(0);
816 init_resized_window();
820 Fallback_to_16bpp_buffers:
821 if ((!IS_16BPP_DISPLAY_FORMAT(presentation_params->BackBufferFormat)) &&
822 (display._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) {
825 display._display_mode.Format = ((display._supported_screen_depths_mask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5);
827 if (wdxdisplay9_cat.info()) {
828 wdxdisplay9_cat.info()
829 <<
"CreateDevice failed with out-of-vidmem or invalid BackBufferFormat, retrying w/16bpp buffers on adapter #"
832 return create_screen_buffers_and_device(display,
true);
835 }
else if (!((dwRenderWidth == 640)&&(dwRenderHeight == 480))) {
836 if (wdxdisplay9_cat.info())
837 wdxdisplay9_cat.info() <<
"CreateDevice failed w/out-of-vidmem, retrying at 640x480 w/16bpp buffers on adapter #" << adapter << endl;
839 display._display_mode.Width = 640;
840 display._display_mode.Height = 480;
841 return create_screen_buffers_and_device(display,
true);
845 wdxdisplay9_cat.fatal()
846 <<
"Can't create any screen buffers, bailing out.\n";
857 bool wdxGraphicsWindow9::
862 DCAST_INTO_R(dxpipe, _pipe,
false);
864 int num_adapters = dxpipe->__d3d9->GetAdapterCount();
865 DXDeviceInfoVec device_infos;
867 for (
int i = 0; i < num_adapters; i++) {
868 D3DADAPTER_IDENTIFIER9 adapter_info;
869 ZeroMemory(&adapter_info,
sizeof(D3DADAPTER_IDENTIFIER9));
870 hr = dxpipe->__d3d9->GetAdapterIdentifier(i, 0, &adapter_info);
872 wdxdisplay9_cat.fatal()
873 <<
"D3D GetAdapterID(" << i <<
") failed: "
874 << D3DERRORSTRING(hr) << endl;
878 LARGE_INTEGER *DrvVer = &adapter_info.DriverVersion;
880 wdxdisplay9_cat.info()
881 <<
"D3D9 Adapter[" << i <<
"]: " << adapter_info.Description
882 <<
", Driver: " << adapter_info.Driver <<
", DriverVersion: ("
883 << HIWORD(DrvVer->HighPart) <<
"." << LOWORD(DrvVer->HighPart) <<
"."
884 << HIWORD(DrvVer->LowPart) <<
"." << LOWORD(DrvVer->LowPart)
885 <<
")\nVendorID: 0x" << std::hex << adapter_info.VendorId
886 <<
" DeviceID: 0x" << adapter_info.DeviceId
887 <<
" SubsysID: 0x" << adapter_info.SubSysId
888 <<
" Revision: 0x" << adapter_info.Revision << std::dec << endl;
890 HMONITOR _monitor = dxpipe->__d3d9->GetAdapterMonitor(i);
891 if (_monitor ==
nullptr) {
892 wdxdisplay9_cat.info()
893 <<
"D3D9 Adapter[" << i <<
"]: seems to be disabled, skipping it\n";
897 DXDeviceInfo devinfo;
898 ZeroMemory(&devinfo,
sizeof(devinfo));
899 memcpy(&devinfo.guidDeviceIdentifier, &adapter_info.DeviceIdentifier,
901 strncpy(devinfo.szDescription, adapter_info.Description,
902 MAX_DEVICE_IDENTIFIER_STRING);
903 strncpy(devinfo.szDriver, adapter_info.Driver,
904 MAX_DEVICE_IDENTIFIER_STRING);
905 devinfo.VendorID = adapter_info.VendorId;
906 devinfo.DeviceID = adapter_info.DeviceId;
907 devinfo._driver_version = adapter_info.DriverVersion;
908 devinfo._monitor = _monitor;
911 device_infos.push_back(devinfo);
914 if (device_infos.empty()) {
915 wdxdisplay9_cat.error()
916 <<
"No available D3D9 devices found.\n";
922 num_adapters = (int)device_infos.size();
926 int adapter_num = D3DADAPTER_DEFAULT;
930 if (dx_preferred_device_id != -1) {
931 if (dx_preferred_device_id < 0 || dx_preferred_device_id >= num_adapters) {
932 wdxdisplay9_cat.error()
933 <<
"invalid 'dx-preferred-device-id', valid values are 0-"
934 << num_adapters - 1 <<
", using default adapter instead.\n";
936 adapter_num = dx_preferred_device_id;
941 if (adapter_num >= 0 && adapter_num < (
int)device_infos.size()) {
942 if (consider_device(dxpipe, &device_infos[adapter_num])) {
943 wdxdisplay9_cat.info()
944 <<
"Selected device " << adapter_num <<
" (of "
945 << device_infos.
size() <<
", zero-based)\n";
948 wdxdisplay9_cat.info()
949 <<
"Could not select device " << adapter_num <<
"\n";
953 for (UINT devnum = 0; devnum < device_infos.size(); ++devnum) {
954 if (consider_device(dxpipe, &device_infos[devnum])) {
955 wdxdisplay9_cat.info()
956 <<
"Chose device " << devnum <<
" (of "
957 << device_infos.size() <<
", zero-based): first one that works.\n";
962 wdxdisplay9_cat.error() <<
"no usable display devices.\n";
970 bool wdxGraphicsWindow9::
973 nassertr(dxpipe !=
nullptr,
false);
975 DWORD dwRenderWidth = properties.
get_x_size();
976 DWORD dwRenderHeight = properties.
get_y_size();
978 LPDIRECT3D9 _d3d9 = dxpipe->__d3d9;
980 nassertr(_dxgsg !=
nullptr,
false);
981 _wcontext._d3d9 = _d3d9;
982 _wcontext._card_id = device_info->cardID;
984 bool bWantStencil = (_fb_properties.get_stencil_bits() > 0);
986 hr = _d3d9->GetAdapterIdentifier(device_info->cardID, 0,
987 &_wcontext._dx_device_id);
989 wdxdisplay9_cat.error()
990 <<
"D3D GetAdapterID failed" << D3DERRORSTRING(hr);
995 hr = _d3d9->GetDeviceCaps(device_info->cardID, D3DDEVTYPE_HAL, &_d3dcaps);
997 if ((hr == D3DERR_INVALIDDEVICE)||(hr == D3DERR_NOTAVAILABLE)) {
998 wdxdisplay9_cat.error()
999 <<
"No DirectX 9 D3D-capable 3D hardware detected for device # "
1000 << device_info->cardID <<
" (" << device_info->szDescription
1003 wdxdisplay9_cat.error()
1004 <<
"GetDeviceCaps failed: " << D3DERRORSTRING(hr) << endl;
1010 memcpy(&_wcontext._d3dcaps, &_d3dcaps,
sizeof(D3DCAPS9));
1011 _wcontext._card_id = device_info->cardID;
1013 _wcontext._max_available_video_memory = UNKNOWN_VIDMEM_SIZE;
1014 _wcontext._is_low_memory_card =
false;
1019 if (_d3dcaps.MaxStreams == 0) {
1020 if (wdxdisplay9_cat.is_debug()) {
1021 wdxdisplay9_cat.debug()
1022 <<
"checking vidmem size\n";
1028 for (IDnum = 0; IDnum < dxpipe->_card_ids.size(); IDnum++) {
1029 if ((device_info->VendorID == dxpipe->_card_ids[IDnum].VendorID) &&
1030 (device_info->DeviceID == dxpipe->_card_ids[IDnum].DeviceID) &&
1031 (device_info->_monitor == dxpipe->_card_ids[IDnum]._monitor))
1035 if (IDnum < dxpipe->_card_ids.size()) {
1036 _wcontext._max_available_video_memory = dxpipe->_card_ids[IDnum]._max_available_video_memory;
1037 _wcontext._is_low_memory_card = dxpipe->_card_ids[IDnum]._is_low_memory_card;
1039 wdxdisplay9_cat.error()
1040 <<
"Error: couldnt find a CardID match in DX7 info, assuming card is not a lowmem card\n";
1044 if ((bWantStencil) && (_d3dcaps.StencilCaps == 0x0)) {
1045 wdxdisplay9_cat.fatal()
1046 <<
"Stencil ability requested, but device #" << device_info->cardID
1047 <<
" (" << _wcontext._dx_device_id.Description
1048 <<
"), has no stencil capability!\n";
1055 _wcontext._is_tnl_device =
1056 ((_d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0);
1057 _wcontext._can_use_hw_vertex_shaders =
1058 (_d3dcaps.VertexShaderVersion >= D3DVS_VERSION(1, 0));
1059 _wcontext._can_use_pixel_shaders =
1060 (_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(1, 0));
1063 ((!(_d3dcaps.RasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )) &&
1064 (_fb_properties.get_depth_bits() > 0));
1066 _wcontext._presentation_params.EnableAutoDepthStencil = bNeedZBuffer;
1068 D3DFORMAT pixFmt = D3DFMT_UNKNOWN;
1071 bool bCouldntFindValidZBuf;
1074 bNeedZBuffer, bWantStencil,
1075 &_wcontext._supported_screen_depths_mask,
1076 &bCouldntFindValidZBuf,
1077 &pixFmt, dx_force_16bpp_zbuffer,
true);
1082 if (pixFmt == D3DFMT_UNKNOWN) {
1083 wdxdisplay9_cat.error()
1084 << (bCouldntFindValidZBuf ?
"Couldnt find valid zbuffer format to go with FullScreen mode" :
"No supported FullScreen modes")
1085 <<
" at " << dwRenderWidth <<
"x" << dwRenderHeight <<
" for device #" << _wcontext._card_id << endl;
1091 D3DDISPLAYMODE dispmode;
1092 hr = _d3d9->GetAdapterDisplayMode(device_info->cardID, &dispmode);
1094 wdxdisplay9_cat.error()
1095 <<
"GetAdapterDisplayMode(" << device_info->cardID
1096 <<
") failed" << D3DERRORSTRING(hr);
1099 pixFmt = dispmode.Format;
1102 _wcontext._display_mode.Width = dwRenderWidth;
1103 _wcontext._display_mode.Height = dwRenderHeight;
1104 _wcontext._display_mode.Format = pixFmt;
1105 _wcontext._display_mode.RefreshRate = D3DPRESENT_RATE_DEFAULT;
1106 _wcontext._monitor = device_info->_monitor;
1108 if (strcmp(device_info->szDriver,
"igdumd32.dll") == 0 &&
1109 device_info->_driver_version.QuadPart <= 0x0007000e000affffLL &&
1110 dx_intel_compressed_texture_bug) {
1113 _wcontext._intel_compressed_texture_bug =
true;
1123 bool wdxGraphicsWindow9::
1124 reset_device_resize_window(UINT new_xsize, UINT new_ysize) {
1128 D3DPRESENT_PARAMETERS d3dpp;
1129 memcpy(&d3dpp, &_wcontext._presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
1130 _wcontext._presentation_params.BackBufferWidth = new_xsize;
1131 _wcontext._presentation_params.BackBufferHeight = new_ysize;
1133 HRESULT hr = _dxgsg->reset_d3d_device(&_wcontext._presentation_params, &screen);
1137 wdxdisplay9_cat.error()
1138 <<
"reset_device_resize_window Reset() failed" << D3DERRORSTRING(hr);
1139 if (hr == D3DERR_OUTOFVIDEOMEMORY) {
1140 memcpy(&_wcontext._presentation_params, &d3dpp,
sizeof(D3DPRESENT_PARAMETERS));
1141 hr = _dxgsg->reset_d3d_device(&_wcontext._presentation_params, &screen);
1143 wdxdisplay9_cat.error()
1144 <<
"reset_device_resize_window Reset() failed OutOfVidmem, then failed again doing Reset w/original params:" << D3DERRORSTRING(hr);
1145 throw_event(
"panda3d-render-error");
1149 if (wdxdisplay9_cat.is_info()) {
1150 wdxdisplay9_cat.info()
1151 <<
"reset of original size (" << _wcontext._presentation_params.BackBufferWidth
1152 <<
", " << _wcontext._presentation_params.BackBufferHeight <<
") succeeded\n";
1156 wdxdisplay9_cat.fatal()
1157 <<
"Can't reset device, bailing out.\n";
1158 throw_event(
"panda3d-render-error");
1165 _wcontext._swap_chain = screen->_swap_chain;
1167 wdxdisplay9_cat.debug() <<
"swapchain is " << _wcontext._swap_chain <<
"\n";
1169 init_resized_window();
1180 void wdxGraphicsWindow9::
1181 init_resized_window() {
1184 DWORD newWidth = _wcontext._presentation_params.BackBufferWidth;
1185 DWORD newHeight = _wcontext._presentation_params.BackBufferHeight;
1187 nassertv((newWidth != 0) && (newHeight != 0));
1188 nassertv(_wcontext._window !=
nullptr);
1190 if (_wcontext._presentation_params.Windowed) {
1197 GetClientRect(_wcontext._window, &client_rect);
1198 ul.x = client_rect.left;
1199 ul.y = client_rect.top;
1200 lr.x = client_rect.right;
1201 lr.y = client_rect.bottom;
1202 ClientToScreen(_wcontext._window, &ul);
1203 ClientToScreen(_wcontext._window, &lr);
1204 client_rect.left = ul.x;
1205 client_rect.top = ul.y;
1206 client_rect.right = lr.x;
1207 client_rect.bottom = lr.y;
1211 nassertv(_wcontext._window !=
nullptr);
1215 hr = _wcontext._d3d_device->EvictManagedResources ( );
1217 wdxdisplay9_cat.error()
1218 <<
"EvictManagedResources failed for device #"
1219 << _wcontext._card_id << D3DERRORSTRING(hr);
1225 _dxgsg->set_render_target ( );
1229 D3DCOLOR clear_color;
1231 flags = D3DCLEAR_TARGET;
1232 if (_fb_properties.get_depth_bits() > 0) {
1233 flags |= D3DCLEAR_ZBUFFER;
1235 clear_color = 0x00000000;
1236 hr = _wcontext._d3d_device-> Clear (0,
nullptr, flags, clear_color, 0.0f, 0);
1238 wdxdisplay9_cat.error()
1239 <<
"Clear failed for device"
1240 << D3DERRORSTRING(hr);
1242 hr = _wcontext._d3d_device-> Present (
nullptr,
nullptr,
nullptr,
nullptr);
1244 wdxdisplay9_cat.error()
1245 <<
"Present failed for device"
1246 << D3DERRORSTRING(hr);
1248 hr = _wcontext._d3d_device-> Clear (0,
nullptr, flags, clear_color, 0.0f, 0);
1250 wdxdisplay9_cat.error()
1251 <<
"Clear failed for device"
1252 << D3DERRORSTRING(hr);
1260 int wdxGraphicsWindow9::
1261 D3DFMT_to_DepthBits(D3DFORMAT fmt) {
1267 case D3DFMT_D24X4S4:
1278 wdxdisplay9_cat.debug()
1279 <<
"D3DFMT_DepthBits: unhandled D3DFMT!\n";
1288 bool wdxGraphicsWindow9::
1289 is_badvidmem_card(D3DADAPTER_IDENTIFIER9 *pDevID) {
1291 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.
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.