libretro, improve ps2 support, switchable renderers, 32X support w/ DRC

This commit is contained in:
kub 2020-12-12 14:51:44 +01:00
parent cd262e4cc7
commit 7e5b769d8f
4 changed files with 66 additions and 81 deletions

View file

@ -203,6 +203,7 @@ else ifeq ($(platform), ps2)
STATIC_LINKING = 1
NO_MMAP = 1
ARCH = mipsel
asm_render = 1
OBJS += platform/ps2/asm.o

View file

@ -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) \

View file

@ -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;

View file

@ -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",