From: Toni Wilen Date: Mon, 12 Dec 2011 19:10:43 +0000 (+0200) Subject: 2400b4 X-Git-Tag: 2400~24 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=d7d6204242dad28319aa7a5162484abba1c1d95b;p=francis%2Fwinuae.git 2400b4 --- diff --git a/audio.cpp b/audio.cpp index 6d573dc5..a9d61cf7 100644 --- a/audio.cpp +++ b/audio.cpp @@ -117,6 +117,7 @@ struct audio_channel_data { /* too fast cpu fixes */ uaecptr ptx; bool ptx_written; + bool ptx_tofetch; }; static int samplecnt; @@ -1052,7 +1053,8 @@ static void zerostate (int nr) { struct audio_channel_data *cdp = audio_channel + nr; #if DEBUG_AUDIO > 0 - write_log (L"%d: ZEROSTATE\n", nr); + if (debugchannel (nr)) + write_log (L"%d: ZEROSTATE\n", nr); #endif cdp->state = 0; cdp->evtime = MAX_EV; @@ -1166,7 +1168,7 @@ static void newsample (int nr, sample8_t sample) if (!debugchannel (nr)) sample = 0; #endif -#if DEBUG_AUDIO > 1 +#if DEBUG_AUDIO > 2 if (debugchannel (nr)) write_log (L"SAMPLE%d: %02x\n", nr, sample & 0xff); #endif @@ -1223,7 +1225,7 @@ static void loaddat (int nr, bool modper) cdp->hisample = cdp->losample = true; cdp->have_dat = false; #endif -#if DEBUG_AUDIO > 1 +#if DEBUG_AUDIO > 2 if (debugchannel (nr)) write_log (L"LOAD%dDAT: New:%04x, Old:%04x\n", nr, cdp->dat, cdp->dat2); #endif @@ -1267,7 +1269,8 @@ static void audio_state_channel2 (int nr, bool perfin) // DMA switched off, state=2/3 and "too fast CPU": kill DMA instantly // or CPU timed DMA wait routines in common tracker players will lose notes #if DEBUG_AUDIO > 0 - write_log (L"%d: INSTADMAOFF\n", nr, M68K_GETPC); + if (debugchannel (nr)) + write_log (L"%d: INSTADMAOFF\n", nr, M68K_GETPC); #endif newsample (nr, (cdp->dat2 >> 0) & 0xff); if (napnav) @@ -1291,6 +1294,7 @@ static void audio_state_channel2 (int nr, bool perfin) cdp->drhpos = hpos; cdp->wlen = cdp->len; cdp->ptx_written = false; + cdp->ptx_tofetch = true; cdp->dsr = true; #if TEST_AUDIO > 0 cdp->have_dat = false; @@ -1844,6 +1848,7 @@ uaecptr audio_getpt (int nr, bool reset) cdp->pt += 2; if (reset) cdp->pt = cdp->lc; + cdp->ptx_tofetch = false; return p; } @@ -1855,7 +1860,7 @@ void AUDxLCH (int nr, uae_u16 v) // someone wants to update PT but DSR has not yet been processed. // too fast CPU and some tracker players: enable DMA, CPU delay, update AUDxPT with loop position - if (usehacks1 () && ((cdp->dsr && cdp->state == 1) || cdp->ptx_written)) { + if (usehacks1 () && ((cdp->ptx_tofetch && cdp->state == 1) || cdp->ptx_written)) { cdp->ptx = cdp->lc; cdp->ptx_written = true; } else { @@ -1863,7 +1868,7 @@ void AUDxLCH (int nr, uae_u16 v) } #if DEBUG_AUDIO > 0 if (debugchannel (nr)) - write_log (L"AUD%dLCH: %04X %08X\n", nr, v, M68K_GETPC); + write_log (L"AUD%dLCH: %04X %08X (%d) (%d %d %08x)\n", nr, v, M68K_GETPC, cdp->state, cdp->dsr, cdp->ptx_written, cdp->ptx); #endif } @@ -1872,7 +1877,7 @@ void AUDxLCL (int nr, uae_u16 v) struct audio_channel_data *cdp = audio_channel + nr; audio_activate (); update_audio (); - if (usehacks1 () && ((cdp->dsr && cdp->state == 1) || cdp->ptx_written)) { + if (usehacks1 () && ((cdp->ptx_tofetch && cdp->state == 1) || cdp->ptx_written)) { cdp->ptx = cdp->lc; cdp->ptx_written = true; } else { @@ -1880,7 +1885,7 @@ void AUDxLCL (int nr, uae_u16 v) } #if DEBUG_AUDIO > 0 if (debugchannel (nr)) - write_log (L"AUD%dLCL: %04X %08X\n", nr, v, M68K_GETPC); + write_log (L"AUD%dLCL: %04X %08X (%d) (%d %d %08x)\n", nr, v, M68K_GETPC, cdp->state, cdp->dsr, cdp->ptx_written, cdp->ptx); #endif } diff --git a/blitter.cpp b/blitter.cpp index 2f71d868..30f34b0e 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -1480,6 +1480,10 @@ int blitnasty (void) return 0; if (!dmaen (DMA_BLITTER)) return 0; + if (blitter_cycle_exact) { + blitter_force_finish (); + return -1; + } if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0]) return 0; cycles = (get_cycles () - blit_first_cycle) / CYCLE_UNIT; diff --git a/custom.cpp b/custom.cpp index d2f91741..9840e7ac 100644 --- a/custom.cpp +++ b/custom.cpp @@ -142,6 +142,7 @@ static int next_lineno, prev_lineno; static enum nln_how nextline_how; static int lof_changed = 0; static int scandoubled_line; +static bool vsync_rendered; /* Stupid genlock-detection prevention hack. * We should stop calling vsync_handler() and @@ -5115,12 +5116,10 @@ static void framewait (void) if (vs == -2) { - show_screen (); vsync_busywait_end (); vsync_busywait_do (&freetime); curr_time = read_processor_time (); vsyncmintime = curr_time + vsynctime; - render_screen (); vsync_busywait_start (); } else { @@ -5204,6 +5203,8 @@ static void fpscounter (void) // vsync functions that are not hardware timing related static void vsync_handler_pre (void) { + vsync_rendered = false; + if (bogusframe > 0) bogusframe--; @@ -5756,6 +5757,10 @@ static void hsync_handler_post (bool onvsync) #ifdef JIT } #endif + if (is_lastline && isvsync () == -2 && !vsync_rendered) { + vsync_rendered = true; + render_screen (); + } if (!nocustom ()) { int lineno = vpos; diff --git a/newcpu.cpp b/newcpu.cpp index d7bdd2d2..64c5374e 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -3299,12 +3299,15 @@ STATIC_INLINE int do_specialties (int cycles) while ((regs.spcflags & SPCFLAG_BLTNASTY) && dmaen (DMA_BLITTER) && cycles > 0 && !currprefs.blitter_cycle_exact) { int c = blitnasty (); - if (c > 0) { + if (c < 0) { + break; + } else if (c > 0) { cycles -= c * CYCLE_UNIT * 2; if (cycles < CYCLE_UNIT) cycles = 0; - } else + } else { c = 4; + } x_do_cycles (c * CYCLE_UNIT); if (regs.spcflags & SPCFLAG_COPPER) do_copper (); diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 9ba0fcff..7012c8d3 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -1989,12 +1989,12 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth memset (&dpp, 0, sizeof (dpp)); dpp.Windowed = isfullscreen () <= 0; dpp.BackBufferFormat = mode.Format; - dpp.BackBufferCount = vsync == -1 ? 0 : (vsync == -2 ? 2 : currprefs.gfx_backbuffers); + dpp.BackBufferCount = currprefs.gfx_backbuffers; dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; dpp.BackBufferWidth = w_w; dpp.BackBufferHeight = w_h; - dpp.PresentationInterval = (dpp.Windowed || dpp.BackBufferCount == 0 || vsync == -1) ? D3DPRESENT_INTERVAL_IMMEDIATE : D3DPRESENT_INTERVAL_ONE; + dpp.PresentationInterval = dpp.BackBufferCount <= 1 || dpp.Windowed ? D3DPRESENT_INTERVAL_IMMEDIATE : D3DPRESENT_INTERVAL_ONE; modeex.Width = w_w; modeex.Height = w_h; @@ -2006,7 +2006,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth if (isfullscreen () > 0) { dpp.FullScreen_RefreshRateInHz = currprefs.gfx_refreshrate > 0 ? currprefs.gfx_refreshrate : 0; modeex.RefreshRate = dpp.FullScreen_RefreshRateInHz; - if (currprefs.gfx_avsync && currprefs.gfx_avsyncmode == 0) { + if (vsync > 0) { dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; if (getvsyncrate (dpp.FullScreen_RefreshRateInHz) != dpp.FullScreen_RefreshRateInHz) { if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) @@ -2095,14 +2095,16 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth write_log (L"DYNAMIC "); write_log (L"\n"); - write_log (L"%s: PS=%d.%d VS=%d.%d %d*%d*%d%s%s %d-bit %d\n", + write_log (L"%s: PS=%d.%d VS=%d.%d %d*%d*%d%s VS=%d B=%d%s%s %d-bit %d\n", D3DHEAD, (d3dCaps.PixelShaderVersion >> 8) & 0xff, d3dCaps.PixelShaderVersion & 0xff, (d3dCaps.VertexShaderVersion >> 8) & 0xff, d3dCaps.VertexShaderVersion & 0xff, max_texture_w, max_texture_h, dpp.Windowed ? 0 : dpp.FullScreen_RefreshRateInHz, dpp.Windowed ? L"" : L" FS", - currprefs.gfx_avsync ? L" VSYNC" : L"", + vsync, dpp.BackBufferCount, + dpp.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE ? L"I" : L"F", + currprefs.gfx_backbuffers == 0 ? L"E" : L"", t_depth, adapter ); @@ -2164,13 +2166,15 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth maxscanline = 0; d3d_enabled = 1; - if (vsync == -1) { - hr = d3ddev->CreateQuery(D3DQUERYTYPE_EVENT, &query); - if (FAILED (hr)) - write_log (L"%s: CreateQuery(D3DQUERYTYPE_EVENT) failed: %s\n", D3DHEAD, D3D_ErrorString (hr)); + if (vsync < 0) { + if (currprefs.gfx_backbuffers == 0) { + hr = d3ddev->CreateQuery(D3DQUERYTYPE_EVENT, &query); + if (FAILED (hr)) + write_log (L"%s: CreateQuery(D3DQUERYTYPE_EVENT) failed: %s\n", D3DHEAD, D3D_ErrorString (hr)); + } } if (d3ddevex) { - hr = d3ddevex->SetMaximumFrameLatency (1); + hr = d3ddevex->SetMaximumFrameLatency (vsync < 0 ? 1 : 0); if (FAILED (hr)) write_log (L"%s: SetMaximumFrameLatency() failed: %s\n", D3DHEAD, D3D_ErrorString (hr)); } diff --git a/od-win32/dxwrap.cpp b/od-win32/dxwrap.cpp index ac55064d..0d4a1556 100644 --- a/od-win32/dxwrap.cpp +++ b/od-win32/dxwrap.cpp @@ -6,6 +6,7 @@ #include "dxwrap.h" #include "win32gfx.h" #include "statusline.h" +#include "xwin.h" #include #include @@ -344,7 +345,7 @@ HRESULT DirectDraw_CreateMainSurface (int width, int height) DWORD oldflags = desc.dwFlags; desc.dwFlags |= DDSD_BACKBUFFERCOUNT; desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP; - desc.dwBackBufferCount = currprefs.gfx_backbuffers; + desc.dwBackBufferCount = currprefs.gfx_backbuffers == 0 ? 1 : currprefs.gfx_backbuffers; if (desc.dwBackBufferCount > 0) { ddrval = IDirectDraw7_CreateSurface (dxdata.maindd, &desc, &dxdata.primary, NULL); if (SUCCEEDED (ddrval)) { @@ -904,12 +905,13 @@ static void flip (void) int result = 0; HRESULT ddrval = DD_OK; DWORD flags = DDFLIP_WAIT; + int vsync = isvsync (); - if (currprefs.turbo_emulation) + if (currprefs.turbo_emulation || (vsync && currprefs.gfx_backbuffers <= 1)) flags |= DDFLIP_NOVSYNC; if (dxdata.backbuffers == 2) { DirectDraw_Blit (dxdata.flipping[1], dxdata.flipping[0]); - if (currprefs.gfx_avsync) { + if (vsync) { if (vblank_skip >= 0 || currprefs.turbo_emulation) { ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags); } else { @@ -925,11 +927,7 @@ static void flip (void) ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags| DDFLIP_NOVSYNC); } } else if(dxdata.backbuffers == 1) { - if (currprefs.gfx_avsync) { - ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags); - } else { - ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags | DDFLIP_NOVSYNC); - } + ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags | DDFLIP_NOVSYNC); DirectDraw_Blit (dxdata.flipping[0], dxdata.primary); } if (ddrval == DDERR_SURFACELOST) { diff --git a/od-win32/win32.h b/od-win32/win32.h index efb1c497..66e3bf84 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,8 +19,8 @@ #define LANG_DLL 1 //#define WINUAEBETA L"" -#define WINUAEBETA L"Beta 2" -#define WINUAEDATE MAKEBD(2011, 12, 11) +#define WINUAEBETA L"Beta 4" +#define WINUAEDATE MAKEBD(2011, 12, 12) #define WINUAEEXTRA L"" #define WINUAEREV L"" diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 70178ab8..28bf738e 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -78,6 +78,7 @@ struct uae_filter *usedfilter; static int scalepicasso; static double remembered_vblank; static volatile int vblankthread_mode, vblankthread_counter; +static CRITICAL_SECTION cs_render; struct winuae_currentmode { unsigned int flags; @@ -859,6 +860,7 @@ bool render_screen (void) return render_ok; flushymin = 0; flushymax = currentmode->amiga_height; + EnterCriticalSection (&cs_render); if (currentmode->flags & DM_D3D) { v = D3D_renderframe (); #ifdef GFXFILTER @@ -869,6 +871,7 @@ bool render_screen (void) } else if (currentmode->flags & DM_DDRAW) { v = true; } + LeaveCriticalSection (&cs_render); render_ok = v; return render_ok; } @@ -879,6 +882,7 @@ void show_screen (void) return; if (!render_ok) return; + EnterCriticalSection (&cs_render); if (currentmode->flags & DM_D3D) { D3D_showframe (); #ifdef GFXFILTER @@ -888,6 +892,7 @@ void show_screen (void) } else if (currentmode->flags & DM_DDRAW) { DirectDraw_Flip (1); } + LeaveCriticalSection (&cs_render); } static uae_u8 *ddraw_dolock (void) @@ -1985,6 +1990,7 @@ void machdep_free (void) int graphics_init (void) { + InitializeCriticalSection (&cs_render); gfxmode_reset (); return open_windows (1); } @@ -2283,6 +2289,7 @@ static void _cdecl vblankthread (void *dummy) bool ok = getvblankstate (&vb); if (!ok || vb) { thread_vblank_found = true; + show_screen (); //write_log (L"%d\n", t - thread_vblank_time); thread_vblank_time = t; } @@ -2315,7 +2322,7 @@ double vblank_calibrate (double approx_vblank, bool waitonly) if (waitonly) { vblankbasefull = syncbase / approx_vblank; vblankbasewait = (syncbase / approx_vblank) * 3 / 4; - vblankbasewait2 = (syncbase / approx_vblank) * 5 / 10; + vblankbasewait2 = (syncbase / approx_vblank) * 7 / 10; remembered_vblank = -1; return -1; } @@ -2369,7 +2376,7 @@ double vblank_calibrate (double approx_vblank, bool waitonly) if (cnt >= total) break; } - changevblankthreadmode (VBLANKTH_IDLE); + changevblankthreadmode (threaded_vsync ? VBLANKTH_IDLE : VBLANKTH_KILL); SetThreadPriority (th, oldpri); if (maxcnt >= maxtotal) { tsum = tsum2 / tcnt2; diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 20b1ae93..a8dacad2 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -5814,10 +5814,6 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l i--; workprefs.gfx_avsync = (i & 1) + 1; workprefs.gfx_avsyncmode = i >= 2 ? 1 : 0; - if (workprefs.gfx_avsyncmode != oldmode && workprefs.gfx_avsyncmode) { - workprefs.gfx_backbuffers = 0; - SendDlgItemMessage (hDlg, IDC_DISPLAY_BUFFERCNT, CB_SETCURSEL, workprefs.gfx_backbuffers, 0); - } } workprefs.gfx_pfullscreen = SendDlgItemMessage (hDlg, IDC_SCREENMODE_RTG, CB_GETCURSEL, 0, 0); diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 671df7c3..e3a85ef2 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,17 @@ +Beta 4: + +- Another switching from CE mode to non-CE hang fix. (Blitter nasty related) +- Another too fast CPU audio hack update, fixes random glitches (Uridium II, Moonstone, probably many others) +- Low latency vsync buffering change, selected buffering mode can be modified now. + - No buffering is same as previously + - Double and triple buffering can be enabled, increases latency but can reduce random jumps. +- Fastest possible CPU low latency vsync update: + - Works now without buffering + - Flips buffers in vblank thread (Flipping timing is correct now, tearing gone) + +Normal vsync may still be broken. + Beta 3: - Fixed DirectDraw mode crash (b1)