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) {
virtual void end_flip()
This function will be called within the draw thread after begin_flip() has been called on all windows...
A GraphicsStateGuardian for rendering into DirectX9 contexts.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_pipe
Returns the graphics pipe on which this GSG was created.
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.
set_size
Specifies the requested size of the window, in pixels.
virtual void end_flip()
This function will be called within the draw thread after begin_flip() has been called on all windows...
This is a convenience class to specialize ConfigVariable as a boolean type.
bool reset_if_new()
Calls reset() to initialize the GSG, but only if it hasn't been called yet.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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 lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_y_origin() const
Returns the y coordinate of the window's top-left corner, not including decorations.
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 is_active() const
Returns true if the window is ready to be rendered into, false otherwise.
get_value
Returns the variable's value.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for the various kinds of properties we might ask to have on a graphics window before we o...
An abstract base class for glGraphicsWindow and dxGraphicsWindow (and, in general,...
bool special_check_fullscreen_resolution(DXScreenData &scrn, UINT x_size, UINT y_size)
overrides of the general estimator for known working cases
static void set_cg_device(LPDIRECT3DDEVICE9 cg_device)
Sets the global Cg device pointer.
An object to create GraphicsOutputs that share a particular 3-D API.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a base class for the various different classes that represent the result of a frame of render...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_unexposed_draw
See set_unexposed_draw().
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_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread after rendering is completed for a given frame.
A thread; that is, a lightweight process.
get_properties
Returns the current properties of the window.
Encapsulates all the communication with a particular instance of a given rendering backend.
This graphics pipe represents the interface for creating DirectX9 graphics windows.
This class is the main interface to controlling the render process.
int get_y_size() const
Returns size in pixels in the y dimension of the useful part of the window, not including decorations...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_x_size() const
Returns size in pixels in the x dimension of the useful part of the window, not including decorations...
TypeHandle is the identifier used to differentiate C++ class types.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
bool is_fullscreen() const
Returns true if the window has been opened as a fullscreen window, false otherwise.
int get_x_origin() const
Returns the x coordinate of the window's top-left corner, not including decorations.
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.