]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Lagless vsync changes.
authorToni Wilen <twilen@winuae.net>
Sun, 19 Aug 2018 15:42:40 +0000 (18:42 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 19 Aug 2018 15:42:40 +0000 (18:42 +0300)
custom.cpp
events.cpp
include/events.h
od-win32/win32.cpp
od-win32/win32gfx.cpp

index 60c166179621d5548c2fa27ccf48f223f0a96a73..dd28e26a761a9fc75a4eca31f4a6252cc80e98bb 100644 (file)
@@ -7940,19 +7940,21 @@ static bool framewait (void)
                        frame_rendered = render_screen(0, 1, false);
                        t = read_processor_time () - start;
                }
-               while (!currprefs.turbo_emulation) {
-                       float v = rpt_vsync (clockadjust) / (syncbase / 1000.0);
-                       if (v >= -2)
-                               break;
-                       rtg_vsynccheck ();
-                       maybe_process_pull_audio();
-                       if (cpu_sleep_millis(1) < 0)
-                               break;
-               }
-               while (rpt_vsync (clockadjust) < 0) {
-                       rtg_vsynccheck ();
-                       if (audio_is_pull_event())
-                               break;
+               if (!currprefs.cpu_thread) {
+                       while (!currprefs.turbo_emulation) {
+                               float v = rpt_vsync(clockadjust) / (syncbase / 1000.0);
+                               if (v >= -2)
+                                       break;
+                               rtg_vsynccheck();
+                               maybe_process_pull_audio();
+                               if (cpu_sleep_millis(1) < 0)
+                                       break;
+                       }
+                       while (rpt_vsync(clockadjust) < 0) {
+                               rtg_vsynccheck();
+                               if (audio_is_pull_event())
+                                       break;
+                       }
                }
                idletime += read_processor_time() - start;
                curr_time = read_processor_time ();
@@ -8671,9 +8673,11 @@ static int display_slice_cnt;
 static int display_slice_lines;
 static int display_slices;
 static bool display_rendered;
+static int vsyncnextstep;
 
 static bool linesync_beam_single_dual(void)
 {
+       bool was_syncline = is_syncline != 0;
        frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase;
        int vp;
 
@@ -8732,35 +8736,58 @@ static bool linesync_beam_single_dual(void)
 
 static bool linesync_beam_single_single(void)
 {
+       bool was_syncline = is_syncline != 0;
        frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase;
        int vp;
 
        if (is_last_line()) {
-               do_render_slice(-1, 0, vpos);
-               while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
-                       maybe_process_pull_audio();
-                       target_spin(0);
-                       vp = target_get_display_scanline(-1);
-                       if (vp >= 0)
-                               break;
+               if (vsyncnextstep != 1) {
+                       vsyncnextstep = 1;
+                       do_render_slice(-1, 0, vpos);
+                       while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
+                               maybe_process_pull_audio();
+                               vp = target_get_display_scanline(-1);
+                               if (vp >= 0)
+                                       break;
+                               if (currprefs.m68k_speed < 0 && !was_syncline) {
+                                       is_syncline = -3;
+                                       return 0;
+                               }
+                               target_spin(0);
+                       }
                }
-               vsync_clear();
-               while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
-                       maybe_process_pull_audio();
-                       vp = target_get_display_scanline(-1);
-                       if (vp >= vsync_activeheight - 1 || vp < 0)
-                               break;
-                       scanlinesleep(vp, vsync_activeheight - 1);
+               if (vsyncnextstep != 2) {
+                       vsyncnextstep = 2;
+                       vsync_clear();
+                       while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
+                               maybe_process_pull_audio();
+                               vp = target_get_display_scanline(-1);
+                               if (vp >= vsync_activeheight - 1 || vp < 0)
+                                       break;
+                               if (currprefs.m68k_speed < 0 && !was_syncline) {
+                                       is_syncline = -2;
+                                       is_syncline_end = vsync_activeheight - 1;
+                                       return 0;
+                               }
+                               scanlinesleep(vp, vsync_activeheight - 1);
+                       }
                }
-               frame_rendered = true;
-               frame_shown = true;
-               do_display_slice();
-               while (vp >= vsync_activeheight / 2 && !currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
-                       maybe_process_pull_audio();
-                       target_spin(0);
-                       vp = target_get_display_scanline(-1);
-                       if (vp < vsync_activeheight / 2)
-                               break;
+               if (vsyncnextstep != 3) {
+                       vsyncnextstep = 3;
+                       do_display_slice();
+                       frame_rendered = true;
+                       frame_shown = true;
+                       while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
+                               maybe_process_pull_audio();
+                               vp = target_get_display_scanline(-1);
+                               if (vp < vsync_activeheight / 2)
+                                       break;
+                               if (currprefs.m68k_speed < 0 && !was_syncline) {
+                                       is_syncline = -(100 + vsync_activeheight / 2);
+                                       return 0;
+                               }
+                               target_spin(0);
+                       }
                }
                return true;
        }
@@ -8941,6 +8968,10 @@ static bool linesync_beam_multi_single(void)
                                if (vp != -1)
                                        break;
                                maybe_process_pull_audio();
+                               if (currprefs.m68k_speed < 0 && !was_syncline) {
+                                       is_syncline = -3;
+                                       return 0;
+                               }
                                target_spin(0);
                        }
                        vsync_clear();
@@ -9031,6 +9062,11 @@ static bool linesync_beam_multi_single(void)
                                        // We are still in vblank and second slice? Poll until vblank ends.
                                        if (display_slice_cnt == 1 && vp == -1) {
                                                maybe_process_pull_audio();
+                                               if (currprefs.m68k_speed < 0 && !was_syncline) {
+                                                       is_syncline = -3;
+                                                       return 0;
+                                               }
+
                                                target_spin(0);
 #if LLV_DEBUG
                                                write_log(_T("3:%d:%d:%d:%d."), vpos, vp, nextwaitvpos, vsyncnextscanline);
@@ -9391,7 +9427,11 @@ static void hsync_handler_post (bool onvsync)
 #endif
        bool input_read_done = false;
 
-       if (isvsync_chipset() < 0) {
+       if (currprefs.cpu_thread) {
+
+               maybe_process_pull_audio();
+
+       } else if (isvsync_chipset() < 0) {
 
                if (currprefs.gfx_display_sections <= 1) {
                        if (vsync_vblank >= 85)
@@ -9420,10 +9460,10 @@ static void hsync_handler_post (bool onvsync)
                                frame_time_t rpt = read_processor_time ();
                                while (vsync_isdone(NULL) <= 0 && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) {
                                        maybe_process_pull_audio();
-                                       if (!execute_other_cpu(rpt + vsynctimebase / 10)) {
+//                                     if (!execute_other_cpu(rpt + vsynctimebase / 10)) {
                                                if (cpu_sleep_millis(1) < 0)
                                                        break;
-                                       }
+//                                     }
                                        rpt = read_processor_time ();
                                }
                        } else if (currprefs.m68k_speed_throttle) {
@@ -9497,10 +9537,10 @@ static void hsync_handler_post (bool onvsync)
                                // sleep if more than 2ms "free" time
                                while (vsync_isdone(NULL) <= 0 && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) {
                                        maybe_process_pull_audio();
-                                       if (!execute_other_cpu(rpt + vsynctimebase / 10)) {
+//                                     if (!execute_other_cpu(rpt + vsynctimebase / 10)) {
                                                if (cpu_sleep_millis(1) < 0)
                                                        break;
-                                       }
+//                                     }
                                        rpt = read_processor_time();
                                }
                        }
@@ -9646,6 +9686,7 @@ static void hsync_handler (void)
        bool vs = is_custom_vsync ();
        hsync_handler_pre (vs);
        if (vs) {
+               vsyncmintimepre = read_processor_time();
                vsync_handler_pre ();
                if (savestate_check ()) {
                        uae_reset (0, 0);
index 5d06c84ef74c36f21b6057457ee39a60acf13b9c..c98a933928a4ff1b67d1eabf7cf1d28696e2bf3e 100644 (file)
@@ -30,7 +30,8 @@ long cycles_to_hsync_event;
 unsigned long start_cycles;
 bool event_wait;
 
-frame_time_t vsyncmintime, vsyncmaxtime, vsyncwaittime;
+frame_time_t vsyncmintime, vsyncmintimepre;
+frame_time_t vsyncmaxtime, vsyncwaittime;
 int vsynctimebase;
 int event2_count;
 
@@ -127,6 +128,29 @@ static bool event_check_vsync(void)
                vsync_clear();
                vsync_event_done();
 
+       } else if (is_syncline == -3) {
+               if (!isvsync_chipset()) {
+                       events_reset_syncline();
+                       return false;
+               }
+               // not vblank
+               audio_finish_pull();
+               int vp = target_get_display_scanline(-1);
+               if (vp <= 0) {
+#ifdef WITH_PPC
+                       if (ppc_state) {
+                               uae_ppc_execute_quick();
+                       }
+#endif
+                       if (currprefs.cachesize)
+                               pissoff = pissoff_value;
+                       else
+                               pissoff = pissoff_nojit_value;
+                       return true;
+               }
+               vsync_clear();
+               vsync_event_done();
+
        } else if (is_syncline > 0) {
 
                if (!isvsync_chipset()) {
@@ -150,6 +174,30 @@ static bool event_check_vsync(void)
                }
                vsync_event_done();
 
+       }
+       else if (is_syncline <= -100) {
+
+               if (!isvsync_chipset()) {
+                       events_reset_syncline();
+                       return false;
+               }
+               audio_finish_pull();
+               // wait for specific scanline
+               int vp = target_get_display_scanline(-1);
+               if (vp < 0 || vp >= (-(is_syncline + 100))) {
+#ifdef WITH_PPC
+                       if (ppc_state) {
+                               uae_ppc_execute_check();
+                       }
+#endif
+                       if (currprefs.cachesize)
+                               pissoff = pissoff_value;
+                       else
+                               pissoff = pissoff_nojit_value;
+                       return true;
+               }
+               vsync_event_done();
+
        } else if (is_syncline == -10) {
 
                // wait is_syncline_end
@@ -206,16 +254,22 @@ static bool event_check_vsync(void)
 void do_cycles_slow (unsigned long cycles_to_add)
 {
 #ifdef WITH_X86
+#if 0
        if (x86_turbo_on) {
                execute_other_cpu_single();
        }
+#endif
 #endif
 
-       if ((pissoff -= cycles_to_add) >= 0)
-               return;
+       if (!currprefs.cpu_thread) {
+               if ((pissoff -= cycles_to_add) >= 0)
+                       return;
 
-       cycles_to_add = -pissoff;
-       pissoff = 0;
+               cycles_to_add = -pissoff;
+               pissoff = 0;
+       } else {
+               pissoff = 0x40000000;
+       }
 
        while ((nextevent - currcycle) <= cycles_to_add) {
 
index e933413f53490afc7873007c9c06b9959292c4e8..ee580416ac643f9042e0f42fb1f565421cf6d074 100644 (file)
@@ -18,7 +18,8 @@
 
 #include "machdep/rpt.h"
 
-extern frame_time_t vsyncmintime, vsyncmaxtime, vsyncwaittime;
+extern frame_time_t vsyncmintime, vsyncmintimepre;
+extern frame_time_t vsyncmaxtime, vsyncwaittime;
 extern int vsynctimebase, syncbase;
 extern void reset_frame_rate_hack (void);
 extern unsigned long int vsync_cycles;
index 3820456b355ce4fa5b24cc78dcb78b0876148d1c..88f95083ecaec4c489b6017c2d14a6fc88fcbe25 100644 (file)
@@ -280,7 +280,7 @@ int target_sleep_nanos(int nanos)
        return 0;
 }
 
-static uae_u64 spincount;
+uae_u64 spincount;
 
 void target_spin(int total)
 {
@@ -302,7 +302,9 @@ void target_calibrate_spin(void)
        struct amigadisplay *ad = &adisplays[0];
        struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
        int vp;
+       uae_u64 sc;
 
+       sc = 0;
        spincount = 0;
        if (!ap->gfx_vsyncmode)
                return;
@@ -311,7 +313,7 @@ void target_calibrate_spin(void)
                return;
        }
        write_log(_T("target_calibrate_spin() start\n"));
-       spincount = 0x800000000000;
+       sc = 0x800000000000;
        for (int i = 0; i < 50; i++) {
                for (;;) {
                        vp = target_get_display_scanline(-1);
@@ -337,19 +339,20 @@ void target_calibrate_spin(void)
                                goto fail;
                        if (vp2 == vp + 2) {
                                uae_u64 sc = __rdtsc() - v1;
-                               if (spincount > sc)
-                                       spincount = sc;
+                               if (sc > sc)
+                                       sc = sc;
                        }
                        if (vp2 != vp + 1)
                                break;
                }
 trynext:;
        }
-       if (spincount == 0x800000000000) {
-               write_log(_T("Spincount calculation error, spinloop not used.\n"), spincount);
+       if (sc == 0x800000000000) {
+               write_log(_T("Spincount calculation error, spinloop not used.\n"), sc);
                spincount = 0;
        } else {
-               write_log(_T("Spincount = %llu\n"), spincount);
+               spincount = sc;
+               write_log(_T("Spincount = %llu\n"), sc);
        }
        return;
 fail:
index f1d005acb7b96a7fd7c7b96a10ab858f81c1ff03..ee8afd59d6d3d30eb14be1021708c139eaa2c665 100644 (file)
@@ -338,7 +338,7 @@ typedef NTSTATUS(CALLBACK* D3DKMTWAITFORVERTICALBLANKEVENT)(const D3DKMT_WAITFOR
 static D3DKMTWAITFORVERTICALBLANKEVENT pD3DKMTWaitForVerticalBlankEvent;
 #define STATUS_SUCCESS ((NTSTATUS)0)
 
-int target_get_display_scanline(int displayindex)
+static int target_get_display_scanline2(int displayindex)
 {
        if (pD3DKMTGetScanLine) {
                D3DKMT_GETSCANLINE sl = { 0 };
@@ -371,6 +371,24 @@ int target_get_display_scanline(int displayindex)
        return -13;
 }
 
+extern uae_u64 spincount;;
+int target_get_display_scanline(int displayindex)
+{
+       static uae_u64 lastrdtsc;
+       static int lastvpos;
+       if (spincount == 0 || currprefs.m68k_speed >= 0) {
+               lastrdtsc = 0;
+               lastvpos = target_get_display_scanline2(displayindex);
+               return lastvpos;
+       }
+       uae_u64 v = __rdtsc();
+       if (lastrdtsc > v)
+               return lastvpos;
+       lastvpos = target_get_display_scanline2(displayindex);
+       lastrdtsc = __rdtsc() + spincount * 4;
+       return lastvpos;
+}
+
 typedef LONG(CALLBACK* QUERYDISPLAYCONFIG)(UINT32, UINT32*, DISPLAYCONFIG_PATH_INFO*, UINT32*, DISPLAYCONFIG_MODE_INFO*, DISPLAYCONFIG_TOPOLOGY_ID*);
 typedef LONG(CALLBACK* GETDISPLAYCONFIGBUFFERSIZES)(UINT32, UINT32*, UINT32*);
 typedef LONG(CALLBACK* DISPLAYCONFIGGETDEVICEINFO)(DISPLAYCONFIG_DEVICE_INFO_HEADER*);