15 #include "wdxGraphicsPipe9.h"
16 #include "wdxGraphicsWindow9.h"
17 #include "config_dxgsg9.h"
18 #include "config_display.h"
19 #include "keyboardButton.h"
20 #include "mouseButton.h"
21 #include "throw_event.h"
22 #include "pStatTimer.h"
52 _depth_buffer_bpp = 0;
53 _awaiting_restore =
false;
54 ZeroMemory(&_wcontext,
sizeof(_wcontext));
63 ~wdxGraphicsWindow9() {
71 void wdxGraphicsWindow9::
75 _dxgsg->set_context(&_wcontext);
95 begin_frame_spam(mode);
101 if (wdxdisplay9_cat.is_spam()) {
102 wdxdisplay9_cat.spam()
103 <<
"Not drawing " <<
this <<
": unexposed.\n";
108 if (_awaiting_restore) {
111 if (!_dxgsg->check_cooperative_level()) {
115 _awaiting_restore =
false;
116 init_resized_window();
121 if (mode == FM_render) {
122 clear_cube_map_selection();
126 bool return_val = _gsg->begin_frame(current_thread);
127 _dxgsg->set_render_target();
140 end_frame_spam(mode);
143 if (mode == FM_render) {
147 _gsg->end_frame(current_thread);
149 if (mode == FM_render) {
151 clear_cube_map_selection();
168 _dxgsg->show_frame();
190 nassertr(IS_VALID_PTR(_dxgsg), 0);
192 int num_valid_modes = 0;
195 DCAST_INTO_R(dxpipe, _pipe, 0);
200 int *pCurDim = dimen;
202 for (
int i = 0; i < numsizes; i++, pCurDim += 2) {
203 int x_size = pCurDim[0];
204 int y_size = pCurDim[1];
206 bool bIsGoodMode =
false;
207 bool CouldntFindAnyValidZBuf;
208 D3DFORMAT newPixFmt = D3DFMT_UNKNOWN;
215 if (_wcontext._is_low_memory_card) {
216 bIsGoodMode = ((x_size == 640) && (y_size == 480));
219 (_wcontext, x_size, y_size, _wcontext._presentation_params.EnableAutoDepthStencil !=
false,
220 IS_STENCIL_FORMAT(_wcontext._presentation_params.AutoDepthStencilFormat),
221 &_wcontext._supported_screen_depths_mask,
222 &CouldntFindAnyValidZBuf, &newPixFmt, dx_force_16bpp_zbuffer,
true);
223 bIsGoodMode = (newPixFmt != D3DFMT_UNKNOWN);
235 if (wdxdisplay9_cat.is_spam()) {
236 wdxdisplay9_cat.spam()
237 <<
"Fullscrn Mode (" << x_size <<
", " << y_size <<
")\t"
238 << (bIsGoodMode ?
"V" :
"Inv") <<
"alid\n";
242 return num_valid_modes;
252 void wdxGraphicsWindow9::
254 if (wdxdisplay9_cat.is_debug()) {
255 wdxdisplay9_cat.debug()
256 <<
"wdxGraphicsWindow9::close_window() " <<
this <<
"\n";
265 _dxgsg->release_swap_chain(&_wcontext);
266 WinGraphicsWindow::close_window();
276 bool wdxGraphicsWindow9::
286 bool discard_device = always_discard_device;
292 DCAST_INTO_R(_dxgsg, _gsg,
false);
295 if (!choose_device()) {
303 resized_props.
set_size(_wcontext._display_mode.Width,
304 _wcontext._display_mode.Height);
305 _properties.add_properties(resized_props);
308 wdxdisplay9_cat.debug() <<
"_wcontext._window is " << _wcontext._window <<
"\n";
309 if (!WinGraphicsWindow::open_window()) {
312 _wcontext._window = _hWnd;
314 wdxdisplay9_cat.debug() <<
"_wcontext._window is " << _wcontext._window <<
"\n";
322 wdxdisplay9_cat.debug() <<
"device is null or fullscreen\n";
326 _dxgsg->dx_cleanup();
329 wdxdisplay9_cat.debug() <<
"device width " << _wcontext._display_mode.Width <<
"\n";
330 if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) {
331 wdxdisplay9_cat.error() <<
"Unable to create window with specified parameters.\n";
335 _dxgsg->
get_pipe()->make_device((
void*)(&_wcontext));
336 _dxgsg->copy_pres_reset(&_wcontext);
337 _dxgsg->create_swap_chain(&_wcontext);
343 wdxdisplay9_cat.debug() <<
"device is not null\n";
346 memcpy(&_wcontext, &dxdev->_Scrn,
sizeof(
DXScreenData));
349 _wcontext._presentation_params.hDeviceWindow = _wcontext._window = _hWnd;
350 _wcontext._presentation_params.BackBufferWidth = _wcontext._display_mode.Width = _properties.get_x_size();
351 _wcontext._presentation_params.BackBufferHeight = _wcontext._display_mode.Height = _properties.get_y_size();
353 wdxdisplay9_cat.debug() <<
"device width " << _wcontext._presentation_params.BackBufferWidth <<
"\n";
354 if (!_dxgsg->create_swap_chain(&_wcontext)) {
355 discard_device =
true;
358 init_resized_window();
362 wdxdisplay9_cat.debug() <<
"swapchain is " << _wcontext._swap_chain <<
"\n";
375 void wdxGraphicsWindow9::
376 reset_window(
bool swapchain) {
378 if (_wcontext._swap_chain) {
379 _dxgsg->create_swap_chain(&_wcontext);
380 wdxdisplay9_cat.debug() <<
"created swapchain " << _wcontext._swap_chain <<
"\n";
384 if (_wcontext._swap_chain) {
385 _dxgsg->release_swap_chain(&_wcontext);
386 wdxdisplay9_cat.debug() <<
"released swapchain " << _wcontext._swap_chain <<
"\n";
400 void wdxGraphicsWindow9::
407 if (_dxgsg != NULL) {
408 _awaiting_restore =
true;
419 void wdxGraphicsWindow9::
422 WinGraphicsWindow::handle_reshape();
424 if (_dxgsg != NULL && _dxgsg->_d3d_device != NULL) {
430 if (_wcontext._presentation_params.BackBufferWidth != x_size ||
431 _wcontext._presentation_params.BackBufferHeight != y_size) {
432 bool resize_succeeded = reset_device_resize_window(x_size, y_size);
434 if (wdxdisplay9_cat.is_debug()) {
435 if (!resize_succeeded) {
436 wdxdisplay9_cat.debug()
437 <<
"windowed_resize to size: (" << x_size <<
", " << y_size
438 <<
") failed due to out-of-memory\n";
442 wdxdisplay9_cat.debug()
443 <<
"windowed_resize to origin: (" << x_origin <<
", "
444 << y_origin <<
"), size: (" << x_size
445 <<
", " << y_size <<
")\n";
458 bool wdxGraphicsWindow9::
459 do_fullscreen_resize(
int x_size,
int y_size) {
460 if (!WinGraphicsWindow::do_fullscreen_resize(x_size, y_size)) {
464 bool bCouldntFindValidZBuf;
466 bool bNeedZBuffer = (_wcontext._presentation_params.EnableAutoDepthStencil !=
false);
467 bool bNeedStencilBuffer = IS_STENCIL_FORMAT(_wcontext._presentation_params.AutoDepthStencilFormat);
470 DCAST_INTO_R(dxpipe, _pipe,
false);
472 bool bIsGoodMode =
false;
473 bool bResizeSucceeded =
false;
478 if (_wcontext._is_low_memory_card && (!((x_size == 640) && (y_size == 480)))) {
479 wdxdisplay9_cat.error() <<
"resize() failed: will not try to resize low vidmem device #" << _wcontext._card_id <<
" to non-640x480!\n";
480 return bResizeSucceeded;
487 bNeedZBuffer, bNeedStencilBuffer,
488 &_wcontext._supported_screen_depths_mask,
489 &bCouldntFindValidZBuf,
490 &pixFmt, dx_force_16bpp_zbuffer,
true);
491 bIsGoodMode = (pixFmt != D3DFMT_UNKNOWN);
494 wdxdisplay9_cat.error() <<
"resize() failed: "
495 << (bCouldntFindValidZBuf ?
"Couldnt find valid zbuffer format to go with FullScreen mode" :
"No supported FullScreen modes")
496 <<
" at " << x_size <<
"x" << y_size <<
" for device #" << _wcontext._card_id << endl;
497 return bResizeSucceeded;
502 _wcontext._display_mode.Width = x_size;
503 _wcontext._display_mode.Height = y_size;
504 _wcontext._display_mode.Format = pixFmt;
505 _wcontext._display_mode.RefreshRate = D3DPRESENT_RATE_DEFAULT;
508 bResizeSucceeded = reset_device_resize_window(x_size, y_size);
510 if (!bResizeSucceeded) {
511 wdxdisplay9_cat.error() <<
"resize() failed with OUT-OF-MEMORY error!\n";
513 if ((!IS_16BPP_DISPLAY_FORMAT(_wcontext._presentation_params.BackBufferFormat)) &&
514 (_wcontext._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) {
516 _wcontext._display_mode.Format = ((_wcontext._supported_screen_depths_mask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5);
517 dx_force_16bpp_zbuffer =
true;
518 if (wdxdisplay9_cat.info())
519 wdxdisplay9_cat.info() <<
"CreateDevice failed with out-of-vidmem, retrying w/16bpp buffers on device #" << _wcontext._card_id << endl;
521 bResizeSucceeded = reset_device_resize_window(x_size, y_size);
525 return bResizeSucceeded;
536 bool wdxGraphicsWindow9::
537 create_screen_buffers_and_device(
DXScreenData &display,
bool force_16bpp_zbuffer) {
539 DCAST_INTO_R(dxpipe, _pipe,
false);
541 DWORD dwRenderWidth = display._display_mode.Width;
542 DWORD dwRenderHeight = display._display_mode.Height;
543 DWORD dwBehaviorFlags = 0x0;
544 LPDIRECT3D9 _d3d9 = display._d3d9;
545 D3DCAPS9 *pD3DCaps = &display._d3dcaps;
546 D3DPRESENT_PARAMETERS* presentation_params = &display._presentation_params;
549 D3DDEVTYPE device_type;
552 adapter = display._card_id;
553 device_type = D3DDEVTYPE_HAL;
556 if (dx_use_nvperfhud) {
560 total_adapters = _d3d9 -> GetAdapterCount ( );
561 for (adapter_id = 0; adapter_id < total_adapters; adapter_id++) {
562 D3DADAPTER_IDENTIFIER9 identifier;
564 _d3d9 -> GetAdapterIdentifier (adapter_id, 0, &identifier);
565 if (strcmp (
"NVIDIA NVPerfHUD", identifier.Description) == 0) {
566 adapter = adapter_id;
567 device_type = D3DDEVTYPE_REF;
573 wdxdisplay9_cat.debug() <<
"Display Width " << dwRenderWidth <<
" and PresParam Width " << _wcontext._presentation_params.BackBufferWidth <<
"\n";
577 bool bWantStencil = (_fb_properties.get_stencil_bits() > 0);
578 bool bWantAlpha = (_fb_properties.get_alpha_bits() > 0);
580 PRINT_REFCNT(wdxdisplay9, _d3d9);
582 nassertr(_d3d9 != NULL,
false);
583 nassertr(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION,
false);
585 bool do_sync = sync_video;
587 if (do_sync && !(pD3DCaps->Caps & D3DCAPS_READ_SCANLINE)) {
588 wdxdisplay9_cat.info()
589 <<
"HW doesnt support syncing to vertical refresh, ignoring sync-video\n";
593 presentation_params->BackBufferFormat = display._display_mode.Format;
597 if (!FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
598 D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8))) {
599 if (!FAILED(_d3d9->CheckDeviceType(adapter, device_type, display._display_mode.Format, D3DFMT_A8R8G8B8,
602 presentation_params->BackBufferFormat = D3DFMT_A8R8G8B8;
609 if (FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
610 D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) {
611 wdxdisplay9_cat.error() <<
"adapter #" << adapter <<
" CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
612 goto Fallback_to_16bpp_buffers;
615 if (FAILED(_d3d9->CheckDeviceType(adapter, device_type, display._display_mode.Format, presentation_params->BackBufferFormat,
617 wdxdisplay9_cat.error() <<
"adapter #" << adapter <<
" CheckDeviceType failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
618 goto Fallback_to_16bpp_buffers;
621 if (display._presentation_params.EnableAutoDepthStencil) {
622 if (!dxpipe->find_best_depth_format(display, display._display_mode,
623 &display._presentation_params.AutoDepthStencilFormat,
624 bWantStencil,
false)) {
625 wdxdisplay9_cat.error()
626 <<
"find_best_depth_format failed in CreateScreenBuffers for device #"
628 goto Fallback_to_16bpp_buffers;
630 _depth_buffer_bpp = D3DFMT_to_DepthBits(display._presentation_params.AutoDepthStencilFormat);
632 _depth_buffer_bpp = 0;
637 int supported_multisamples = 0;
638 if (framebuffer_multisample.
get_value()){
639 supported_multisamples = multisamples.
get_value();
642 while (supported_multisamples > 1){
644 hr = _d3d9->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, display._display_mode.Format,
645 is_fullscreen(), D3DMULTISAMPLE_TYPE(supported_multisamples), NULL);
647 supported_multisamples--;
651 if (display._presentation_params.EnableAutoDepthStencil) {
652 hr = _d3d9->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, display._presentation_params.AutoDepthStencilFormat,
653 is_fullscreen(), D3DMULTISAMPLE_TYPE(supported_multisamples), NULL);
655 supported_multisamples--;
660 presentation_params->MultiSampleType = D3DMULTISAMPLE_TYPE(supported_multisamples);
662 if (wdxdisplay9_cat.is_info())
663 wdxdisplay9_cat.info() <<
"adapter #" << adapter <<
" using multisample antialiasing level: " << supported_multisamples <<
664 ". Requested level was: " << multisamples.
get_value() << endl;
668 presentation_params->BackBufferCount = 1;
669 presentation_params->Flags = 0x0;
670 presentation_params->hDeviceWindow = display._window;
671 presentation_params->BackBufferWidth = display._display_mode.Width;
672 presentation_params->BackBufferHeight = display._display_mode.Height;
674 if (_wcontext._is_tnl_device) {
675 dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
683 dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
686 if (dx_preserve_fpu_state)
687 dwBehaviorFlags |= D3DCREATE_FPU_PRESERVE;
694 if (!SetForegroundWindow(display._window)) {
695 wdxdisplay9_cat.warning() <<
"SetForegroundWindow() failed!\n";
698 if (dx_use_multithread) {
699 dwBehaviorFlags |= D3DCREATE_MULTITHREADED;
701 if (dx_use_puredevice) {
702 dwBehaviorFlags |= D3DCREATE_PUREDEVICE;
705 if (dx_disable_driver_management) {
706 dwBehaviorFlags |= D3DCREATE_DISABLE_DRIVER_MANAGEMENT;
708 if (dx_disable_driver_management_ex) {
709 dwBehaviorFlags |= D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX;
715 presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD;
716 presentation_params->PresentationInterval = (do_sync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE);
717 presentation_params->FullScreen_RefreshRateInHz = display._display_mode.RefreshRate;
721 hr = _d3d9->CreateDevice(adapter, device_type, _hWnd,
722 dwBehaviorFlags, presentation_params, &display._d3d_device);
725 wdxdisplay9_cat.fatal() <<
"D3D CreateDevice failed for adapter #" << adapter <<
", " << D3DERRORSTRING(hr);
727 if (hr == D3DERR_OUTOFVIDEOMEMORY)
728 goto Fallback_to_16bpp_buffers;
733 SetRect(&view_rect, 0, 0, dwRenderWidth, dwRenderHeight);
738 D3DDISPLAYMODE dispmode;
739 hr = display._d3d9->GetAdapterDisplayMode(adapter, &dispmode);
742 wdxdisplay9_cat.fatal()
743 <<
"GetAdapterDisplayMode failed" << D3DERRORSTRING(hr);
747 if (dispmode.Format == D3DFMT_P8) {
748 wdxdisplay9_cat.fatal()
749 <<
"Can't run windowed in an 8-bit or less display mode" << endl;
758 presentation_params->PresentationInterval = 0;
761 presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD;
762 if (do_sync ==
false) {
763 presentation_params->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
789 hr = _d3d9->CreateDevice(adapter, device_type, _hWnd,
790 dwBehaviorFlags, presentation_params, &display._d3d_device);
793 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferWidth : " << presentation_params->BackBufferWidth << endl;
794 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferHeight : " << presentation_params->BackBufferHeight << endl;
795 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferFormat : " << presentation_params->BackBufferFormat << endl;
796 wdxdisplay9_cat.warning() <<
"presentation_params->BackBufferCount : " << presentation_params->BackBufferCount << endl;
797 wdxdisplay9_cat.warning() <<
"D3D CreateDevice failed for adapter #" << adapter << D3DERRORSTRING(hr);
798 goto Fallback_to_16bpp_buffers;
804 PRINT_REFCNT(wdxdisplay9, _wcontext._d3d_device);
806 if (presentation_params->EnableAutoDepthStencil) {
812 switch (presentation_params->AutoDepthStencilFormat)
814 case D3DFMT_D16_LOCKABLE:
835 case D3DFMT_D32F_LOCKABLE:
846 wdxdisplay9_cat.error() <<
"unknown depth stencil format " << presentation_params->AutoDepthStencilFormat;
850 _fb_properties.set_stencil_bits(stencil_bits);
851 _fb_properties.set_depth_bits(depth_bits);
853 _fb_properties.set_depth_bits(0);
854 _fb_properties.set_stencil_bits(0);
857 init_resized_window();
861 Fallback_to_16bpp_buffers:
862 if ((!IS_16BPP_DISPLAY_FORMAT(presentation_params->BackBufferFormat)) &&
863 (display._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) {
866 display._display_mode.Format = ((display._supported_screen_depths_mask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5);
868 if (wdxdisplay9_cat.info()) {
869 wdxdisplay9_cat.info()
870 <<
"CreateDevice failed with out-of-vidmem or invalid BackBufferFormat, retrying w/16bpp buffers on adapter #"
873 return create_screen_buffers_and_device(display,
true);
876 }
else if (!((dwRenderWidth == 640)&&(dwRenderHeight == 480))) {
877 if (wdxdisplay9_cat.info())
878 wdxdisplay9_cat.info() <<
"CreateDevice failed w/out-of-vidmem, retrying at 640x480 w/16bpp buffers on adapter #" << adapter << endl;
880 display._display_mode.Width = 640;
881 display._display_mode.Height = 480;
882 return create_screen_buffers_and_device(display,
true);
886 wdxdisplay9_cat.fatal()
887 <<
"Can't create any screen buffers, bailing out.\n";
900 bool wdxGraphicsWindow9::
905 DCAST_INTO_R(dxpipe, _pipe,
false);
907 int num_adapters = dxpipe->__d3d9->GetAdapterCount();
908 DXDeviceInfoVec device_infos;
910 for (
int i = 0; i < num_adapters; i++) {
911 D3DADAPTER_IDENTIFIER9 adapter_info;
912 ZeroMemory(&adapter_info,
sizeof(D3DADAPTER_IDENTIFIER9));
913 hr = dxpipe->__d3d9->GetAdapterIdentifier(i, 0, &adapter_info);
915 wdxdisplay9_cat.fatal()
916 <<
"D3D GetAdapterID(" << i <<
") failed: "
917 << D3DERRORSTRING(hr) << endl;
921 LARGE_INTEGER *DrvVer = &adapter_info.DriverVersion;
923 wdxdisplay9_cat.info()
924 <<
"D3D9." << (dxpipe->__is_dx9_1 ?
"1":
"0") <<
" Adapter[" << i <<
"]: " << adapter_info.Description
925 <<
", Driver: " << adapter_info.Driver <<
", DriverVersion: ("
926 << HIWORD(DrvVer->HighPart) <<
"." << LOWORD(DrvVer->HighPart) <<
"."
927 << HIWORD(DrvVer->LowPart) <<
"." << LOWORD(DrvVer->LowPart)
928 <<
")\nVendorID: 0x" << (
void*) adapter_info.VendorId
929 <<
" DeviceID: 0x" << (
void*) adapter_info.DeviceId
930 <<
" SubsysID: 0x" << (
void*) adapter_info.SubSysId
931 <<
" Revision: 0x" << (
void*) adapter_info.Revision << endl;
933 HMONITOR _monitor = dxpipe->__d3d9->GetAdapterMonitor(i);
934 if (_monitor == NULL) {
935 wdxdisplay9_cat.info()
936 <<
"D3D9 Adapter[" << i <<
"]: seems to be disabled, skipping it\n";
940 DXDeviceInfo devinfo;
941 ZeroMemory(&devinfo,
sizeof(devinfo));
942 memcpy(&devinfo.guidDeviceIdentifier, &adapter_info.DeviceIdentifier,
944 strncpy(devinfo.szDescription, adapter_info.Description,
945 MAX_DEVICE_IDENTIFIER_STRING);
946 strncpy(devinfo.szDriver, adapter_info.Driver,
947 MAX_DEVICE_IDENTIFIER_STRING);
948 devinfo.VendorID = adapter_info.VendorId;
949 devinfo.DeviceID = adapter_info.DeviceId;
950 devinfo._driver_version = adapter_info.DriverVersion;
951 devinfo._monitor = _monitor;
954 device_infos.push_back(devinfo);
957 if (device_infos.empty()) {
958 wdxdisplay9_cat.error()
959 <<
"No available D3D9 devices found.\n";
965 num_adapters = (int)device_infos.size();
969 int adapter_num = D3DADAPTER_DEFAULT;
973 if (dx_preferred_device_id != -1) {
974 if (dx_preferred_device_id < 0 || dx_preferred_device_id >= num_adapters) {
975 wdxdisplay9_cat.error()
976 <<
"invalid 'dx-preferred-device-id', valid values are 0-"
977 << num_adapters - 1 <<
", using default adapter instead.\n";
979 adapter_num = dx_preferred_device_id;
984 if (adapter_num >= 0 && adapter_num < (
int)device_infos.size()) {
985 if (consider_device(dxpipe, &device_infos[adapter_num])) {
986 wdxdisplay9_cat.info()
987 <<
"Selected device " << adapter_num <<
" (of "
988 << device_infos.
size() <<
", zero-based)\n";
991 wdxdisplay9_cat.info()
992 <<
"Could not select device " << adapter_num <<
"\n";
997 for (UINT devnum = 0; devnum < device_infos.size(); ++devnum) {
998 if (consider_device(dxpipe, &device_infos[devnum])) {
999 wdxdisplay9_cat.info()
1000 <<
"Chose device " << devnum <<
" (of "
1001 << device_infos.size() <<
", zero-based): first one that works.\n";
1006 wdxdisplay9_cat.error() <<
"no usable display devices.\n";
1017 bool wdxGraphicsWindow9::
1020 nassertr(dxpipe != NULL,
false);
1022 DWORD dwRenderWidth = properties.
get_x_size();
1023 DWORD dwRenderHeight = properties.
get_y_size();
1025 LPDIRECT3D9 _d3d9 = dxpipe->__d3d9;
1027 nassertr(_dxgsg != NULL,
false);
1028 _wcontext._d3d9 = _d3d9;
1029 _wcontext._is_dx9_1 = dxpipe->__is_dx9_1;
1030 _wcontext._card_id = device_info->cardID;
1032 bool bWantStencil = (_fb_properties.get_stencil_bits() > 0);
1034 hr = _d3d9->GetAdapterIdentifier(device_info->cardID, 0,
1035 &_wcontext._dx_device_id);
1037 wdxdisplay9_cat.error()
1038 <<
"D3D GetAdapterID failed" << D3DERRORSTRING(hr);
1043 hr = _d3d9->GetDeviceCaps(device_info->cardID, D3DDEVTYPE_HAL, &_d3dcaps);
1045 if ((hr == D3DERR_INVALIDDEVICE)||(hr == D3DERR_NOTAVAILABLE)) {
1046 wdxdisplay9_cat.error()
1047 <<
"No DirectX 9 D3D-capable 3D hardware detected for device # "
1048 << device_info->cardID <<
" (" << device_info->szDescription
1051 wdxdisplay9_cat.error()
1052 <<
"GetDeviceCaps failed: " << D3DERRORSTRING(hr) << endl;
1058 memcpy(&_wcontext._d3dcaps, &_d3dcaps,
sizeof(D3DCAPS9));
1059 _wcontext._card_id = device_info->cardID;
1061 _wcontext._max_available_video_memory = UNKNOWN_VIDMEM_SIZE;
1062 _wcontext._is_low_memory_card =
false;
1067 if (_d3dcaps.MaxStreams == 0) {
1068 if (wdxdisplay9_cat.is_debug()) {
1069 wdxdisplay9_cat.debug()
1070 <<
"checking vidmem size\n";
1076 for (IDnum = 0; IDnum < dxpipe->_card_ids.size(); IDnum++) {
1077 if ((device_info->VendorID == dxpipe->_card_ids[IDnum].VendorID) &&
1078 (device_info->DeviceID == dxpipe->_card_ids[IDnum].DeviceID) &&
1079 (device_info->_monitor == dxpipe->_card_ids[IDnum]._monitor))
1083 if (IDnum < dxpipe->_card_ids.size()) {
1084 _wcontext._max_available_video_memory = dxpipe->_card_ids[IDnum]._max_available_video_memory;
1085 _wcontext._is_low_memory_card = dxpipe->_card_ids[IDnum]._is_low_memory_card;
1087 wdxdisplay9_cat.error()
1088 <<
"Error: couldnt find a CardID match in DX7 info, assuming card is not a lowmem card\n";
1092 if ((bWantStencil) && (_d3dcaps.StencilCaps == 0x0)) {
1093 wdxdisplay9_cat.fatal()
1094 <<
"Stencil ability requested, but device #" << device_info->cardID
1095 <<
" (" << _wcontext._dx_device_id.Description
1096 <<
"), has no stencil capability!\n";
1104 _wcontext._is_tnl_device =
1105 ((_d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0);
1106 _wcontext._can_use_hw_vertex_shaders =
1107 (_d3dcaps.VertexShaderVersion >= D3DVS_VERSION(1, 0));
1108 _wcontext._can_use_pixel_shaders =
1109 (_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(1, 0));
1112 ((!(_d3dcaps.RasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )) &&
1113 (_fb_properties.get_depth_bits() > 0));
1115 _wcontext._presentation_params.EnableAutoDepthStencil = bNeedZBuffer;
1117 D3DFORMAT pixFmt = D3DFMT_UNKNOWN;
1120 bool bCouldntFindValidZBuf;
1123 bNeedZBuffer, bWantStencil,
1124 &_wcontext._supported_screen_depths_mask,
1125 &bCouldntFindValidZBuf,
1126 &pixFmt, dx_force_16bpp_zbuffer,
true);
1131 if (pixFmt == D3DFMT_UNKNOWN) {
1132 wdxdisplay9_cat.error()
1133 << (bCouldntFindValidZBuf ?
"Couldnt find valid zbuffer format to go with FullScreen mode" :
"No supported FullScreen modes")
1134 <<
" at " << dwRenderWidth <<
"x" << dwRenderHeight <<
" for device #" << _wcontext._card_id << endl;
1140 D3DDISPLAYMODE dispmode;
1141 hr = _d3d9->GetAdapterDisplayMode(device_info->cardID, &dispmode);
1143 wdxdisplay9_cat.error()
1144 <<
"GetAdapterDisplayMode(" << device_info->cardID
1145 <<
") failed" << D3DERRORSTRING(hr);
1148 pixFmt = dispmode.Format;
1151 _wcontext._display_mode.Width = dwRenderWidth;
1152 _wcontext._display_mode.Height = dwRenderHeight;
1153 _wcontext._display_mode.Format = pixFmt;
1154 _wcontext._display_mode.RefreshRate = D3DPRESENT_RATE_DEFAULT;
1155 _wcontext._monitor = device_info->_monitor;
1157 if (strcmp(device_info->szDriver,
"igdumd32.dll") == 0 &&
1158 device_info->_driver_version.QuadPart <= 0x0007000e000affffLL &&
1159 dx_intel_compressed_texture_bug) {
1163 _wcontext._intel_compressed_texture_bug =
true;
1176 bool wdxGraphicsWindow9::
1177 reset_device_resize_window(UINT new_xsize, UINT new_ysize) {
1181 D3DPRESENT_PARAMETERS d3dpp;
1182 memcpy(&d3dpp, &_wcontext._presentation_params,
sizeof(D3DPRESENT_PARAMETERS));
1183 _wcontext._presentation_params.BackBufferWidth = new_xsize;
1184 _wcontext._presentation_params.BackBufferHeight = new_ysize;
1186 HRESULT hr = _dxgsg->reset_d3d_device(&_wcontext._presentation_params, &screen);
1190 wdxdisplay9_cat.error()
1191 <<
"reset_device_resize_window Reset() failed" << D3DERRORSTRING(hr);
1192 if (hr == D3DERR_OUTOFVIDEOMEMORY) {
1193 memcpy(&_wcontext._presentation_params, &d3dpp,
sizeof(D3DPRESENT_PARAMETERS));
1194 hr = _dxgsg->reset_d3d_device(&_wcontext._presentation_params, &screen);
1196 wdxdisplay9_cat.error()
1197 <<
"reset_device_resize_window Reset() failed OutOfVidmem, then failed again doing Reset w/original params:" << D3DERRORSTRING(hr);
1198 throw_event(
"panda3d-render-error");
1202 if (wdxdisplay9_cat.is_info()) {
1203 wdxdisplay9_cat.info()
1204 <<
"reset of original size (" << _wcontext._presentation_params.BackBufferWidth
1205 <<
", " << _wcontext._presentation_params.BackBufferHeight <<
") succeeded\n";
1209 wdxdisplay9_cat.fatal()
1210 <<
"Can't reset device, bailing out.\n";
1211 throw_event(
"panda3d-render-error");
1217 _wcontext._swap_chain = screen->_swap_chain;
1219 wdxdisplay9_cat.debug() <<
"swapchain is " << _wcontext._swap_chain <<
"\n";
1221 init_resized_window();
1235 void wdxGraphicsWindow9::
1236 init_resized_window() {
1239 DWORD newWidth = _wcontext._presentation_params.BackBufferWidth;
1240 DWORD newHeight = _wcontext._presentation_params.BackBufferHeight;
1242 nassertv((newWidth != 0) && (newHeight != 0));
1243 nassertv(_wcontext._window != NULL);
1245 if (_wcontext._presentation_params.Windowed) {
1252 GetClientRect(_wcontext._window, &client_rect);
1253 ul.x = client_rect.left;
1254 ul.y = client_rect.top;
1255 lr.x = client_rect.right;
1256 lr.y = client_rect.bottom;
1257 ClientToScreen(_wcontext._window, &ul);
1258 ClientToScreen(_wcontext._window, &lr);
1259 client_rect.left = ul.x;
1260 client_rect.top = ul.y;
1261 client_rect.right = lr.x;
1262 client_rect.bottom = lr.y;
1266 nassertv(_wcontext._window != NULL);
1270 hr = _wcontext._d3d_device->EvictManagedResources ( );
1272 wdxdisplay9_cat.error()
1273 <<
"EvictManagedResources failed for device #"
1274 << _wcontext._card_id << D3DERRORSTRING(hr);
1280 _dxgsg->set_render_target ( );
1284 D3DCOLOR clear_color;
1286 flags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER;
1287 clear_color = 0x00000000;
1288 hr = _wcontext._d3d_device-> Clear (0, NULL, flags, clear_color, 0.0f, 0);
1290 wdxdisplay9_cat.error()
1291 <<
"Clear failed for device"
1292 << D3DERRORSTRING(hr);
1294 hr = _wcontext._d3d_device-> Present (NULL, NULL, NULL, NULL);
1296 wdxdisplay9_cat.error()
1297 <<
"Present failed for device"
1298 << D3DERRORSTRING(hr);
1300 hr = _wcontext._d3d_device-> Clear (0, NULL, flags, clear_color, 0.0f, 0);
1302 wdxdisplay9_cat.error()
1303 <<
"Clear failed for device"
1304 << D3DERRORSTRING(hr);
1314 int wdxGraphicsWindow9::
1315 D3DFMT_to_DepthBits(D3DFORMAT fmt) {
1321 case D3DFMT_D24X4S4:
1332 wdxdisplay9_cat.debug()
1333 <<
"D3DFMT_DepthBits: unhandled D3DFMT!\n";
1345 bool wdxGraphicsWindow9::
1346 is_badvidmem_card(D3DADAPTER_IDENTIFIER9 *pDevID) {
1348 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...
int size() const
Returns the number of unique words in the variable.
A GraphicsStateGuardian for rendering into DirectX9 contexts.
int get_x_origin() const
Returns the x coordinate of the window's top-left corner, not including decorations.
bool get_value() const
Returns the variable's value.
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 void end_flip()
This function will be called within the draw thread after begin_flip() has been called on all windows...
bool is_fullscreen() const
Returns true if the window has been opened as a fullscreen window, false otherwise.
GraphicsDevice * get_device() const
Returns a pointer to device object.
const WindowProperties get_properties() const
Returns the current properties of the window.
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.
int get_y_size() const
Returns size in pixels in the y dimension of the useful part of the window, not including decorations...
GraphicsPipe * get_pipe() const
Returns the graphics pipe on which this GSG was created.
void set_size(const LVector2i &size)
Specifies the requested size of the window, in pixels.
int get_y_origin() const
Returns the y coordinate of the window's top-left corner, not including decorations.
A GraphicsDevice necessary for multi-window rendering in DX.
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...
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.
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, graphics windows that interface with the Microsoft Windows API).
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.
This is a base class for the various different classes that represent the result of a frame of render...
virtual int verify_window_sizes(int numsizes, int *dimen)
Determines which of the indicated window sizes are supported by available hardware (e...
int get_x_size() const
Returns size in pixels in the x dimension of the useful part of the window, not including decorations...
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.
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.
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.
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 get_unexposed_draw() const
See set_unexposed_draw().
int get_value() const
Returns the variable's value.