]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Lagless vsync updates, including autoscale compatibility.
authorToni Wilen <twilen@winuae.net>
Sun, 22 Apr 2018 09:10:57 +0000 (12:10 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 22 Apr 2018 09:10:57 +0000 (12:10 +0300)
custom.cpp
drawing.cpp
include/uae.h
od-win32/direct3d.cpp
od-win32/direct3d11.cpp
od-win32/win32.cpp
od-win32/win32_scaler.cpp
od-win32/win32gfx.cpp

index 00ccc660460704177dd53829fa07632128b3497e..86b50e9199beab8dd2b5df9220e818ba5892f3b7 100644 (file)
@@ -8111,9 +8111,9 @@ static bool is_custom_vsync (void)
        return false;
 }
 
-static bool do_render_slice(int mode, int slicecnt)
+static bool do_render_slice(int mode, int slicecnt, int lastline)
 {
-       draw_lines(vpos, slicecnt);
+       draw_lines(lastline, slicecnt);
        render_screen(0, mode, true);
        return true;
 }
@@ -8244,7 +8244,7 @@ static void scanlinesleep(int currline, int nextline)
                return;
        int diff = vsync_hblank / (nextline - currline);
        int us = 1000000 / diff;
-       if (us < 1300) { // spin if less than 1.3ms
+       if (us < target_sleep_nanos(-1)) { // spin if less than minimum sleep time
                target_spin(nextline - currline - 1);
                return;
        }
@@ -8267,9 +8267,8 @@ static bool linesync_beam_single(void)
        frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase;
 
        is_syncline = 0;
-       maybe_process_pull_audio();
        if (is_last_line()) {
-               do_render_slice(-1, 0);
+               do_render_slice(-1, 0, vpos - 1);
                while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
                        maybe_process_pull_audio();
                        target_spin(0);
@@ -8299,16 +8298,15 @@ static bool linesync_beam_single(void)
        return false;
 }
 
-
 static bool linesync_beam_multi_dual(void)
 {
+       frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase;
        static int vsyncnextscanline;
        static int nextwaitvpos;
        static int display_slice_cnt;
        static int display_slice_lines;
        static int display_slices;
        static bool display_rendered;
-       frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase;
        bool input_read_done = false;
        bool was_syncline = is_syncline != 0;
 
@@ -8341,7 +8339,7 @@ static bool linesync_beam_multi_dual(void)
                if (display_slice_cnt == 0) {
 
                        if (!was_syncline) {
-                               do_render_slice(1, display_slice_cnt);
+                               do_render_slice(is_last_line() ? 1 : 2, display_slice_cnt, vpos - 1);
                                display_rendered = true;
                        }
                        while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
@@ -8361,7 +8359,7 @@ static bool linesync_beam_multi_dual(void)
 
                        if (!currprefs.turbo_emulation) {
                                if (!was_syncline && !display_rendered) {
-                                       do_render_slice(0, display_slice_cnt);
+                                       do_render_slice(0, display_slice_cnt, vpos - 1);
                                        display_rendered = true;
                                }
                                while(sync_timeout_check(maxtime)) {
@@ -8409,6 +8407,7 @@ static bool linesync_beam_multi_dual(void)
 
 static bool linesync_beam_multi_single(void)
 {
+       frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase;
        static int vsyncnextscanline;
        static int vsyncnextscanline_add;
        static int nextwaitvpos;
@@ -8416,7 +8415,6 @@ static bool linesync_beam_multi_single(void)
        static int display_slice_lines;
        static int display_slices;
        static bool display_rendered;
-       frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase;
        bool input_read_done = false;
        bool was_syncline = is_syncline != 0;
 
@@ -8449,7 +8447,7 @@ static bool linesync_beam_multi_single(void)
        if (is_last_line()) {
 
                if (!was_syncline && !display_rendered) {
-                       do_render_slice(0, display_slice_cnt);
+                       do_render_slice(1, display_slice_cnt, vpos - 1);
                        display_rendered = true;
                }
                // if 2 slices: make sure we are out of vblank.
@@ -8495,7 +8493,7 @@ static bool linesync_beam_multi_single(void)
 
                                if (!currprefs.turbo_emulation) {
                                        if (!was_syncline) {
-                                               do_render_slice(1, display_slice_cnt);
+                                               do_render_slice(2, display_slice_cnt, vpos - 1);
                                                display_rendered = true;
                                        }
 
@@ -8525,7 +8523,7 @@ static bool linesync_beam_multi_single(void)
 
                                if (!currprefs.turbo_emulation) {
                                        if (!was_syncline) {
-                                               do_render_slice(1, display_slice_cnt);
+                                               do_render_slice(2, display_slice_cnt, vpos - 1);
                                                display_rendered = true;
                                        }
 
@@ -8574,7 +8572,7 @@ static bool linesync_beam_multi_single(void)
                        int vp2 = target_get_display_scanline(-1);
                        if (!currprefs.turbo_emulation && (currprefs.m68k_speed < 0 || vp2 < vsyncnextscanline - vsyncnextscanline_add / 10)) {
                                if (!was_syncline && !display_rendered) {
-                                       do_render_slice(0, display_slice_cnt);
+                                       do_render_slice(0, display_slice_cnt, vpos - 1);
                                        display_rendered = true;
                                }
                                while (sync_timeout_check(maxtime)) {
index 3fba5c67f6657258a191442f355c5966d76da034..99781f7f747007699aac2e03868c6937db820321 100644 (file)
@@ -3700,6 +3700,8 @@ static void draw_frame_extras(struct vidbuffer *vb, int y_start, int y_end)
                refresh_indicator_update(vb);
 }
 
+extern bool beamracer_debug;
+
 void draw_lines(int end, int section)
 {
        int monid = 0;
@@ -3708,6 +3710,11 @@ void draw_lines(int end, int section)
        int y_start = -1;
        int y_end = -1;
 
+       static bool section_toggle;
+
+       if (section == 0)
+               section_toggle = !section_toggle;
+
        end -= minfirstline;
        if (end < 0)
                return;
@@ -3719,6 +3726,8 @@ void draw_lines(int end, int section)
                        return;
        }
 
+       int section_color_cnt = 4;
+
        vidinfo->outbuffer = vb;
        if (!lockscr(vb, false, vb->last_drawn_line ? false : true))
                return;
@@ -3740,12 +3749,20 @@ void draw_lines(int end, int section)
                hposblank = 0;
                pfield_draw_line(vb, line, whereline, wherenext);
 
-#if 0
-               static const int section_colors[] = { 0x777, 0xf00, 0x0f0, 0x00f };
-               int color = section_colors[section & 3];
-               xlinebuffer = row_map[whereline];
-               for (int x = 0; x < 4; x++) {
-                       putpixel(xlinebuffer, NULL, vidinfo->drawbuffer.pixbytes, x, xcolors[color], 1);
+#if 1
+               if (beamracer_debug) {
+                       if (vb->last_drawn_line == end - 4) {
+                               section_color_cnt = 4;
+                       }
+                       if (section_color_cnt > 0) {
+                               section_color_cnt--;
+                               static const int section_colors[] = { 0x777, 0xf00, 0x0f0, 0x00f };
+                               int color = section_toggle ? section_colors[section & 3] : 0;
+                               xlinebuffer = row_map[whereline];
+                               for (int x = 0; x < 4; x++) {
+                                       putpixel(xlinebuffer, NULL, vidinfo->drawbuffer.pixbytes, x, xcolors[color], 1);
+                               }
+                       }
                }
 #endif
 
@@ -3883,7 +3900,7 @@ static void finish_drawing_frame(bool drawlines)
                }
                if (multimon && locked) {
                        unlockscr(out, -1, -1);
-                       render_screen(out->monitor_id, 0, true);
+                       render_screen(out->monitor_id, 1, true);
                        show_screen(out->monitor_id, 0);
                }
        }
@@ -4232,7 +4249,7 @@ void freevidbuffer(int monid, struct vidbuffer *buf)
        memset (buf, 0, sizeof (struct vidbuffer));
 }
 
-void reset_drawing (void)
+void reset_drawing(void)
 {
        int monid = 0;
        struct amigadisplay *ad = &adisplays[monid];
index 7d1867ce7939be240e77839cdfe6cbe0aba583aa..6ea146c41ec0c5e707fe130832b95ed697e951d7 100644 (file)
@@ -37,7 +37,7 @@ extern void target_quit (void);
 extern void target_restart (void);
 extern void target_getdate(int *y, int *m, int *d);
 extern void target_cpu_speed(void);
-extern void target_sleep_nanos(int);
+extern int target_sleep_nanos(int);
 extern bool get_plugin_path (TCHAR *out, int size, const TCHAR *path);
 extern void stripslashes (TCHAR *p);
 extern void fixtrailing (TCHAR *p);
index 50f8dc07a7222fcf858f68a81a84e06facc4dc44..c7030c5683afdb849938fb5c2a063db8de9cc22a 100644 (file)
@@ -1842,7 +1842,7 @@ static bool xD3D_getscalerect(int monid, float *mx, float *my, float *sx, float
        return true;
 }
 
-static void setupscenecoords (struct d3dstruct *d3d)
+static void setupscenecoords (struct d3dstruct *d3d, bool normalrender)
 {
        int monid = d3d - d3ddata;
        struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo;
@@ -1851,6 +1851,9 @@ static void setupscenecoords (struct d3dstruct *d3d)
        float dw, dh;
        static RECT sr2[MAX_AMIGAMONITORS], dr2[MAX_AMIGAMONITORS], zr2[MAX_AMIGAMONITORS];
 
+       if (!normalrender)
+               return;
+
        //write_log (_T("%dx%d %dx%d %dx%d\n"), tin_w, tin_h, tin_w, tin_h, window_w, window_h);
 
        getfilterrect2 (monid, &dr, &sr, &zr, d3d->window_w, d3d->window_h, d3d->tin_w / d3d->dmult, d3d->tin_h / d3d->dmult, d3d->dmult, d3d->tin_w, d3d->tin_h);
@@ -3106,7 +3109,9 @@ static void D3D_render2(struct d3dstruct *d3d, int mode)
        if (!isd3d (d3d) || !d3d->texture)
                return;
 
-       if (mode > 0)
+       bool normalrender = mode < 0 || (mode & 1);
+
+       if (mode > 0 && (mode & 2))
                d3d->slicecnt = 0;
        else if (mode < 0)
                d3d->slicecnt = d3d->slicecnt == 2 ? 0 : d3d->slicecnt;
@@ -3161,7 +3166,7 @@ static void D3D_render2(struct d3dstruct *d3d, int mode)
                                masktexture = s->masktexture;
                }
 
-               setupscenecoords (d3d);
+               setupscenecoords(d3d, normalrender);
                hr = d3d->d3ddev->SetTransform (D3DTS_PROJECTION, &d3d->m_matProj);
                hr = d3d->d3ddev->SetTransform (D3DTS_VIEW, &d3d->m_matView);
                hr = d3d->d3ddev->SetTransform (D3DTS_WORLD, &d3d->m_matWorld);
@@ -3260,7 +3265,7 @@ static void D3D_render2(struct d3dstruct *d3d, int mode)
        } else {
 
                // non-shader version
-               setupscenecoords (d3d);
+               setupscenecoords (d3d, normalrender);
                hr = d3d->d3ddev->SetTransform (D3DTS_PROJECTION, &d3d->m_matProj);
                hr = d3d->d3ddev->SetTransform (D3DTS_VIEW, &d3d->m_matView);
                hr = d3d->d3ddev->SetTransform (D3DTS_WORLD, &d3d->m_matWorld);
index a1f8f69779717b5619e3e44861e14bfc80b09297..da943f35843ff14c91bd935a9e409a646d75dff9 100644 (file)
@@ -1460,10 +1460,13 @@ static bool UpdateBuffers(struct d3d11struct *d3d)
        return true;
 }
 
-static void setupscenecoords(struct d3d11struct *d3d)
+static void setupscenecoords(struct d3d11struct *d3d, bool normalrender)
 {
        RECT sr, dr, zr;
 
+       if (!normalrender)
+               return;
+
        getfilterrect2(d3d - d3d11data, &dr, &sr, &zr, d3d->m_screenWidth, d3d->m_screenHeight, d3d->m_bitmapWidth / d3d->dmult, d3d->m_bitmapHeight / d3d->dmult, d3d->dmult, d3d->m_bitmapWidth, d3d->m_bitmapHeight);
 
        if (!memcmp(&sr, &d3d->sr2, sizeof RECT) && !memcmp(&dr, &d3d->dr2, sizeof RECT) && !memcmp(&zr, &d3d->zr2, sizeof RECT)) {
@@ -4151,11 +4154,11 @@ static void CameraClass_Render(struct d3d11struct *d3d)
        xD3DXMatrixLookAtLH(&d3d->m_viewMatrix, &position, &lookAt, &up);
 }
 
-static bool GraphicsClass_Render(struct d3d11struct *d3d, float rotation)
+static bool GraphicsClass_Render(struct d3d11struct *d3d, float rotation, bool normalrender)
 {
        bool result;
 
-       setupscenecoords(d3d);
+       setupscenecoords(d3d, normalrender);
 
        // Generate the view matrix based on the camera's position.
        CameraClass_Render(d3d);
@@ -4309,7 +4312,7 @@ static bool xD3D11_renderframe(int monid, int mode, bool immediate)
 
        d3d->frames_since_init++;
 
-       if (mode > 0)
+       if (mode > 0 && (mode & 2))
                d3d->slicecnt = 0;
        else if (mode < 0)
                d3d->slicecnt = d3d->slicecnt == 2 ? 0 : d3d->slicecnt;
@@ -4331,7 +4334,7 @@ static bool xD3D11_renderframe(int monid, int mode, bool immediate)
        if (d3d->delayedfs || !d3d->texture2d || !d3d->d3dinit_done)
                return false;
 
-       GraphicsClass_Render(d3d, 0);
+       GraphicsClass_Render(d3d, 0, mode < 0 || (mode & 1));
 
        if (d3d->filenotificationhandle != NULL) {
                bool notify = false;
@@ -4508,7 +4511,7 @@ static bool xD3D11_alloctexture(int monid, int w, int h)
                d3d->delayedrestore = true;
        }
 
-       setupscenecoords(d3d);
+       setupscenecoords(d3d, true);
 
        changed_prefs.leds_on_screen |= STATUSLINE_TARGET;
        currprefs.leds_on_screen |= STATUSLINE_TARGET;
index 35cb99a2010d7a4dc7bc55b0c861087523598cff..ed774d03540a564b4cbadd11043c081119aa9991 100644 (file)
@@ -232,7 +232,7 @@ static CLOSETOUCHINPUTHANDLE pCloseTouchInputHandle;
 
 static ULONG ActualTimerResolution;
 
-void target_sleep_nanos(int nanos)
+int target_sleep_nanos(int nanos)
 {
        static bool init;
        if (!init) {
@@ -261,6 +261,8 @@ void target_sleep_nanos(int nanos)
                init = true;
        }
        if (pNtDelayExecution) {
+               if (nanos < 0)
+                       return 800;
                LARGE_INTEGER interval;
                int start = read_processor_time();
                nanos *= 10;
@@ -270,8 +272,11 @@ void target_sleep_nanos(int nanos)
                pNtDelayExecution(false, &interval);
                idletime += read_processor_time() - start;
        } else {
+               if (nanos < 0)
+                       return 1300;
                sleep_millis_main(1);
        }
+       return 0;
 }
 
 static uae_u64 spincount;
index b83c2fc71badf7d68ebfa5784f0b6ba3b601d0bc..d57d806c94407096af763484189b304de2a1fc1b 100644 (file)
@@ -1126,13 +1126,23 @@ void S2X_render(int monid, int y_start, int y_end)
        } else { /* null */
 
                if (amiga_depth == dst_depth) {
-                       uae_u8 *d = dptr, *s = sptr;
-                       int y;
                        int w = aw * dst_depth / 8;
-                       for (y = 0; y < ah && d + w <= enddptr; y++) {
-                               memcpy (d, s, w);
-                               s += vb->rowbytes;
-                               d += pitch;
+                       if (y_start < 0) {
+                               uae_u8 *d = dptr;
+                               uae_u8 *s = sptr;
+                               for (int y = 0; y < ah && d + w <= enddptr; y++) {
+                                       memcpy(d, s, w);
+                                       s += vb->rowbytes;
+                                       d += pitch;
+                               }
+                       } else {
+                               uae_u8 *d = dptr + y_start * pitch;
+                               uae_u8 *s = sptr + y_start * vb->rowbytes;
+                               for (int y = y_start; y < ah && y < y_end && d + w <= enddptr; y++) {
+                                       memcpy(d, s, w);
+                                       s += vb->rowbytes;
+                                       d += pitch;
+                               }
                        }
                }
                ok = 1;
index a72181dd745a33fc56bd5c1c048efc82f20cc7e3..839bd53456e1494fc358447f6b8391d44bf47a08 100644 (file)
@@ -102,6 +102,7 @@ int vsync_modechangetimeout = 10;
 
 int vsync_activeheight, vsync_totalheight;
 float vsync_vblank, vsync_hblank;
+bool beamracer_debug;
 
 int reopen(struct AmigaMonitor *, int, bool);
 
@@ -4094,6 +4095,10 @@ retry:
        if (isfullscreen () != 0)
                setmouseactive(mon->monitor_id, -1);
 
+       if (D3D_debug) {
+               D3D_debug(0, beamracer_debug);
+       }
+
        return 1;
 
 oops:
@@ -4198,10 +4203,11 @@ void updatewinfsmode(int monid, struct uae_prefs *p)
 bool toggle_3d_debug(void)
 {
        if (isvsync_chipset() < 0) {
+               beamracer_debug = !beamracer_debug;
                if (D3D_debug) {
-                       int d = D3D_debug(0, 0);
-                       D3D_debug(0, d ? 0 : 1);
+                       D3D_debug(0, beamracer_debug);
                }
+               reset_drawing();
                return true;
        }
        return false;