22 void Print(
const char* msg, ...);
28 #define RELEASE(x) if (x) { x->Release(); x=NULL; }
34 static UINT GetBitsPerPixel(D3DFORMAT fmt)
37 case D3DFMT_A8R8G8B8:
return 32;
38 case D3DFMT_X8R8G8B8:
return 32;
39 case D3DFMT_A2B10G10R10:
return 32;
40 case D3DFMT_A2R10G10B10:
return 32;
41 case D3DFMT_R8G8B8:
return 24;
42 case D3DFMT_R5G6B5:
return 16;
43 case D3DFMT_X1R5G5B5:
return 16;
44 case D3DFMT_A1R5G5B5:
return 16;
45 case D3DFMT_A4R4G4B4:
return 16;
46 case D3DFMT_A8R3G3B2:
return 16;
47 case D3DFMT_X4R4G4B4:
return 16;
48 case D3DFMT_R3G3B2:
return 8;
55 static UINT GetColorChannelBits(D3DFORMAT fmt)
58 case D3DFMT_A2B10G10R10:
return 10;
59 case D3DFMT_A2R10G10B10:
return 10;
60 case D3DFMT_R8G8B8:
return 8;
61 case D3DFMT_A8R8G8B8:
return 8;
62 case D3DFMT_X8R8G8B8:
return 8;
63 case D3DFMT_R5G6B5:
return 6;
64 case D3DFMT_X1R5G5B5:
return 5;
65 case D3DFMT_A1R5G5B5:
return 5;
66 case D3DFMT_A4R4G4B4:
return 4;
67 case D3DFMT_R3G3B2:
return 2;
68 case D3DFMT_A8R3G3B2:
return 2;
69 case D3DFMT_X4R4G4B4:
return 4;
76 static UINT GetAlphaChannelBits(D3DFORMAT fmt)
79 case D3DFMT_R8G8B8:
return 0;
80 case D3DFMT_A8R8G8B8:
return 8;
81 case D3DFMT_X8R8G8B8:
return 0;
82 case D3DFMT_R5G6B5:
return 0;
83 case D3DFMT_X1R5G5B5:
return 0;
84 case D3DFMT_A1R5G5B5:
return 1;
85 case D3DFMT_A4R4G4B4:
return 4;
86 case D3DFMT_R3G3B2:
return 0;
87 case D3DFMT_A8R3G3B2:
return 8;
88 case D3DFMT_X4R4G4B4:
return 0;
89 case D3DFMT_A2B10G10R10:
return 2;
90 case D3DFMT_A2R10G10B10:
return 2;
97 static UINT GetDepthBits(D3DFORMAT fmt)
100 case D3DFMT_D16:
return 16;
101 case D3DFMT_D15S1:
return 15;
102 case D3DFMT_D24X8:
return 24;
103 case D3DFMT_D24S8:
return 24;
104 case D3DFMT_D24X4S4:
return 24;
105 case D3DFMT_D32:
return 32;
112 static UINT GetStencilBits(D3DFORMAT fmt)
115 case D3DFMT_D16:
return 0;
116 case D3DFMT_D15S1:
return 1;
117 case D3DFMT_D24X8:
return 0;
118 case D3DFMT_D24S8:
return 8;
119 case D3DFMT_D24X4S4:
return 4;
120 case D3DFMT_D32:
return 0;
130 static void DescribeGUID(GUID* lpGUID)
133 Print(
" GUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
134 lpGUID->Data1, lpGUID->Data2, lpGUID->Data3,
135 lpGUID->Data4[0], lpGUID->Data4[1],
136 lpGUID->Data4[2], lpGUID->Data4[3],
137 lpGUID->Data4[4], lpGUID->Data4[5],
138 lpGUID->Data4[6], lpGUID->Data4[7]);
140 Print(
" GUID IS NULL!\n");
191 if (index >= 0 && index < adapter_info_list.
size())
192 adapter_index = index;
198 if (adapter_index >= 0 && adapter_index < adapter_info_list.
size())
199 return adapter_info_list[adapter_index];
207 if (adapter_index >= 0 && adapter_index < adapter_info_list.
size()) {
227 if (adapter_index >= 0 && adapter_index < adapter_info_list.
size()) {
231 while (++mode_iter) {
234 if (mode->
width == (UINT) w &&
235 mode->
height == (UINT) h &&
236 GetBitsPerPixel(mode->
format) == (UINT) b) {
257 Print(
"Video DX9 Enumerate Adapters and Devices\n");
258 Print(
"----------------------------------------\n\n");
261 allowed_adapter_format_list.push_back(D3DFMT_X8R8G8B8);
262 allowed_adapter_format_list.push_back(D3DFMT_X1R5G5B5);
263 allowed_adapter_format_list.push_back(D3DFMT_R5G6B5);
264 allowed_adapter_format_list.push_back(D3DFMT_A2R10G10B10);
267 std::vector<D3DFORMAT> adapter_format_list;
268 UINT num_adapters = d3d->GetAdapterCount();
270 for (UINT ordinal = 0; ordinal < num_adapters; ordinal++) {
273 return E_OUTOFMEMORY;
280 adapter_format_list.clear();
282 for (
size_t iaaf = 0; iaaf < allowed_adapter_format_list.size(); iaaf++) {
283 D3DFORMAT allowed_adapter_format = allowed_adapter_format_list[iaaf];
284 UINT num_adapter_modes = d3d->GetAdapterModeCount(ordinal, allowed_adapter_format);
286 for (UINT mode = 0; mode < num_adapter_modes; mode++) {
287 D3DDISPLAYMODE display_mode;
288 d3d->EnumAdapterModes(ordinal, allowed_adapter_format, mode, &display_mode);
298 if (!dx9_display_mode) {
300 return E_OUTOFMEMORY;
305 bool contains_display_mode =
false;
306 for (
auto afli = adapter_format_list.begin(); afli != adapter_format_list.end(); ++afli) {
307 if (*afli == display_mode.Format) {
308 contains_display_mode =
true;
312 if (!contains_display_mode)
313 adapter_format_list.push_back(display_mode.Format);
338 if (FAILED(hr = EnumerateDevices(adapter_info, adapter_format_list))) {
348 adapter_info_list.
append(adapter_info);
361 VideoDX9Enum::EnumerateDevices(
VideoDX9AdapterInfo* adapter_info, std::vector<D3DFORMAT>& adapter_format_list)
364 const D3DDEVTYPE dtypes[3] = { D3DDEVTYPE_HAL, D3DDEVTYPE_SW, D3DDEVTYPE_REF };
365 const char* dtypestr[3] = {
"D3DDEVTYPE_HAL",
"D3DDEVTYPE_SW",
"D3DDEVTYPE_REF" };
368 for (
int i = 0; i < 3; i++ ) {
371 return E_OUTOFMEMORY;
378 &device_info->
caps))) {
384 Print(
" Device %d - %s\n", i, dtypestr[i]);
385 Print(
" Max Texture Width: %d\n", device_info->
caps.MaxTextureWidth);
386 Print(
" Max Texture Height: %d\n", device_info->
caps.MaxTextureHeight);
390 if (FAILED(hr = EnumerateDeviceCombos(device_info, adapter_format_list))) {
410 VideoDX9Enum::EnumerateDeviceCombos(
VideoDX9DeviceInfo* device_info, std::vector<D3DFORMAT>& adapter_format_list)
412 const D3DFORMAT back_buffer_formats[] = {
421 bool is_windowed[] = {
false,
true };
425 for (
size_t i = 0; i < adapter_format_list.size(); i++) {
426 a_fmt = adapter_format_list[i];
429 for (
int n = 0; n < 6; n++) {
430 b_fmt = back_buffer_formats[n];
436 for (
int w = 0; w < 2; w++) {
437 win = is_windowed[w];
461 return E_OUTOFMEMORY;
470 BuildDepthStencilFormatList(device_combo);
477 BuildMultiSampleTypeList(device_combo);
483 BuildDSMSConflictList(device_combo);
485 BuildVertexProcessingTypeList(device_info, device_combo);
491 BuildPresentIntervalList(device_info, device_combo);
504 const D3DFORMAT depth_stencil_formats[] = {
513 for (
int i = 0; i < 6; i++) {
514 D3DFORMAT fmt = depth_stencil_formats[i];
525 D3DUSAGE_DEPTHSTENCIL,
529 if (SUCCEEDED(d3d->CheckDepthStencilMatch(device_combo->
adapter_ordinal,
544 const D3DMULTISAMPLE_TYPE multisample_type_array[] = {
546 D3DMULTISAMPLE_NONMASKABLE,
547 D3DMULTISAMPLE_2_SAMPLES,
548 D3DMULTISAMPLE_3_SAMPLES,
549 D3DMULTISAMPLE_4_SAMPLES,
550 D3DMULTISAMPLE_5_SAMPLES,
551 D3DMULTISAMPLE_6_SAMPLES,
552 D3DMULTISAMPLE_7_SAMPLES,
553 D3DMULTISAMPLE_8_SAMPLES,
554 D3DMULTISAMPLE_9_SAMPLES,
555 D3DMULTISAMPLE_10_SAMPLES,
556 D3DMULTISAMPLE_11_SAMPLES,
557 D3DMULTISAMPLE_12_SAMPLES,
558 D3DMULTISAMPLE_13_SAMPLES,
559 D3DMULTISAMPLE_14_SAMPLES,
560 D3DMULTISAMPLE_15_SAMPLES,
561 D3DMULTISAMPLE_16_SAMPLES,
564 for (
int i = 0; i < 17; i++) {
565 D3DMULTISAMPLE_TYPE multisample_type = multisample_type_array[i];
566 DWORD multisample_qual = 0;
568 if (SUCCEEDED(d3d->CheckDeviceMultiSampleType(device_combo->
adapter_ordinal,
573 &multisample_qual))) {
590 if (FAILED(d3d->CheckDeviceMultiSampleType(device_combo->
adapter_ordinal,
611 if ((device_info->
caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0) {
612 if ((device_info->
caps.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0) {
629 const DWORD present_interval_array[] = {
630 D3DPRESENT_INTERVAL_IMMEDIATE,
631 D3DPRESENT_INTERVAL_DEFAULT,
632 D3DPRESENT_INTERVAL_ONE,
633 D3DPRESENT_INTERVAL_TWO,
634 D3DPRESENT_INTERVAL_THREE,
635 D3DPRESENT_INTERVAL_FOUR,
638 for (
int i = 0; i < 6; i++) {
639 DWORD interval = present_interval_array[i];
649 if (interval == D3DPRESENT_INTERVAL_DEFAULT ||
650 (device_info->
caps.PresentationIntervals & interval)) {
665 D3DDISPLAYMODE desktop_display_mode;
666 d3d->GetAdapterDisplayMode(0, &desktop_display_mode);
671 int best_adapter_index = 0;
672 int best_device_index = 0;
697 if (best_device_combo == NULL ||
699 device_combo->
device_type == D3DDEVTYPE_HAL && formats_match) {
701 best_adapter_info = adapter_info;
702 best_adapter_index = a_iter.
index();
703 best_device_info = device_info;
704 best_device_index = d_iter.
index();
705 best_device_combo = device_combo;
707 if (device_combo->
device_type == D3DDEVTYPE_HAL && formats_match) {
709 goto EndWindowedDeviceComboSearch;
718 EndWindowedDeviceComboSearch:
719 if (best_device_combo == NULL)
755 D3DDISPLAYMODE desktop_display_mode;
756 D3DDISPLAYMODE best_desktop_display_mode;
758 best_desktop_display_mode.Width = 0;
759 best_desktop_display_mode.Height = 0;
760 best_desktop_display_mode.Format = D3DFMT_UNKNOWN;
761 best_desktop_display_mode.RefreshRate = 0;
766 int best_adapter_index = 0;
767 int best_device_index = 0;
772 d3d->GetAdapterDisplayMode(adapter_info->
adapter_ordinal, &desktop_display_mode);
783 bool bAdapterMatchesDesktop = (device_combo->
adapter_format == desktop_display_mode.Format);
791 if (best_device_combo == NULL ||
793 device_combo->
device_type == D3DDEVTYPE_HAL && best_device_combo->
adapter_format != desktop_display_mode.Format && bAdapterMatchesDesktop ||
794 device_combo->
device_type == D3DDEVTYPE_HAL && bAdapterMatchesDesktop && bAdapterMatchesBB ) {
796 best_desktop_display_mode = desktop_display_mode;
797 best_adapter_info = adapter_info;
798 best_device_info = device_info;
799 best_device_combo = device_combo;
801 if (device_info->
device_type == D3DDEVTYPE_HAL && bAdapterMatchesDesktop && bAdapterMatchesBB) {
803 goto EndFullscreenDeviceComboSearch;
812 EndFullscreenDeviceComboSearch:
813 if (best_device_combo == NULL)
827 if (display_mode->
width == desired_width &&
828 display_mode->
height == desired_height &&
829 display_mode->
refresh == best_desktop_display_mode.RefreshRate) {
832 best_display_mode = *display_mode;
835 else if (display_mode->
width == desired_width &&
836 display_mode->
height == desired_height &&
837 display_mode->
refresh > best_desktop_display_mode.RefreshRate) {
840 best_display_mode = *display_mode;
842 else if (display_mode->
width == desired_width) {
844 best_display_mode = *display_mode;
846 else if (best_display_mode.
width == 0)
849 best_display_mode = *display_mode;
880 : width(0), height(0), refresh(0), format(D3DFMT_UNKNOWN)
884 : width(m.width), height(m.height), refresh(m.refresh), format(m.format)
888 : width(m.Width), height(m.Height), refresh(m.RefreshRate), format(m.Format)
939 static char desc[32];
941 sprintf_s(desc,
"%4d x %4d %-12s %d Hz",
953 const char* str =
"Unknown Format";
956 case D3DFMT_UNKNOWN: str =
"UNKNOWN";
break;
957 case D3DFMT_R8G8B8: str =
"R8G8B8";
break;
958 case D3DFMT_A8R8G8B8: str =
"A8R8G8B8";
break;
959 case D3DFMT_X8R8G8B8: str =
"X8R8G8B8";
break;
960 case D3DFMT_R5G6B5: str =
"R5G6B5";
break;
961 case D3DFMT_X1R5G5B5: str =
"X1R5G5B5";
break;
962 case D3DFMT_A1R5G5B5: str =
"A1R5G5B5";
break;
963 case D3DFMT_A4R4G4B4: str =
"A4R4G4B4";
break;
964 case D3DFMT_R3G3B2: str =
"R3G3B2";
break;
965 case D3DFMT_A8: str =
"A8";
break;
966 case D3DFMT_A8R3G3B2: str =
"A8R3G3B2";
break;
967 case D3DFMT_X4R4G4B4: str =
"X4R4G4B4";
break;
968 case D3DFMT_A2B10G10R10: str =
"A2B10G10R10";
break;
969 case D3DFMT_A8B8G8R8: str =
"A8B8G8R8";
break;
970 case D3DFMT_X8B8G8R8: str =
"X8B8G8R8";
break;
971 case D3DFMT_G16R16: str =
"G16R16";
break;
972 case D3DFMT_A2R10G10B10: str =
"A2R10G10B10";
break;
973 case D3DFMT_A16B16G16R16: str =
"A16B16G16R16";
break;
974 case D3DFMT_A8P8: str =
"A8P8";
break;
975 case D3DFMT_P8: str =
"P8";
break;
976 case D3DFMT_L8: str =
"L8";
break;
977 case D3DFMT_A8L8: str =
"A8L8";
break;
978 case D3DFMT_A4L4: str =
"A4L4";
break;
979 case D3DFMT_V8U8: str =
"V8U8";
break;
980 case D3DFMT_L6V5U5: str =
"L6V5U5";
break;
981 case D3DFMT_X8L8V8U8: str =
"X8L8V8U8";
break;
982 case D3DFMT_Q8W8V8U8: str =
"Q8W8V8U8";
break;
983 case D3DFMT_V16U16: str =
"V16U16";
break;
984 case D3DFMT_A2W10V10U10: str =
"A2W10V10U10";
break;
985 case D3DFMT_UYVY: str =
"UYVY";
break;
986 case D3DFMT_YUY2: str =
"YUY2";
break;
987 case D3DFMT_DXT1: str =
"DXT1";
break;
988 case D3DFMT_DXT2: str =
"DXT2";
break;
989 case D3DFMT_DXT3: str =
"DXT3";
break;
990 case D3DFMT_DXT4: str =
"DXT4";
break;
991 case D3DFMT_DXT5: str =
"DXT5";
break;
992 case D3DFMT_D16_LOCKABLE: str =
"D16_LOCKABLE";
break;
993 case D3DFMT_D32: str =
"D32";
break;
994 case D3DFMT_D15S1: str =
"D15S1";
break;
995 case D3DFMT_D24S8: str =
"D24S8";
break;
996 case D3DFMT_D24X8: str =
"D24X8";
break;
997 case D3DFMT_D24X4S4: str =
"D24X4S4";
break;
998 case D3DFMT_D16: str =
"D16";
break;
999 case D3DFMT_L16: str =
"L16";
break;
1000 case D3DFMT_VERTEXDATA: str =
"VERTEXDATA";
break;
1001 case D3DFMT_INDEX16: str =
"INDEX16";
break;
1002 case D3DFMT_INDEX32: str =
"INDEX32";
break;
1003 case D3DFMT_Q16W16V16U16: str =
"Q16W16V16U16";
break;
1004 case D3DFMT_MULTI2_ARGB8: str =
"MULTI2_ARGB8";
break;
1005 case D3DFMT_R16F: str =
"R16F";
break;
1006 case D3DFMT_G16R16F: str =
"G16R16F";
break;
1007 case D3DFMT_A16B16G16R16F: str =
"A16B16G16R16F";
break;
1008 case D3DFMT_R32F: str =
"R32F";
break;
1009 case D3DFMT_G32R32F: str =
"G32R32F";
break;
1010 case D3DFMT_A32B32G32R32F: str =
"A32B32G32R32F";
break;
1011 case D3DFMT_CxV8U8: str =
"CxV8U8";
break;
1012 default: str =
"Unknown format";
break;
1022 : adapter_ordinal(0)
1042 : adapter_ordinal(0), device_type(D3DDEVTYPE_HAL)
1055 : adapter_ordinal(0), device_type(D3DDEVTYPE_HAL),
1056 adapter_format((D3DFORMAT) 0),
1057 back_buffer_format((D3DFORMAT) 0),