]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Lagless vsync updates (100/120Hz, BFI)
authorToni Wilen <twilen@winuae.net>
Sun, 8 Jul 2018 15:05:30 +0000 (18:05 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 8 Jul 2018 15:05:30 +0000 (18:05 +0300)
custom.cpp
main.cpp
od-win32/direct3d.cpp
od-win32/direct3d11.cpp
od-win32/win32gfx.cpp

index 71ddf1462cc48d32d9cd3c198df9974f4ffacda5..c683f3831dd91f27092e7dfb62cdf6fc5115121a 100644 (file)
@@ -7465,7 +7465,7 @@ static bool framewait (void)
                if (!frame_shown) {
                        show_screen(0, 1);
                        if (currprefs.gfx_apmode[0].gfx_strobo)
-                               show_screen(0, 2);
+                               show_screen(0, 4);
                }
 
                maybe_process_pull_audio();
@@ -8297,37 +8297,97 @@ static int display_slice_lines;
 static int display_slices;
 static bool display_rendered;
 
-static bool linesync_beam_single(void)
+static bool linesync_beam_single_dual(void)
 {
        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);
-                       int vp = target_get_display_scanline(-1);
+                       vp = target_get_display_scanline(-1);
                        if (vp >= 0)
                                break;
                }
+               vsyncmintime = read_processor_time() + vsynctimebase;
                vsync_clear();
                while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
                        maybe_process_pull_audio();
-                       int vp = target_get_display_scanline(-1);
+                       vp = target_get_display_scanline(-1);
                        if (vp >= vsync_activeheight - 1 || vp < 0)
                                break;
                        scanlinesleep(vp, vsync_activeheight - 1);
                }
+               frame_rendered = true;
+               frame_shown = true;
+               do_display_slice();
+               int vv = vsync_vblank;
+               while (vv >= 85) {
+                       while (!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;
+                       }
+                       while (!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;
+                       }
+                       show_screen(0, 3);
+                       while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
+                               maybe_process_pull_audio();
+                               target_spin(0);
+                               vp = target_get_display_scanline(-1);
+                               if (vp >= vsync_activeheight - 1 || vp < vsync_activeheight / 2)
+                                       break;
+                       }
+                       show_screen(0, 2);
+                       vv -= currprefs.ntscmode ? 60 : 50;
+               }
+               return true;
+       }
+       return false;
+}
+
+static bool linesync_beam_single_single(void)
+{
+       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);
-                       int vp = target_get_display_scanline(-1);
-                       if (vp < 0)
+                       vp = target_get_display_scanline(-1);
+                       if (vp >= 0)
+                               break;
+               }
+               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);
                }
                frame_rendered = true;
                frame_shown = true;
-               return do_display_slice();
+               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;
+               }
+               return true;
        }
        return false;
 }
@@ -8339,21 +8399,23 @@ static bool linesync_beam_multi_dual(void)
        bool was_syncline = is_syncline != 0;
 
        events_reset_syncline();
-       if (vpos == 0) {
+       if (vpos == 0 && !was_syncline) {
                int firstline, lastline;
                linesync_first_last_line(&firstline, &lastline);
 
                display_slices = currprefs.gfx_display_sections;
-               if (display_slices <= 0)
+               if (!display_slices)
                        display_slices = 1;
                display_slice_cnt = 0;
                vsyncnextscanline = vsync_activeheight / display_slices + 1;
+               vsyncnextscanline_add = vsync_activeheight / display_slices;
                display_slice_lines = (lastline - firstline) / display_slices + 1;
-               nextwaitvpos = firstline + display_slice_lines;
+               nextwaitvpos = firstline + display_slice_lines + display_slice_lines / 2;
                if (display_slices <= 1)
-                       nextwaitvpos = maxvpos_display + 1;
+                       nextwaitvpos = lastline + 1;
                if (display_slices <= 2 && vsyncnextscanline > vsync_activeheight * 2 / 3)
                        vsyncnextscanline = vsync_activeheight * 2 / 3;
+
                display_rendered = false;
                frame_rendered = true;
                frame_shown = true;
@@ -8370,15 +8432,15 @@ static bool linesync_beam_multi_dual(void)
                                do_render_slice(is_last_line() ? 1 : 2, display_slice_cnt, vpos);
                                display_rendered = true;
                        }
+
                        while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
-                               frame_time_t rpt = read_processor_time();
-                               if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -vsynctimebase * 2) {
-                                       vsyncmintime = rpt + vsynctimebase;
-                                       break;
-                               }
                                maybe_process_pull_audio();
                                target_spin(0);
+                               int vp = target_get_display_scanline(-1);
+                               if (vp >= vsync_activeheight - 1 || vp < 0)
+                                       break;
                        }
+
                        do_display_slice();
                        display_rendered = false;
                        input_read_done = true;
@@ -8407,22 +8469,48 @@ static bool linesync_beam_multi_dual(void)
                                        scanlinesleep(vp, vsyncnextscanline);
                                }
                                do_display_slice();
-                               input_read_done = true;
-                               display_rendered = false;
                        }
-                       vsyncnextscanline += vsync_activeheight / display_slices;
-                       vsync_clear();
 
                        if (is_last_line()) {
-                               // wait until about middle of second frame
-                               while (!currprefs.turbo_emulation) {
-                                       frame_time_t rpt = read_processor_time();
-                                       if ((int)rpt - ((int)vsyncmintime - vsynctimebase * 1 / 4) >= 0)
+                               // wait extra frames
+                               int vv = vsync_vblank;
+                               for(;;) {
+                                       while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
+                                               maybe_process_pull_audio();
+                                               target_spin(0);
+                                               int vp = target_get_display_scanline(-1);
+                                               if (vp >= vsync_activeheight - 1 || vp < 0)
+                                                       break;
+                                       }
+                                       show_screen(0, 3);
+                                       show_screen(0, 2);
+                                       while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
+                                               maybe_process_pull_audio();
+                                               target_spin(0);
+                                               int vp = target_get_display_scanline(-1);
+                                               if (vp >= vsync_activeheight / 2)
+                                                       break;
+                                       }
+                                       vv -= currprefs.ntscmode ? 60 : 50;
+                                       if (vv < 85)
                                                break;
-                                       maybe_process_pull_audio();
-                                       target_spin(0);
+
+                                       while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
+                                               maybe_process_pull_audio();
+                                               target_spin(0);
+                                               int vp = target_get_display_scanline(-1);
+                                               if (vp < vsync_activeheight / 2 && vp >= 0)
+                                                       break;
+                                       }
                                }
+
                        }
+
+                       input_read_done = true;
+                       display_rendered = false;
+
+                       vsyncnextscanline += vsync_activeheight / display_slices;
+                       vsync_clear();
                }
 
                nextwaitvpos += display_slice_lines;
@@ -8433,8 +8521,7 @@ static bool linesync_beam_multi_dual(void)
        return input_read_done;
 }
 
-
-static bool linesync_beam_vrr(void)
+static bool linesync_beam_multi_single(void)
 {
        frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase;
        bool input_read_done = false;
@@ -8472,6 +8559,17 @@ static bool linesync_beam_vrr(void)
                        do_render_slice(1, display_slice_cnt, vpos);
                        display_rendered = true;
                }
+               // if 2 slices: make sure we are out of vblank.
+               if (display_slices <= 2) {
+                       while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
+                               int vp = target_get_display_scanline(-1);
+                               if (vp != -1)
+                                       break;
+                               maybe_process_pull_audio();
+                               target_spin(0);
+                       }
+                       vsync_clear();
+               }
 
                while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
                        int vp = target_get_display_scanline(-1);
@@ -8501,52 +8599,54 @@ static bool linesync_beam_vrr(void)
                if (display_slice_cnt == 0) {
 
                        if (!currprefs.turbo_emulation) {
+                               if (!was_syncline) {
+                                       do_render_slice(2, display_slice_cnt, vpos - 1);
+                                       display_rendered = true;
+                               }
 
-                               frame_time_t rpt;
-                               for (;;) {
-                                       rpt = read_processor_time();
-                                       if ((int)rpt - (int)(vsyncmintime - vsynctimebase * 2 / 3) >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase)
-                                               break;
+                               // flip slightly early because flip regularly gets delayed if done during vblank
+                               int lastflipline = vsync_activeheight - vsyncnextscanline_add / 3;
+                               while (sync_timeout_check(maxtime)) {
+                                       int vp = target_get_display_scanline(-1);
                                        maybe_process_pull_audio();
+                                       if (vp < vsync_activeheight / 2 || vp >= lastflipline)
+                                               break;
                                        if (currprefs.m68k_speed < 0 && !was_syncline) {
-                                               is_syncline = -1;
-                                               is_syncline_end = target_get_display_scanline(-1);
+                                               is_syncline_end = lastflipline;
+                                               is_syncline = -2;
                                                return 0;
                                        }
                                        target_spin(0);
+#if LLV_DEBUG
+                                       write_log(_T("2:%d:%d:%d:%d."), vpos, vp, nextwaitvpos, vsyncnextscanline);
+#endif
                                }
+                               do_display_slice();
+                               display_rendered = false;
+                               input_read_done = true;
 
-                               if (!was_syncline) {
-                                       do_render_slice(2, display_slice_cnt, vpos - 1);
-                                       display_rendered = true;
-                               }
-
-                               for (;;) {
-                                       rpt = read_processor_time();
-                                       if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase)
+#if 1
+                               // if flipped before vblank, wait for vblank
+                               while (sync_timeout_check(maxtime)) {
+                                       int vp = target_get_display_scanline(-1);
+                                       if (vp < vsync_activeheight / 2)
                                                break;
-                                       maybe_process_pull_audio();
                                        if (currprefs.m68k_speed < 0 && !was_syncline) {
                                                is_syncline = -1;
-                                               is_syncline_end = target_get_display_scanline(-1);
+                                               is_syncline_end = vp;
                                                return 0;
                                        }
+                                       maybe_process_pull_audio();
                                        target_spin(0);
                                }
-
-                               if ((int)rpt - (int)vsyncmintime < vsynctimebase && (int)rpt - (int)vsyncmintime > -vsynctimebase) {
-                                       vsyncmintime += vsynctimebase;
-                               } else {
-                                       vsyncmintime = rpt + vsynctimebase;
-                               }
-                               do_display_slice();
-                               display_rendered = false;
-                               input_read_done = true;
+#endif
                        }
 
                } else {
 
-                       if (!currprefs.turbo_emulation) {
+                       // skip if too close
+                       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, vpos - 1);
                                        display_rendered = true;
@@ -8591,8 +8691,7 @@ static bool linesync_beam_vrr(void)
        return input_read_done;
 }
 
-
-static bool linesync_beam_multi_single(void)
+static bool linesync_beam_vrr(void)
 {
        frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase;
        bool input_read_done = false;
@@ -8630,17 +8729,6 @@ static bool linesync_beam_multi_single(void)
                        do_render_slice(1, display_slice_cnt, vpos);
                        display_rendered = true;
                }
-               // if 2 slices: make sure we are out of vblank.
-               if (display_slices <= 2) {
-                       while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
-                               int vp = target_get_display_scanline(-1);
-                               if (vp != -1)
-                                       break;
-                               maybe_process_pull_audio();
-                               target_spin(0);
-                       }
-                       vsync_clear();
-               }
 
                while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
                        int vp = target_get_display_scanline(-1);
@@ -8670,54 +8758,52 @@ static bool linesync_beam_multi_single(void)
                if (display_slice_cnt == 0) {
 
                        if (!currprefs.turbo_emulation) {
-                               if (!was_syncline) {
-                                       do_render_slice(2, display_slice_cnt, vpos - 1);
-                                       display_rendered = true;
-                               }
 
-                               // flip slightly early because flip regularly gets delayed if done during vblank
-                               int lastflipline = vsync_activeheight - vsyncnextscanline_add / 3;
-                               while (sync_timeout_check(maxtime)) {
-                                       int vp = target_get_display_scanline(-1);
-                                       maybe_process_pull_audio();
-                                       if (vp < vsync_activeheight / 2 || vp >= lastflipline)
+                               frame_time_t rpt;
+                               for (;;) {
+                                       rpt = read_processor_time();
+                                       if ((int)rpt - (int)(vsyncmintime - vsynctimebase * 2 / 3) >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase)
                                                break;
+                                       maybe_process_pull_audio();
                                        if (currprefs.m68k_speed < 0 && !was_syncline) {
-                                               is_syncline_end = lastflipline;
-                                               is_syncline = -2;
+                                               is_syncline = -1;
+                                               is_syncline_end = target_get_display_scanline(-1);
                                                return 0;
                                        }
                                        target_spin(0);
-#if LLV_DEBUG
-                                       write_log(_T("2:%d:%d:%d:%d."), vpos, vp, nextwaitvpos, vsyncnextscanline);
-#endif
                                }
-                               do_display_slice();
-                               display_rendered = false;
-                               input_read_done = true;
 
-#if 1
-                               // if flipped before vblank, wait for vblank
-                               while (sync_timeout_check(maxtime)) {
-                                       int vp = target_get_display_scanline(-1);
-                                       if (vp < vsync_activeheight / 2)
+                               if (!was_syncline) {
+                                       do_render_slice(2, display_slice_cnt, vpos - 1);
+                                       display_rendered = true;
+                               }
+
+                               for (;;) {
+                                       rpt = read_processor_time();
+                                       if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase)
                                                break;
+                                       maybe_process_pull_audio();
                                        if (currprefs.m68k_speed < 0 && !was_syncline) {
                                                is_syncline = -1;
-                                               is_syncline_end = vp;
+                                               is_syncline_end = target_get_display_scanline(-1);
                                                return 0;
                                        }
-                                       maybe_process_pull_audio();
                                        target_spin(0);
                                }
-#endif
+
+                               if ((int)rpt - (int)vsyncmintime < vsynctimebase && (int)rpt - (int)vsyncmintime > -vsynctimebase) {
+                                       vsyncmintime += vsynctimebase;
+                               } else {
+                                       vsyncmintime = rpt + vsynctimebase;
+                               }
+                               do_display_slice();
+                               display_rendered = false;
+                               input_read_done = true;
                        }
 
                } else {
 
-                       // skip if too close
-                       int vp2 = target_get_display_scanline(-1);
-                       if (!currprefs.turbo_emulation && (currprefs.m68k_speed < 0 || vp2 < vsyncnextscanline - vsyncnextscanline_add / 10)) {
+                       if (!currprefs.turbo_emulation) {
                                if (!was_syncline && !display_rendered) {
                                        do_render_slice(0, display_slice_cnt, vpos - 1);
                                        display_rendered = true;
@@ -8770,7 +8856,10 @@ void vsync_event_done(void)
                return;
        }
        if (currprefs.gfx_display_sections <= 1) {
-               linesync_beam_single();
+               if (vsync_vblank >= 85)
+                       linesync_beam_single_dual();
+               else
+                       linesync_beam_single_single();
        } else {
                if (currprefs.gfx_variable_sync)
                        linesync_beam_vrr();
@@ -8930,7 +9019,10 @@ static void hsync_handler_post (bool onvsync)
        if (isvsync_chipset() < 0) {
 
                if (currprefs.gfx_display_sections <= 1) {
-                       input_read_done = linesync_beam_single();
+                       if (vsync_vblank >= 85)
+                               input_read_done = linesync_beam_single_dual();
+                       else
+                               input_read_done = linesync_beam_single_single();
                } else {
                        if (currprefs.gfx_variable_sync)
                                input_read_done = linesync_beam_vrr();
index abc7f51a559652bc1d2a0ec60a88558cb62f2b23..8c048ec69ad110d64b64172b6b90ea4c76627319 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -181,7 +181,7 @@ void fixup_prefs_dimensions (struct uae_prefs *prefs)
                        if (ap->gfx_vsyncmode) {
                                if (ap->gfx_fullscreen != 0) {
                                        ap->gfx_backbuffers = 1;
-                                       ap->gfx_strobo = false;
+                                       ap->gfx_strobo = prefs->lightboost_strobo;
                                } else {
                                        ap->gfx_vsyncmode = 0;
                                        ap->gfx_vsync = 0;
index 8b95d7cb34f36d031b645dde651bb224f3f9104f..bcb78623f6a258f7fedd84b5e5c6e44c966f73f3 100644 (file)
@@ -3896,9 +3896,13 @@ static void xD3D_showframe_special (int monid, int mode)
                return;
        if (pause_emulation)
                return;
-       hr = d3d->d3ddev->Clear (0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, d3ddebug ? 0x80 : 0, 0), 0, 0);
-       D3D_showframe2 (d3d, true);
-       flushgpu (d3d,true);
+       if (mode == 2) {
+               hr = d3d->d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, d3ddebug ? 0x80 : 0, 0), 0, 0);
+       }
+       if (mode == 1) {
+               D3D_showframe2(d3d, true);
+       }
+       flushgpu(d3d, true);
 }
 
 static void xD3D_refresh (int monid)
index 63e62e6cd2dec034fa944a1db69485a6f0371892..6e0e9f5aeb54624512d24a261233664396e5263a 100644 (file)
@@ -262,7 +262,6 @@ struct d3d11struct
        bool blackscreen;
        int framecount;
        UINT syncinterval;
-       bool flipped;
        float vblank;
        DWM_FRAME_COUNT lastframe;
        int frames_since_init;
@@ -3154,23 +3153,24 @@ static bool device_error(struct d3d11struct *d3d)
        return false;
 }
 
-static void do_present(struct d3d11struct *d3d, int black)
+static void do_black(struct d3d11struct *d3d)
+{
+       float color[4];
+       color[0] = 0;
+       color[1] = 0;
+       color[2] = 0;
+       color[3] = 0;
+       // Clear the back buffer.
+       d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color);
+}
+
+static void do_present(struct d3d11struct *d3d)
 {
        struct amigadisplay *ad = &adisplays[d3d - d3d11data];
        struct apmode *apm = ad->picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE];
        HRESULT hr;
        UINT presentFlags = 0;
 
-       if (black) {
-               float color[4];
-               color[0] = 0;
-               color[1] = 0;
-               color[2] = 0;
-               color[3] = 0;
-               // Clear the back buffer.
-               d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color);
-       }
-
        int vsync = isvsync();
        UINT syncinterval = d3d->vblankintervals;
        // only if no vsync or low latency vsync
@@ -3180,7 +3180,6 @@ static void do_present(struct d3d11struct *d3d, int black)
                        syncinterval = 0;
                }
        }
-       d3d->flipped = true;
        if (!vsync) {
                if (apm->gfx_backbuffers == 0 || (presentFlags & DXGI_PRESENT_ALLOW_TEARING) || (apm->gfx_vflip == 0 && isfs(d3d) <= 0) || (isfs(d3d) > 0 && apm->gfx_vsyncmode))
                        syncinterval = 0;
@@ -3195,6 +3194,7 @@ static void do_present(struct d3d11struct *d3d, int black)
                        presentFlags |= DXGI_PRESENT_DO_NOT_WAIT;
                syncinterval = 0;
        }
+
        hr = d3d->m_swapChain->Present(syncinterval, presentFlags);
        if (currprefs.turbo_emulation && hr == DXGI_ERROR_WAS_STILL_DRAWING)
                hr = S_OK;
@@ -3583,6 +3583,12 @@ static int xxD3D11_init2(HWND ahwnd, int monid, int w_w, int w_h, int t_w, int t
        if (d3d->swapChainDesc.BufferCount < 2)
                d3d->swapChainDesc.BufferCount = 2;
 
+       if (d3d->swapChainDesc.BufferCount > 2 && isfullscreen() <= 0 && !apm->gfx_vsync) {
+               write_log(_T("Switch from triple buffer to double buffer (%d).\n"), apm->gfx_vflip);
+               d3d->swapChainDesc.BufferCount = 2;
+               apm->gfx_vflip = 0;
+       }
+
        d3d->swapChainDesc.SwapEffect = os_win8 ? (os_win10 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) : DXGI_SWAP_EFFECT_SEQUENTIAL;
        if (apm->gfx_vsyncmode && isfs(d3d) > 0 && !os_win10) {
                d3d->swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
@@ -3608,7 +3614,7 @@ static int xxD3D11_init2(HWND ahwnd, int monid, int w_w, int w_h, int t_w, int t
                int vsync = isvsync();
                int hzmult = 0;
                getvsyncrate(monid, *freq, &hzmult);
-               if (hzmult < 0 && !currprefs.gfx_variable_sync) {
+               if (hzmult < 0 && !currprefs.gfx_variable_sync && apm->gfx_vsyncmode == 0) {
                        if (!apm->gfx_strobo) {
                                d3d->vblankintervals = 2;
                        } else {
@@ -3916,9 +3922,7 @@ static void EndScene(struct d3d11struct *d3d)
        }
        SetEvent(flipevent);
 #endif
-       do_present(d3d, 0);
-       if (d3d->blackscreen)
-               do_present(d3d, 1);
+       do_present(d3d);
 }
 
 static void TextureShaderClass_RenderShader(struct d3d11struct *d3d)
@@ -4457,6 +4461,20 @@ static bool xD3D11_renderframe(int monid, int mode, bool immediate)
        return true;
 }
 
+static void xD3D11_showframe_special(int monid, int mode)
+{
+       struct d3d11struct *d3d = &d3d11data[monid];
+
+       if (d3d->invalidmode || d3d->delayedfs || !d3d->texture2d || !d3d->d3dinit_done)
+               return;
+       if (!d3d->m_swapChain)
+               return;
+       if (mode == 1)
+               do_present(d3d);
+       if (mode == 2)
+               do_black(d3d);
+}
+
 static void xD3D11_showframe(int monid)
 {
        struct d3d11struct *d3d = &d3d11data[monid];
@@ -4972,7 +4990,7 @@ void d3d11_select(void)
        D3D_flushtexture = xD3D11_flushtexture;
 
        D3D_showframe = xD3D11_showframe;
-       D3D_showframe_special = NULL;
+       D3D_showframe_special = xD3D11_showframe_special;
        D3D_guimode = xD3D11_guimode;
        D3D_getDC = xD3D_getDC;
        D3D_isenabled = xD3D11_isenabled;
index 04884d9766a2332c915b3d868f06331dfc8d346f..97b49af59213eb0c4b05dea816a38d00bfd17473 100644 (file)
@@ -513,6 +513,8 @@ static void display_param_init(struct AmigaMonitor *mon)
        vsync_vblank = 0;
        vsync_hblank = 0;
        get_display_vblank_params(-1, &vsync_activeheight, &vsync_totalheight, &vsync_vblank, &vsync_hblank);
+       if (vsync_vblank <= 0)
+               vsync_vblank = mon->currentmode.freq;
        // GPU scaled mode?
        if (vsync_activeheight > mon->currentmode.current_height) {
                float m = (float)vsync_activeheight / mon->currentmode.current_height;
@@ -1439,10 +1441,19 @@ void show_screen(int monid, int mode)
        struct amigadisplay *ad = &adisplays[monid];
        strobo_active = false;
        strobo_active2 = false;
+       struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
+
        gfx_lock();
-       if (mode == 2) {
-               if ((mon->currentmode.flags & DM_D3D) && D3D_showframe_special) {
-                       D3D_showframe_special(0, 1);
+       if (mode == 2 || mode == 3 || mode == 4) {
+               if ((mon->currentmode.flags & DM_D3D) && D3D_showframe_special && ap->gfx_strobo) {
+                       if (mode == 4) {
+                               // erase + render
+                               D3D_showframe_special(0, 2);
+                               D3D_showframe_special(0, 1);
+                       } else {
+                               // erase or render
+                               D3D_showframe_special(0, mode == 3 ? 2 : 1);
+                       }
                }
                gfx_unlock();
                return;
@@ -1452,7 +1463,7 @@ void show_screen(int monid, int mode)
                return;
        }
        if (mon->currentmode.flags & DM_D3D) {
-               struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
+#if 0
                if (ap->gfx_vsync < 0 && ap->gfx_strobo && currprefs.gfx_api < 2) {
                        float vblank = vblank_hz;
                        if (WIN32GFX_IsPicassoScreen(mon)) {
@@ -1481,6 +1492,7 @@ void show_screen(int monid, int mode)
                                timeSetEvent(waitms, 0, blackinsertion_cb, NULL, TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
                        }
                }
+#endif
                D3D_showframe(monid);
                if (monid == 0)
                        strobo_active2 = true;