]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
RTG color conversion/copy thread support.
authorToni Wilen <twilen@winuae.net>
Thu, 1 Feb 2018 16:42:46 +0000 (18:42 +0200)
committerToni Wilen <twilen@winuae.net>
Thu, 1 Feb 2018 16:42:46 +0000 (18:42 +0200)
cfgfile.cpp
include/options.h
od-win32/picasso96_win.cpp
od-win32/picasso96_win.h
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/win32gui.cpp

index ccbe0e11669f07c496c48cd8e23da2b25910ec6c..00dcef50d9a8c631997162773f63f17859046290 100644 (file)
@@ -2239,7 +2239,8 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite(f, _T("cpuboardmem1_size"), _T("%d"), p->cpuboardmem1_size / 0x100000);
        cfgfile_dwrite(f, _T("cpuboardmem2_size"), _T("%d"), p->cpuboardmem2_size / 0x100000);
        cfgfile_write_bool(f, _T("gfxcard_hardware_vblank"), p->rtg_hardwareinterrupt);
-       cfgfile_write_bool (f, _T("gfxcard_hardware_sprite"), p->rtg_hardwaresprite);
+       cfgfile_write_bool(f, _T("gfxcard_hardware_sprite"), p->rtg_hardwaresprite);
+       cfgfile_write_bool(f, _T("gfxcard_multithread"), p->rtg_multithread);
        for (int i = 0; i < MAX_RTG_BOARDS; i++) {
                TCHAR tmp2[100];
                struct rtgboardconfig *rbc = &p->rtgboards[i];
@@ -5052,6 +5053,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_yesno(option, value, _T("agnus_bltbusybug"), &p->cs_agnusbltbusybug)
                || cfgfile_yesno(option, value, _T("gfxcard_hardware_vblank"), &p->rtg_hardwareinterrupt)
                || cfgfile_yesno(option, value, _T("gfxcard_hardware_sprite"), &p->rtg_hardwaresprite)
+               || cfgfile_yesno(option, value, _T("gfxcard_multithread"), &p->rtg_multithread)
                || cfgfile_yesno(option, value, _T("synchronize_clock"), &p->tod_hack)
                || cfgfile_yesno(option, value, _T("keyboard_connected"), &p->keyboard_connected)
                || cfgfile_coords(option, value, _T("lightpen_offset"), &p->lightpen_offset[0], &p->lightpen_offset[1])
index d9fdad1fef7cb6689324acaeb12485df6cc9dc20..a194a0f2a43661bcc00081bd25261496cbdb70f6 100644 (file)
@@ -692,6 +692,7 @@ struct uae_prefs {
        bool rtg_hardwareinterrupt;
        bool rtg_hardwaresprite;
        bool rtg_more_compatible;
+       bool rtg_multithread;
        struct rtgboardconfig rtgboards[MAX_RTG_BOARDS];
        uae_u32 custom_memory_addrs[MAX_CUSTOM_MEMORY_ADDRS];
        uae_u32 custom_memory_sizes[MAX_CUSTOM_MEMORY_ADDRS];
index 509b9354e9a0dc3a95848faeb347314127837782..e73b59c9fee58c25a80add3a74f1fe68d922d088 100644 (file)
@@ -34,6 +34,8 @@
 #include "sysconfig.h"
 #include "sysdeps.h"
 
+#include <stdlib.h>
+
 #if defined(PICASSO96)
 
 #define MULTIDISPLAY 0
@@ -86,11 +88,15 @@ static int picasso96_PCT = PCT_Unknown;
 int mman_GetWriteWatch (PVOID lpBaseAddress, SIZE_T dwRegionSize, PVOID *lpAddresses, PULONG_PTR lpdwCount, PULONG lpdwGranularity);
 void mman_ResetWatch (PVOID lpBaseAddress, SIZE_T dwRegionSize);
 
+bool picasso_flushpixels(int index, uae_u8 *src, int offset);
+
 int p96refresh_active;
 bool have_done_picasso = 1; /* For the JIT compiler */
 static int p96syncrate;
 static int p96hsync_counter, full_refresh;
 
+static smp_comm_pipe *render_pipe;
+static CRITICAL_SECTION render_cs;
 
 #define PICASSO_STATE_SETDISPLAY 1
 #define PICASSO_STATE_SETPANNING 2
@@ -200,16 +206,27 @@ extern addrbank gfxmem_bank;
 extern addrbank *gfxmem_banks[MAX_RTG_BOARDS];
 extern int rtg_index;
 
+static void lockrtg(void)
+{
+       if (currprefs.rtg_multithread)
+               EnterCriticalSection(&render_cs);
+}
+
+static void unlockrtg(void)
+{
+       if (currprefs.rtg_multithread)
+               LeaveCriticalSection(&render_cs);
+}
+
 STATIC_INLINE void endianswap (uae_u32 *vp, int bpp)
 {
-       uae_u32 v = *vp;
        switch (bpp)
        {
        case 2:
-               *vp = (((v >> 8) & 0x00ff) | (v << 8)) & 0xffff;
+               *vp = _byteswap_ushort(*vp);
                break;
        case 4:
-               *vp = ((v >> 24) & 0x000000ff) | ((v >> 8) & 0x0000ff00) | ((v << 8) & 0x00ff0000) | ((v << 24) & 0xff000000);
+               *vp = _byteswap_ulong(*vp);
                break;
        }
 }
@@ -612,34 +629,90 @@ static void do_fillrect_frame_buffer(struct RenderInfo *ri, int X, int Y, int Wi
                for (lines = 0; lines < Height; lines++, dst += bpr) {
                        memset (dst, Pen, Width);
                }
-               break;
+       break;
        case 2:
+       {
+               uae_u32 * p;
                Pen |= Pen << 16;
                for (lines = 0; lines < Height; lines++, dst += bpr) {
                        uae_u32 *p = (uae_u32*)dst;
-                       for (cols = 0; cols < Width / 2; cols++)
+                       for (cols = 0; cols < Width & ~15; cols += 16) {
+                               *p++ = Pen;
+                               *p++ = Pen;
+                               *p++ = Pen;
+                               *p++ = Pen;
                                *p++ = Pen;
-                       if (Width & 1)
+                               *p++ = Pen;
+                               *p++ = Pen;
+                               *p++ = Pen;
+                       }
+                       while (cols < Width / 2) {
+                               *p++ = Pen;
+                               cols++;
+                       }
+                       if (Width & 1) {
                                ((uae_u16*)p)[0] = Pen;
+                       }
                }
-               break;
+       }
+       break;
        case 3:
+       {
+               uae_u16 Pen1 = Pen >> 8; // RG
+               uae_u16 Pen2 = (Pen << 8) | (Pen >> 16); // BR
+               uae_u16 Pen3 = Pen & 0xffff; // GB
+               bool same = (Pen & 0xff) == ((Pen >> 8) & 0xff) && (Pen & 0xff) == ((Pen >> 16) & 0xff);
                for (lines = 0; lines < Height; lines++, dst += bpr) {
-                       uae_u8 *p = (uae_u8*)dst;
-                       for (cols = 0; cols < Width; cols++) {
-                               *p++ = Pen >> 0;
-                               *p++ = Pen >> 8;
-                               *p++ = Pen >> 16;
+                       uae_u16 *p = (uae_u16*)dst;
+                       if (same) {
+                               memset(p, Pen & 0xff, Width * 3);
+                       } else {
+                               for (cols = 0; cols < Width & ~7; cols += 8) {
+                                       *p++ = Pen1;
+                                       *p++ = Pen2;
+                                       *p++ = Pen3;
+                                       *p++ = Pen1;
+                                       *p++ = Pen2;
+                                       *p++ = Pen3;
+                                       *p++ = Pen1;
+                                       *p++ = Pen2;
+                                       *p++ = Pen3;
+                                       *p++ = Pen1;
+                                       *p++ = Pen2;
+                                       *p++ = Pen3;
+                               }
+                               uae_u8 *p8 = (uae_u8*)p;
+                               while (cols < Width) {
+                                       *p8++ = Pen >> 0;
+                                       *p8++ = Pen >> 8;
+                                       *p8++ = Pen >> 16;
+                                       cols++;
+                               }
                        }
                }
-               break;
+       }
+       break;
        case 4:
+       {
                for (lines = 0; lines < Height; lines++, dst += bpr) {
                        uae_u32 *p = (uae_u32*)dst;
-                       for (cols = 0; cols < Width; cols++)
+                       for (cols = 0; cols < Width & ~7; cols += 8) {
+                               *p++ = Pen;
+                               *p++ = Pen;
+                               *p++ = Pen;
+                               *p++ = Pen;
+                               *p++ = Pen;
                                *p++ = Pen;
+                               *p++ = Pen;
+                               *p++ = Pen;
+                       }
+                       while (cols < Width) {
+                               *p++ = Pen;
+                               cols++;
+                       }
                }
-               break;
+       }
+       break;
        }
 }
 
@@ -743,7 +816,12 @@ static bool rtg_render (void)
        } else {
                bool full = full_refresh > 0;
                if (uaegfx_active) {
-                       flushed = picasso_flushpixels (rtg_index, gfxmem_banks[rtg_index]->start + natmem_offset, picasso96_state.XYOffset - gfxmem_banks[rtg_index]->start);
+                       if (currprefs.rtg_multithread) {
+                               write_comm_pipe_int(render_pipe, rtg_index, 0);
+                               flushed = true;
+                       } else {
+                               flushed = picasso_flushpixels(rtg_index, gfxmem_banks[rtg_index]->start + natmem_offset, picasso96_state.XYOffset - gfxmem_banks[rtg_index]->start);
+                       }
                } else {
                        if (full_refresh < 0)
                                full_refresh = 0;
@@ -900,6 +978,7 @@ static void setconvert(void)
 {
        static int ohost_mode, orgbformat;
 
+       lockrtg();
        picasso_convert = getconvert(picasso96_state.RGBFormat, picasso_vidinfo.pixbytes);
        if (currprefs.gfx_api) {
                host_mode = picasso_vidinfo.pixbytes == 4 ? RGBFB_B8G8R8A8 : RGBFB_B5G6R5PC;
@@ -919,6 +998,7 @@ static void setconvert(void)
                orgbformat = picasso96_state.RGBFormat;
        }
        full_refresh = 1;
+       unlockrtg();
 }
 
 bool picasso_is_active (void)
@@ -938,6 +1018,7 @@ void picasso_refresh (void)
 
        if (!picasso_on || rtg_index < 0)
                return;
+       lockrtg();
        full_refresh = 1;
        setconvert();
        setupcursor();
@@ -945,6 +1026,7 @@ void picasso_refresh (void)
 
        if (currprefs.rtgboards[rtg_index].rtgmem_type >= GFXBOARD_HARDWARE) {
                gfxboard_refresh ();
+               unlockrtg();
                return;
        }
 
@@ -976,6 +1058,7 @@ void picasso_refresh (void)
        } else {
                write_log (_T("ERROR - picasso_refresh() can't refresh!\n"));
        }
+       unlockrtg();
 }
 
 static void selectuaegfx(void)
@@ -993,6 +1076,8 @@ static void picasso_handle_vsync2(void)
        bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
 
        int state = picasso_state_change;
+       if (state)
+               lockrtg();
        if (state & PICASSO_STATE_SETDAC) {
                atomic_and(&picasso_state_change, ~PICASSO_STATE_SETDAC);
                rtg_clear();
@@ -1025,6 +1110,8 @@ static void picasso_handle_vsync2(void)
                init_picasso_screen();
                set_panning_called = 0;
        }
+       if (state)
+               unlockrtg();
 
        if (picasso_on) {
                if (vsync < 0) {
@@ -1146,7 +1233,7 @@ void picasso_handle_hsync(void)
 #define BLT_FUNC(s,d) *d = 0
 #include "../p96_blit.cpp"
 #define BLT_NAME BLIT_NOR_32
-#define BLT_FUNC(s,d) *d = ~(*s | * d)
+#define BLT_FUNC(s,d) *d = ~((*s) | (*d))
 #include "../p96_blit.cpp"
 #define BLT_NAME BLIT_ONLYDST_32
 #define BLT_FUNC(s,d) *d = (*d) & ~(*s)
@@ -1197,7 +1284,7 @@ void picasso_handle_hsync(void)
 #define BLT_FUNC(s,d) *d = 0
 #include "../p96_blit.cpp"
 #define BLT_NAME BLIT_NOR_24
-#define BLT_FUNC(s,d) *d = ~(*s | * d)
+#define BLT_FUNC(s,d) *d = ~((*s) | (*d))
 #include "../p96_blit.cpp"
 #define BLT_NAME BLIT_ONLYDST_24
 #define BLT_FUNC(s,d) *d = (*d) & ~(*s)
@@ -1248,7 +1335,7 @@ void picasso_handle_hsync(void)
 #define BLT_FUNC(s,d) *d = 0
 #include "../p96_blit.cpp"
 #define BLT_NAME BLIT_NOR_16
-#define BLT_FUNC(s,d) *d = ~(*s | * d)
+#define BLT_FUNC(s,d) *d = ~((*s) | (*d))
 #include "../p96_blit.cpp"
 #define BLT_NAME BLIT_ONLYDST_16
 #define BLT_FUNC(s,d) *d = (*d) & ~(*s)
@@ -1299,7 +1386,7 @@ void picasso_handle_hsync(void)
 #define BLT_FUNC(s,d) *d = 0
 #include "../p96_blit.cpp"
 #define BLT_NAME BLIT_NOR_8
-#define BLT_FUNC(s,d) *d = ~(*s | * d)
+#define BLT_FUNC(s,d) *d = ~((*s) | (*d))
 #include "../p96_blit.cpp"
 #define BLT_NAME BLIT_ONLYDST_8
 #define BLT_FUNC(s,d) *d = (*d) & ~(*s)
@@ -1936,7 +2023,7 @@ static uae_u32 REGPARAM2 picasso_FindCard (TrapContext *ctx)
 {
        uaecptr AmigaBoardInfo = trap_get_areg(ctx, 0);
        /* NOTES: See BoardInfo struct definition in Picasso96 dev info */
-       if (!uaegfx_active || !gfxmem_bank.start)
+       if (!uaegfx_active || !(gfxmem_bank.flags & ABFLAG_MAPPED))
                return 0;
        if (uaegfx_base) {
                trap_put_long(ctx, uaegfx_base + CARD_BOARDINFO, AmigaBoardInfo);
@@ -2568,6 +2655,7 @@ static uae_u32 REGPARAM2 picasso_InitCard (TrapContext *ctx)
 */
 static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx)
 {
+       lockrtg();
        uae_u16 flag = trap_get_dreg(ctx, 0) & 0xFFFF;
 
        atomic_or(&picasso_state_change, PICASSO_STATE_SETSWITCH);
@@ -2582,6 +2670,7 @@ static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx)
        write_log(_T("SetSwitch() - %s\n"), flag ? p96text : _T("amiga"));
 
        /* Put old switch-state in D0 */
+       unlockrtg();
        return !flag;
 }
 
@@ -2715,6 +2804,7 @@ static void init_picasso_screen (void)
 */
 static uae_u32 REGPARAM2 picasso_SetGC (TrapContext *ctx)
 {
+       lockrtg();
        /* Fill in some static UAE related structure about this new ModeInfo setting */
        uaecptr AmigaBoardInfo = trap_get_areg(ctx, 0);
        uae_u32 border   = trap_get_dreg(ctx, 0);
@@ -2737,7 +2827,7 @@ static uae_u32 REGPARAM2 picasso_SetGC (TrapContext *ctx)
        picasso96_state_uaegfx.HostAddress = NULL;
 
        atomic_or(&picasso_state_change, PICASSO_STATE_SETGC);
-
+       unlockrtg();
        return 1;
 }
 
@@ -2776,6 +2866,7 @@ static void picasso_SetPanningInit (void)
 
 static uae_u32 REGPARAM2 picasso_SetPanning (TrapContext *ctx)
 {
+       lockrtg();
        uae_u16 Width = trap_get_dreg(ctx, 0);
        uaecptr start_of_screen = trap_get_areg(ctx, 1);
        uaecptr bi = trap_get_areg(ctx, 0);
@@ -2821,6 +2912,7 @@ static uae_u32 REGPARAM2 picasso_SetPanning (TrapContext *ctx)
 
        atomic_or(&picasso_state_change, PICASSO_STATE_SETPANNING);
 
+       unlockrtg();
        return 1;
 }
 
@@ -4352,7 +4444,7 @@ void picasso_invalidate (int x, int y, int w, int h)
        DX_Invalidate (x, y, w, h);
 }
 
-bool picasso_flushpixels (int index, uae_u8 *src, int off)
+static bool picasso_flushpixels (int index, uae_u8 *src, int off)
 {
        uae_u8 *src_start;
        uae_u8 *src_end;
@@ -4523,6 +4615,19 @@ bool picasso_flushpixels (int index, uae_u8 *src, int off)
        return lock != 0; 
 }
 
+static void *render_thread(void *v)
+{
+       for (;;) {
+               int idx = read_comm_pipe_int_blocking(render_pipe);
+               if (idx == -1)
+                       break;
+               lockrtg();
+               picasso_flushpixels(idx, gfxmem_banks[idx]->start + natmem_offset, picasso96_state.XYOffset - gfxmem_banks[idx]->start);
+               unlockrtg();
+       }
+       return 0;
+}
+
 extern addrbank gfxmem_bank;
 MEMORY_FUNCTIONS(gfxmem);
 addrbank gfxmem_bank = {
@@ -4904,6 +5009,13 @@ static void inituaegfxfuncs(TrapContext *ctx, uaecptr start, uaecptr ABI)
 
 void picasso_reset (void)
 {
+       if (!render_pipe && currprefs.rtg_multithread) {
+               InitializeCriticalSection(&render_cs);
+               render_pipe = xmalloc(smp_comm_pipe, 1);
+               init_comm_pipe(render_pipe, 10, 1);
+               uae_start_thread(_T("rtg"), render_thread, NULL, NULL);
+       }
+
        rtg_index = -1;
        if (savestate_state != STATE_RESTORE) {
                uaegfx_base = 0;
@@ -4948,7 +5060,7 @@ static uaecptr uaegfx_card_install (TrapContext *ctx, uae_u32 extrasize)
        uaecptr findcardfunc, initcardfunc;
        uaecptr exec = trap_get_long(ctx, 4);
 
-       if (uaegfx_old || !gfxmem_bank.start)
+       if (uaegfx_old || !(gfxmem_bank.flags & ABFLAG_MAPPED))
                return 0;
 
        uaegfx_resid = ds (_T("UAE Graphics Card 3.3"));
@@ -5038,6 +5150,7 @@ static uaecptr uaegfx_card_install (TrapContext *ctx, uae_u32 extrasize)
 
        write_log (_T("uaegfx.card %d.%d init @%08X\n"), UAEGFX_VERSION, UAEGFX_REVISION, uaegfx_base);
        uaegfx_active = 1;
+
        return uaegfx_base;
 }
 
index 17780a9e38b85ad26f5ce93bad70f44cb49f6c87..a6dca7ce4bdefec417f34b6ff799b250d250eff5 100644 (file)
@@ -558,7 +558,6 @@ extern void picasso_reset (void);
 extern bool picasso_is_active (void);
 extern int picasso_setwincursor (void);
 extern int picasso_palette (struct MyCLUTEntry *CLUT);
-extern bool picasso_flushpixels (int index, uae_u8 *src, int offset);
 extern void picasso_allocatewritewatch (int index, int gfxmemsize);
 extern void picasso_getwritewatch (int index, int offset);
 extern bool picasso_is_vram_dirty (int index, uaecptr addr, int size);
index 739be5074ba5d713fa4c30591b44147ab2af7d64..06d29ff40c5beece83b2189a0f4d54e30c42c391 100644 (file)
 #define IDC_RTG_Z2Z4                    1799
 #define IDC_RTG_NUM                     1799
 #define IDC_PORT2_REMAP                 1800
+#define IDC_RTG_THREAD                  1800
 #define IDC_PORT3_REMAP                 1801
 #define IDC_INPUTMAPOUT                 1801
 #define IDC_INFOBOX_TEXT2               1802
index a70ca1b00f715ada679ece0b9ee3409cf0c4c12b..1a573b40bdac88f38457f16279c049d1c52f1e39 100644 (file)
@@ -1219,6 +1219,7 @@ BEGIN
     COMBOBOX        IDC_RTG_BUFFERCNT,153,162,84,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
     CTEXT           "Aspect ratio:",IDC_STATIC,282,149,83,10,SS_CENTERIMAGE
     COMBOBOX        IDC_RTG_SCALE_ASPECTRATIO,282,162,84,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "Multithreaded",IDC_RTG_THREAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,207,93,83,10
 END
 
 IDD_INPUTMAP DIALOGEX 0, 0, 421, 341
index ce0d40a9525fe956c7870c2ebb688e1402494b19..458200d84eda7a7b4bcea6a12230a01ce111247a 100644 (file)
@@ -9947,6 +9947,7 @@ static void enable_for_expansiondlg(HWND hDlg)
        ew(hDlg, IDC_RTG_BUFFERCNT, rtg2);
        ew(hDlg, IDC_RTG_DISPLAYSELECT, rtg2);
        ew(hDlg, IDC_RTG_VBINTERRUPT, rtg3);
+       ew(hDlg, IDC_RTG_THREAD, rtg3 && en);
        if (!workprefs.gfx_api) {
                workprefs.rtg_hardwaresprite = false;
                CheckDlgButton(hDlg, IDC_RTG_HWSPRITE, FALSE);
@@ -10063,6 +10064,7 @@ static void values_to_expansiondlg(HWND hDlg)
        CheckDlgButton(hDlg, IDC_RTG_MATCH_DEPTH, workprefs.win32_rtgmatchdepth);
        CheckDlgButton(hDlg, IDC_RTG_VBINTERRUPT, workprefs.rtg_hardwareinterrupt);
        CheckDlgButton(hDlg, IDC_RTG_HWSPRITE, workprefs.rtg_hardwaresprite);
+       CheckDlgButton(hDlg, IDC_RTG_THREAD, workprefs.rtg_multithread);
 
        SendDlgItemMessage(hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_SETCURSEL,
                                           (workprefs.win32_rtgscaleaspectratio == 0) ? 0 :
@@ -10193,7 +10195,10 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                                workprefs.rtg_hardwareinterrupt = ischecked (hDlg, IDC_RTG_VBINTERRUPT);
                                break;
                        case IDC_RTG_HWSPRITE:
-                               workprefs.rtg_hardwaresprite = ischecked (hDlg, IDC_RTG_HWSPRITE);
+                               workprefs.rtg_hardwaresprite = ischecked(hDlg, IDC_RTG_HWSPRITE);
+                               break;
+                       case IDC_RTG_THREAD:
+                               workprefs.rtg_multithread = ischecked(hDlg, IDC_RTG_THREAD);
                                break;
                        }
                        if (HIWORD (wParam) == CBN_SELENDOK || HIWORD (wParam) == CBN_KILLFOCUS || HIWORD (wParam) == CBN_EDITCHANGE)  {