8282{
8383 AdapterOption Adapter;
8484} Options;
85- vector<tuple<int , int , int >> monitorModes;
85+ vector<tuple<int , int , int , int >> monitorModes;
8686vector< DISPLAYCONFIG_VIDEO_SIGNAL_INFO > s_KnownMonitorModes2;
8787UINT numVirtualDisplays;
8888wstring gpuname;
@@ -263,6 +263,25 @@ string WStringToString(const wstring& wstr) { //basically just a function for co
263263 return str;
264264}
265265
266+ int gcd (int a, int b) {
267+ while (b != 0 ) {
268+ int temp = b;
269+ b = a % b;
270+ a = temp;
271+ }
272+ return a;
273+ }
274+
275+ void float_to_vsync (float refresh_rate, int & num, int & den) {
276+ den = 10000 ;
277+
278+ num = static_cast <int >(round (refresh_rate * den));
279+
280+ int divisor = gcd (num, den);
281+ num /= divisor;
282+ den /= divisor;
283+ }
284+
266285void vddlog (const char * type, const char * message) {
267286 FILE * logFile;
268287 logsEnabled = LogEnabledQuery ();
@@ -1073,7 +1092,7 @@ void loadSettings() {
10731092 UINT cwchValue;
10741093 wstring currentElement;
10751094 wstring width, height, refreshRate;
1076- vector<tuple<int , int , int >> res;
1095+ vector<tuple<int , int , int , int >> res;
10771096 wstring gpuFriendlyName;
10781097 UINT monitorcount = 1 ;
10791098
@@ -1118,9 +1137,12 @@ void loadSettings() {
11181137 if (refreshRate.empty ()) {
11191138 refreshRate = L" 30" ;
11201139 }
1121- res.push_back (make_tuple (stoi (width), stoi (height), stoi (refreshRate)));
1140+ int vsync_num, vsync_den;
1141+ float_to_vsync (stof (refreshRate), vsync_num, vsync_den);
1142+
1143+ res.push_back (make_tuple (stoi (width), stoi (height), vsync_num, vsync_den));
11221144 stringstream ss;
1123- ss << " Added: " << stoi (width) << " x" << stoi (height) << " @ " << stoi (refreshRate) << " Hz" ;
1145+ ss << " Added: " << stoi (width) << " x" << stoi (height) << " @ " << vsync_num << " / " << vsync_den << " Hz" ;
11241146 vddlog (" d" , ss.str ().c_str ());
11251147 }
11261148 break ;
@@ -1137,80 +1159,92 @@ void loadSettings() {
11371159 ifstream ifs (optionsname);
11381160 if (ifs.is_open ()) {
11391161 string line;
1140- vector<tuple<int , int , int >> res;
1162+ vector<tuple<int , int , int , int >> res;
11411163 getline (ifs, line);
11421164 numVirtualDisplays = stoi (line);
11431165 while (getline (ifs, line)) {
11441166 vector<string> strvec = split (line, ' ,' );
11451167 if (strvec.size () == 3 && strvec[0 ].substr (0 , 1 ) != " #" ) {
1146- res.push_back ({ stoi (strvec[0 ]),stoi (strvec[1 ]),stoi (strvec[2 ]) });
1168+ int vsync_num, vsync_den;
1169+ float_to_vsync (stof (strvec[2 ]), vsync_num, vsync_den);
1170+ res.push_back ({ stoi (strvec[0 ]), stoi (strvec[1 ]), vsync_num, vsync_den });
11471171 }
11481172 }
11491173 vddlog (" i" , " Using option.txt" );
1150- monitorModes = res;
1174+ monitorModes = res;
11511175 for (const auto & mode : res) {
1152- int width, height, refreshRate ;
1153- tie (width, height, refreshRate ) = mode;
1176+ int width, height, vsync_num, vsync_den ;
1177+ tie (width, height, vsync_num, vsync_den ) = mode;
11541178 stringstream ss;
1155- ss << " Resolution: " << width << " x" << height << " @ " << refreshRate << " Hz" ;
1179+ ss << " Resolution: " << width << " x" << height << " @ " << vsync_num << " / " << vsync_den << " Hz" ;
11561180 vddlog (" d" , ss.str ().c_str ());
11571181 }
11581182 return ;
1159-
11601183 }
11611184 else {
11621185 numVirtualDisplays = 1 ;
1163- vector<tuple<int , int , int >> res = {
1164- make_tuple ( 800 , 600 , 30 ),
1165- make_tuple ( 800 , 600 , 60 ) ,
1166- make_tuple ( 800 , 600 , 90 ) ,
1167- make_tuple ( 800 , 600 , 120 ) ,
1168- make_tuple ( 800 , 600 , 144 ) ,
1169- make_tuple ( 800 , 600 , 165 ) ,
1170- make_tuple ( 1280 , 720 , 30 ) ,
1171- make_tuple ( 1280 , 720 , 60 ) ,
1172- make_tuple ( 1280 , 720 , 90 ) ,
1173- make_tuple ( 1280 , 720 , 130 ) ,
1174- make_tuple ( 1280 , 720 , 144 ) ,
1175- make_tuple ( 1280 , 720 , 165 ) ,
1176- make_tuple ( 1366 , 768 , 30 ) ,
1177- make_tuple ( 1366 , 768 , 60 ) ,
1178- make_tuple ( 1366 , 768 , 90 ) ,
1179- make_tuple ( 1366 , 768 , 120 ) ,
1180- make_tuple ( 1366 , 768 , 144 ) ,
1181- make_tuple ( 1366 , 768 , 165 ) ,
1182- make_tuple ( 1920 , 1080 , 30 ) ,
1183- make_tuple ( 1920 , 1080 , 60 ) ,
1184- make_tuple ( 1920 , 1080 , 90 ) ,
1185- make_tuple ( 1920 , 1080 , 120 ) ,
1186- make_tuple ( 1920 , 1080 , 144 ) ,
1187- make_tuple ( 1920 , 1080 , 165 ) ,
1188- make_tuple ( 2560 , 1440 , 30 ) ,
1189- make_tuple ( 2560 , 1440 , 60 ) ,
1190- make_tuple ( 2560 , 1440 , 90 ) ,
1191- make_tuple ( 2560 , 1440 , 120 ) ,
1192- make_tuple ( 2560 , 1440 , 144 ) ,
1193- make_tuple ( 2560 , 1440 , 165 ) ,
1194- make_tuple ( 3840 , 2160 , 30 ) ,
1195- make_tuple ( 3840 , 2160 , 60 ) ,
1196- make_tuple ( 3840 , 2160 , 90 ) ,
1197- make_tuple ( 3840 , 2160 , 120 ) ,
1198- make_tuple ( 3840 , 2160 , 144 ) ,
1199- make_tuple ( 3840 , 2160 , 165 )
1200-
1186+ vector<tuple<int , int , int , int >> res;
1187+ vector<tuple< int , int , float >> fallbackRes = {
1188+ { 800 , 600 , 30 . 0f } ,
1189+ { 800 , 600 , 60 . 0f } ,
1190+ { 800 , 600 , 90 . 0f } ,
1191+ { 800 , 600 , 120 . 0f } ,
1192+ { 800 , 600 , 144 . 0f } ,
1193+ { 800 , 600 , 165 . 0f } ,
1194+ { 1280 , 720 , 30 . 0f } ,
1195+ { 1280 , 720 , 60 . 0f } ,
1196+ { 1280 , 720 , 90 . 0f } ,
1197+ { 1280 , 720 , 130 . 0f } ,
1198+ { 1280 , 720 , 144 . 0f } ,
1199+ { 1280 , 720 , 165 . 0f } ,
1200+ { 1366 , 768 , 30 . 0f } ,
1201+ { 1366 , 768 , 60 . 0f } ,
1202+ { 1366 , 768 , 90 . 0f } ,
1203+ { 1366 , 768 , 120 . 0f } ,
1204+ { 1366 , 768 , 144 . 0f } ,
1205+ { 1366 , 768 , 165 . 0f } ,
1206+ { 1920 , 1080 , 30 . 0f } ,
1207+ { 1920 , 1080 , 60 . 0f } ,
1208+ { 1920 , 1080 , 90 . 0f } ,
1209+ { 1920 , 1080 , 120 . 0f } ,
1210+ { 1920 , 1080 , 144 . 0f } ,
1211+ { 1920 , 1080 , 165 . 0f } ,
1212+ { 2560 , 1440 , 30 . 0f } ,
1213+ { 2560 , 1440 , 60 . 0f } ,
1214+ { 2560 , 1440 , 90 . 0f } ,
1215+ { 2560 , 1440 , 120 . 0f } ,
1216+ { 2560 , 1440 , 144 . 0f } ,
1217+ { 2560 , 1440 , 165 . 0f } ,
1218+ { 3840 , 2160 , 30 . 0f } ,
1219+ { 3840 , 2160 , 60 . 0f } ,
1220+ { 3840 , 2160 , 90 . 0f } ,
1221+ { 3840 , 2160 , 120 . 0f } ,
1222+ { 3840 , 2160 , 144 . 0f },
1223+ { 3840 , 2160 , 165 . 0f }
12011224 };
12021225
12031226 vddlog (" i" , " Loading Fallback - no settings found" );
1204- for (const auto & mode : res) {
1205- int width, height, refreshRate;
1227+
1228+ for (const auto & mode : fallbackRes) {
1229+ int width, height;
1230+ float refreshRate;
12061231 tie (width, height, refreshRate) = mode;
1232+
1233+ int vsync_num, vsync_den;
1234+ float_to_vsync (refreshRate, vsync_num, vsync_den); // Convert refresh rate to vsync_num and vsync_den
1235+
1236+ // Use the correct type for vsync_num and vsync_den (int, int)
1237+ res.push_back (make_tuple (width, height, vsync_num, vsync_den)); // Add the tuple with vsync values
1238+
12071239 stringstream ss;
1208- ss << " Resolution: " << width << " x" << height << " @ " << refreshRate << " Hz" ;
1240+ ss << " Resolution: " << width << " x" << height << " @ " << vsync_num << " / " << vsync_den << " Hz" ;
12091241 vddlog (" d" , ss.str ().c_str ());
12101242 }
12111243
1212- monitorModes = res; return ;
1244+ monitorModes = res;
1245+ return ;
12131246 }
1247+
12141248}
12151249
12161250_Use_decl_annotations_
@@ -1793,8 +1827,8 @@ void SwapChainProcessor::RunCore()
17931827const UINT64 MHZ = 1000000 ;
17941828const UINT64 KHZ = 1000 ;
17951829
1796- constexpr DISPLAYCONFIG_VIDEO_SIGNAL_INFO dispinfo (UINT32 h, UINT32 v, UINT32 r ) {
1797- const UINT32 clock_rate = r * (v + 4 ) * (v + 4 ) + 1000 ;
1830+ constexpr DISPLAYCONFIG_VIDEO_SIGNAL_INFO dispinfo (UINT32 h, UINT32 v, UINT32 rn, UINT32 rd ) {
1831+ const UINT32 clock_rate = rn * (v + 4 ) * (v + 4 ) / rd + 1000 ;
17981832 return {
17991833 clock_rate, // pixel clock rate [Hz]
18001834 { clock_rate, v + 4 }, // fractional horizontal refresh rate [Hz]
@@ -2244,7 +2278,7 @@ NTSTATUS IddSampleParseMonitorDescription(const IDARG_IN_PARSEMONITORDESCRIPTION
22442278 vddlog (" d" , logStream.str ().c_str ());
22452279
22462280 for (int i = 0 ; i < monitorModes.size (); i++) {
2247- s_KnownMonitorModes2.push_back (dispinfo (std::get<0 >(monitorModes[i]), std::get<1 >(monitorModes[i]), std::get<2 >(monitorModes[i])));
2281+ s_KnownMonitorModes2.push_back (dispinfo (std::get<0 >(monitorModes[i]), std::get<1 >(monitorModes[i]), std::get<2 >(monitorModes[i]), std::get< 3 >(monitorModes[i]) ));
22482282 }
22492283 pOutArgs->MonitorModeBufferOutputCount = (UINT )monitorModes.size ();
22502284
@@ -2299,23 +2333,25 @@ NTSTATUS IddSampleMonitorGetDefaultModes(IDDCX_MONITOR MonitorObject, const IDAR
22992333// / <summary>
23002334// / Creates a target mode from the fundamental mode attributes.
23012335// / </summary>
2302- void CreateTargetMode (DISPLAYCONFIG_VIDEO_SIGNAL_INFO & Mode, UINT Width, UINT Height, UINT VSync )
2336+ void CreateTargetMode (DISPLAYCONFIG_VIDEO_SIGNAL_INFO & Mode, UINT Width, UINT Height, UINT VSyncNum, UINT VSyncDen )
23032337{
23042338 stringstream logStream;
23052339 logStream << " Creating target mode with Width: " << Width
23062340 << " , Height: " << Height
2307- << " , VSync: " << VSync;
2341+ << " , VSyncNum: " << VSyncNum
2342+ << " , VSyncDen: " << VSyncDen;
23082343 vddlog (" d" , logStream.str ().c_str ());
23092344
23102345 Mode.totalSize .cx = Mode.activeSize .cx = Width;
23112346 Mode.totalSize .cy = Mode.activeSize .cy = Height;
23122347 Mode.AdditionalSignalInfo .vSyncFreqDivider = 1 ;
23132348 Mode.AdditionalSignalInfo .videoStandard = 255 ;
2314- Mode.vSyncFreq .Numerator = VSync;
2315- Mode.vSyncFreq .Denominator = Mode.hSyncFreq .Denominator = 1 ;
2316- Mode.hSyncFreq .Numerator = VSync * Height;
2349+ Mode.vSyncFreq .Numerator = VSyncNum;
2350+ Mode.vSyncFreq .Denominator = VSyncDen;
2351+ Mode.hSyncFreq .Numerator = VSyncNum * Height;
2352+ Mode.hSyncFreq .Denominator = VSyncDen;
23172353 Mode.scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE ;
2318- Mode.pixelRate = VSync * Width * Height;
2354+ Mode.pixelRate = VSyncNum * Width * Height / VSyncDen ;
23192355
23202356 logStream.str (" " );
23212357 logStream << " Target mode configured with:"
@@ -2328,18 +2364,19 @@ void CreateTargetMode(DISPLAYCONFIG_VIDEO_SIGNAL_INFO& Mode, UINT Width, UINT He
23282364 vddlog (" d" , logStream.str ().c_str ());
23292365}
23302366
2331- void CreateTargetMode (IDDCX_TARGET_MODE & Mode, UINT Width, UINT Height, UINT VSync )
2367+ void CreateTargetMode (IDDCX_TARGET_MODE & Mode, UINT Width, UINT Height, UINT VSyncNum, UINT VSyncDen )
23322368{
23332369 Mode.Size = sizeof (Mode);
2334- CreateTargetMode (Mode.TargetVideoSignalInfo .targetVideoSignalInfo , Width, Height, VSync );
2370+ CreateTargetMode (Mode.TargetVideoSignalInfo .targetVideoSignalInfo , Width, Height, VSyncNum, VSyncDen );
23352371}
23362372
2337- void CreateTargetMode2 (IDDCX_TARGET_MODE2 & Mode, UINT Width, UINT Height, UINT VSync )
2373+ void CreateTargetMode2 (IDDCX_TARGET_MODE2 & Mode, UINT Width, UINT Height, UINT VSyncNum, UINT VSyncDen )
23382374{
23392375 stringstream logStream;
23402376 logStream << " Creating IDDCX_TARGET_MODE2 with Width: " << Width
23412377 << " , Height: " << Height
2342- << " , VSync: " << VSync;
2378+ << " , VSyncNum: " << VSyncNum
2379+ << " , VSyncDen: " << VSyncDen;
23432380 vddlog (" d" , logStream.str ().c_str ());
23442381
23452382 Mode.Size = sizeof (Mode);
@@ -2356,7 +2393,7 @@ void CreateTargetMode2(IDDCX_TARGET_MODE2& Mode, UINT Width, UINT Height, UINT V
23562393 << " and BitsPerComponent.Rgb: " << Mode.BitsPerComponent .Rgb ;
23572394 vddlog (" d" , logStream.str ().c_str ());
23582395
2359- CreateTargetMode (Mode.TargetVideoSignalInfo .targetVideoSignalInfo , Width, Height, VSync );
2396+ CreateTargetMode (Mode.TargetVideoSignalInfo .targetVideoSignalInfo , Width, Height, VSyncNum, VSyncDen );
23602397}
23612398
23622399_Use_decl_annotations_
@@ -2375,7 +2412,7 @@ NTSTATUS IddSampleMonitorQueryModes(IDDCX_MONITOR MonitorObject, const IDARG_IN_
23752412 // report the available set of modes for a given output as the intersection of monitor modes with target modes.
23762413
23772414 for (int i = 0 ; i < monitorModes.size (); i++) {
2378- CreateTargetMode (TargetModes[i], std::get<0 >(monitorModes[i]), std::get<1 >(monitorModes[i]), std::get<2 >(monitorModes[i]));
2415+ CreateTargetMode (TargetModes[i], std::get<0 >(monitorModes[i]), std::get<1 >(monitorModes[i]), std::get<2 >(monitorModes[i]), std::get< 3 >(monitorModes[i]) );
23792416
23802417 logStream.str (" " );
23812418 logStream << " Created target mode " << i << " : Width = " << std::get<0 >(monitorModes[i])
@@ -2508,7 +2545,7 @@ NTSTATUS IddSampleEvtIddCxParseMonitorDescription2(
25082545 vddlog (" d" , logStream.str ().c_str ());
25092546
25102547 for (int i = 0 ; i < monitorModes.size (); i++) {
2511- s_KnownMonitorModes2.push_back (dispinfo (std::get<0 >(monitorModes[i]), std::get<1 >(monitorModes[i]), std::get<2 >(monitorModes[i])));
2548+ s_KnownMonitorModes2.push_back (dispinfo (std::get<0 >(monitorModes[i]), std::get<1 >(monitorModes[i]), std::get<2 >(monitorModes[i]), std::get< 3 >(monitorModes[i]) ));
25122549 }
25132550 pOutArgs->MonitorModeBufferOutputCount = (UINT )monitorModes.size ();
25142551
@@ -2576,7 +2613,7 @@ NTSTATUS IddSampleEvtIddCxMonitorQueryTargetModes2(
25762613 logStream << " Creating target modes:" ;
25772614
25782615 for (int i = 0 ; i < monitorModes.size (); i++) {
2579- CreateTargetMode2 (TargetModes[i], std::get<0 >(monitorModes[i]), std::get<1 >(monitorModes[i]), std::get<2 >(monitorModes[i]));
2616+ CreateTargetMode2 (TargetModes[i], std::get<0 >(monitorModes[i]), std::get<1 >(monitorModes[i]), std::get<2 >(monitorModes[i]), std::get< 3 >(monitorModes[i]) );
25802617 logStream << " \n TargetModeIndex: " << i
25812618 << " \n Width: " << std::get<0 >(monitorModes[i])
25822619 << " \n Height: " << std::get<1 >(monitorModes[i])
0 commit comments