From: kub Date: Sat, 12 Dec 2020 13:51:44 +0000 (+0100) Subject: libretro, improve ps2 support, switchable renderers, 32X support w/ DRC X-Git-Tag: v2.00~644 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e5b769d8f5b50f570a0e51a1d049250741660d0;p=picodrive.git libretro, improve ps2 support, switchable renderers, 32X support w/ DRC --- diff --git a/Makefile.libretro b/Makefile.libretro index eb9c20ca..67775769 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -203,6 +203,7 @@ else ifeq ($(platform), ps2) STATIC_LINKING = 1 NO_MMAP = 1 + ARCH = mipsel asm_render = 1 OBJS += platform/ps2/asm.o diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index ba6e8713..4ab42047 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -380,7 +380,7 @@ static struct block_list *inactive_blocks[TCACHE_BUFFERS]; // each array has len: sizeof(mem) / INVAL_PAGE_SIZE static struct block_list **inval_lookup[TCACHE_BUFFERS]; -#define HASH_TABLE_SIZE(tcid) ((tcid) ? 512 : 64*512) +#define HASH_TABLE_SIZE(tcid) ((tcid) ? 512 : 32*512) static struct block_entry **hash_tables[TCACHE_BUFFERS]; #define HASH_FUNC(hash_tab, addr, mask) \ diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index e39f5023..6de10340 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -3,6 +3,7 @@ * (C) notaz, 2013 * (C) aliaspider, 2016 * (C) Daniel De Matteis, 2013 + * (C) kub, 2020 * * This work is licensed under the terms of MAME license. * See COPYING file in the top-level directory. @@ -80,12 +81,8 @@ static retro_input_state_t input_state_cb; static retro_environment_t environ_cb; static retro_audio_sample_batch_t audio_batch_cb; -#if defined(RENDER_GSKIT_PS2) -#define VOUT_MAX_WIDTH 328 -#else #define VOUT_MAX_WIDTH 320 #define VOUT_32COL_WIDTH 256 -#endif #define VOUT_MAX_HEIGHT 240 #define INITIAL_SND_RATE 44100 @@ -109,6 +106,8 @@ static int vout_width, vout_height, vout_offset; static float user_vout_width = 0.0; #if defined(RENDER_GSKIT_PS2) +#define VOUT_8BIT_WIDTH 328 +#define VOUT_8BIT_HEIGHT 256 RETRO_HW_RENDER_INTEFACE_GSKIT_PS2 *ps2 = NULL; static void *retro_palette; static struct retro_hw_ps2_insets padding; @@ -213,6 +212,28 @@ void cache_flush_d_inval_i(void *start, void *end) #endif } +#ifdef RENDER_GSKIT_PS2 +/* ee-gcc is version 3.2, where these aren't yet defined */ +void __builtin___clear_cache(void *b, void *e) +{ +#if 0 /* which of these is overall faster for lots of small cache updates? */ + SyncDCache(b, e); +#else + FlushCache(0); /* WRITEBACK_DCACHE */ +#endif + FlushCache(2); /* INVALIDATE_ICACHE */ +} + +int __builtin_parity(unsigned v) +{ + /* credits to bit twiddling hacks, https://graphics.stanford.edu/~seander/bithacks.html */ + v ^= v >> 16; + v ^= v >> 8; + v ^= v >> 4; + return (0x6996 >> (v&0xf)) & 1; +} +#endif + #ifdef __MACH__ /* calls to this may be generated by the compiler, but it's missing in libc? */ void __clear_cache(void *start, void *end) @@ -604,17 +625,29 @@ void emu_video_mode_change(int start_line, int line_count, int is_32cols) vout_16bit = vout_format == PDF_RGB555 || (PicoIn.AHW & PAHW_32X); #if defined(RENDER_GSKIT_PS2) + // calculate the borders of the real image inside the picodrive image + vout_width = (vout_16bit ? VOUT_MAX_WIDTH : VOUT_8BIT_WIDTH); + vout_height = (vout_16bit ? VOUT_MAX_HEIGHT : VOUT_8BIT_HEIGHT); + vout_offset = (vout_16bit ? 0 : 8); // 8bit has 8 px overlap area on the left if (is_32cols) { - padding = (struct retro_hw_ps2_insets){start_line, 16.0f, VOUT_MAX_HEIGHT - line_count - start_line, 64.0f}; + // 256x240, with or w/o overlap on the left and 64 px on the right + padding = (struct retro_hw_ps2_insets){start_line, vout_offset, vout_height - line_count - start_line, vout_width - 256.0f - vout_offset}; } else { - padding = (struct retro_hw_ps2_insets){start_line, 16.0f, VOUT_MAX_HEIGHT - line_count - start_line, 0.0f}; + // 320x240, with or w/o overlap on the left and none on the right + padding = (struct retro_hw_ps2_insets){start_line, vout_offset, vout_height - line_count - start_line, vout_width - 320.0f - vout_offset}; } - vout_width = VOUT_MAX_WIDTH; - vout_height = VOUT_MAX_HEIGHT; - memset(vout_buf, 0, vout_width * VOUT_MAX_HEIGHT); + int pxsz = (vout_16bit ? 2 : 1); // pixel size: RGB = 16 bits, CLUT = 8 bits + memset(vout_buf, 0, pxsz * vout_width * vout_height); memset(retro_palette, 0, gsKit_texture_size_ee(16, 16, GS_PSM_CT16)); - PicoDrawSetOutBuf(vout_buf, vout_width); + PicoDrawSetOutBuf(vout_buf, pxsz * vout_width); + if (ps2) { + // prepare image as texture for rendering + ps2->coreTexture->Width = vout_width; + ps2->coreTexture->Height = vout_height; + ps2->coreTexture->PSM = (vout_16bit ? GS_PSM_CT16 : GS_PSM_T8); + ps2->padding = padding; + } #else vout_width = is_32cols ? VOUT_32COL_WIDTH : VOUT_MAX_WIDTH; memset(vout_buf, 0, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2); @@ -1653,10 +1686,11 @@ void retro_run(void) buff = (uint32_t *)RETRO_HW_FRAME_BUFFER_VALID; if (!ps2) { + // get access to the graphics hardware if (!environ_cb(RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE, (void **)&ps2) || !ps2) { printf("Failed to get HW rendering interface!\n"); return; - } + } if (ps2->interface_version != RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION) { printf("HW render interface mismatch, expected %u, got %u!\n", @@ -1664,72 +1698,32 @@ void retro_run(void) return; } - ps2->coreTexture->Width = vout_width; - ps2->coreTexture->Height = vout_height; - ps2->coreTexture->PSM = GS_PSM_T8; ps2->coreTexture->ClutPSM = GS_PSM_CT16; ps2->coreTexture->Filter = GS_FILTER_LINEAR; ps2->coreTexture->Clut = retro_palette; - } - if (Pico.m.dirtyPal) { - int i; - unsigned short int *pal=(void *)ps2->coreTexture->Clut; - - if (PicoIn.AHW & PAHW_SMS) { - // SMS - unsigned int *spal=(void *)PicoMem.cram; - unsigned int *dpal=(void *)pal; - unsigned int t; - - /* cram is always stored as shorts, even though real hardware probably uses bytes */ - for (i = 0x20/2; i > 0; i--, spal++, dpal++) { - t = *spal; - t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<6) | ((t & 0x00300030)<<9); - t |= t >> 2; - t |= (t >> 4) & 0x08610861; - *dpal = t; - } - pal[0xe0] = 0; - - - } else if (PicoIn.AHW & PAHW_32X) { - // MCD+32X - } else if (PicoIn.AHW & PAHW_MCD) { - // MCD - } else { - // MD - if(Pico.video.reg[0xC]&8){ - do_pal_convert_with_shadows(pal, PicoMem.cram); - } else { - do_pal_convert(pal, PicoMem.cram); - if (Pico.est.rendstatus & PDRAW_SONIC_MODE) { - memcpy(&pal[0x80], pal, 0x40*2); - } - } - } - - - //Rotate CLUT. - for (i = 0; i < 256; i++) { - if ((i&0x18) == 8) { - unsigned short int tmp = pal[i]; - pal[i] = pal[i+8]; - pal[i+8] = tmp; - } - } - - Pico.m.dirtyPal = 0; - } - - if (PicoIn.AHW & PAHW_SMS) { ps2->coreTexture->Mem = vout_buf; - } else { - ps2->coreTexture->Mem = Pico.est.Draw2FB; + ps2->coreTexture->Width = vout_width; + ps2->coreTexture->Height = vout_height; + ps2->coreTexture->PSM = (vout_16bit ? GS_PSM_CT16 : GS_PSM_T8); + ps2->padding = padding; } - ps2->padding = padding; - + // CLUT update needed? + if (!vout_16bit && Pico.m.dirtyPal) { + PicoDrawUpdateHighPal(); + + // Rotate CLUT. PS2 is special since entries in CLUT are not in sequence. + unsigned short int *pal=(void *)retro_palette; + for (i = 0; i < 256; i+=8) { + if ((i&0x18) == 0x08) + memcpy(pal+i,Pico.est.HighPal+i+8,16); + else if ((i&0x18) == 0x10) + memcpy(pal+i,Pico.est.HighPal+i-8,16); + else + memcpy(pal+i,Pico.est.HighPal+i,16); + } + } #else if (!vout_16bit) { /* The 8 bit renderers write a CLUT image in Pico.est.Draw2FB, while libretro wants RGB in vout_buf. @@ -1809,21 +1803,13 @@ void retro_init(void) #ifdef _3DS vout_buf = linearMemAlign(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2, 0x80); #elif defined(RENDER_GSKIT_PS2) - vout_buf = memalign(128, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT); + vout_buf = memalign(4096, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2); retro_palette = memalign(128, gsKit_texture_size_ee(16, 16, GS_PSM_CT16)); #else vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2); #endif PicoInit(); -#if defined(RENDER_GSKIT_PS2) - PicoDrawSetOutFormat(PDF_NONE, 0); - PicoDrawSetOutBuf(vout_buf, vout_width); - PicoDrawSetOutputMode4(PDF_8BIT); -#else - PicoDrawSetOutFormat(PDF_RGB555, 0); - PicoDrawSetOutBuf(vout_buf, vout_width * 2); -#endif //PicoIn.osdMessage = plat_status_msg_busy_next; PicoIn.mcdTrayOpen = disk_tray_open; diff --git a/platform/libretro/libretro_core_options.h b/platform/libretro/libretro_core_options.h index a28de567..23ca4163 100644 --- a/platform/libretro/libretro_core_options.h +++ b/platform/libretro/libretro_core_options.h @@ -237,7 +237,6 @@ struct retro_core_option_definition option_defs_us[] = { }, "33" }, -#if !defined(RENDER_GSKIT_PS2) { "picodrive_renderer", "Renderer", @@ -250,7 +249,6 @@ struct retro_core_option_definition option_defs_us[] = { }, "accurate" }, -#endif { "picodrive_sound_rate", "Sound quality",