From 0b02eb7712f1272fa7f38b0af41968b53af3b5a8 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 13 Aug 2012 00:02:23 +0300 Subject: [PATCH] add support for software-enhanced rendering --- frontend/main.c | 2 ++ frontend/menu.c | 8 +++++++- frontend/plugin_lib.h | 2 ++ plugins/gpulib/gpu.c | 15 ++++++++++++++ plugins/gpulib/gpu.h | 4 ++++ plugins/gpulib/vout_pl.c | 43 ++++++++++++++++++++++++++++++---------- 6 files changed, 63 insertions(+), 11 deletions(-) diff --git a/frontend/main.c b/frontend/main.c index 19e8319b..c98e9e0c 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -143,6 +143,8 @@ void emu_set_default_config(void) Config.PsxAuto = 1; pl_rearmed_cbs.gpu_neon.allow_interlace = 2; // auto + pl_rearmed_cbs.gpu_neon.enhancement_enable = + pl_rearmed_cbs.gpu_neon.enhancement_no_main = 0; pl_rearmed_cbs.gpu_peops.iUseDither = 0; pl_rearmed_cbs.gpu_peops.dwActFixes = 1<<7; pl_rearmed_cbs.gpu_unai.abe_hack = diff --git a/frontend/menu.c b/frontend/menu.c index 42a53e1d..2fc56ba6 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -288,6 +288,8 @@ static const struct { CE_INTVAL_P(gpu_unai.no_light), CE_INTVAL_P(gpu_unai.no_blend), CE_INTVAL_P(gpu_neon.allow_interlace), + CE_INTVAL_P(gpu_neon.enhancement_enable), + CE_INTVAL_P(gpu_neon.enhancement_no_main), CE_INTVAL_P(gpu_peopsgl.bDrawDither), CE_INTVAL_P(gpu_peopsgl.iFilterType), CE_INTVAL_P(gpu_peopsgl.iFrameTexType), @@ -1119,17 +1121,21 @@ void menu_set_filter_list(void *filters) #ifdef __ARM_NEON__ static const char h_gpu_neon[] = "Configure built-in NEON GPU plugin"; +static const char h_gpu_neon_enhanced[] = "Renders in double resolution at the cost of lower performance"; +static const char h_gpu_neon_enhanced_hack[] = "Speed hack for above option (glitches some games)"; static const char *men_gpu_interlace[] = { "Off", "On", "Auto", NULL }; static menu_entry e_menu_plugin_gpu_neon[] = { mee_enum ("Enable interlace mode", 0, pl_rearmed_cbs.gpu_neon.allow_interlace, men_gpu_interlace), + mee_onoff_h ("Enhanced resolution (slow)", 0, pl_rearmed_cbs.gpu_neon.enhancement_enable, 1, h_gpu_neon_enhanced), + mee_onoff_h ("Enhanced res. speed hack", 0, pl_rearmed_cbs.gpu_neon.enhancement_no_main, 1, h_gpu_neon_enhanced_hack), mee_end, }; static int menu_loop_plugin_gpu_neon(int id, int keys) { - int sel = 0; + static int sel = 0; me_loop(e_menu_plugin_gpu_neon, &sel); return 0; } diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h index bcf74acc..7687bf84 100644 --- a/frontend/plugin_lib.h +++ b/frontend/plugin_lib.h @@ -60,6 +60,8 @@ struct rearmed_cbs { unsigned int only_16bpp; // platform is 16bpp-only struct { int allow_interlace; // 0 off, 1 on, 2 guess + int enhancement_enable; + int enhancement_no_main; } gpu_neon; struct { int iUseDither; diff --git a/plugins/gpulib/gpu.c b/plugins/gpulib/gpu.c index 46e92d1b..462e301a 100644 --- a/plugins/gpulib/gpu.c +++ b/plugins/gpulib/gpu.c @@ -9,6 +9,7 @@ */ #include +#include #include #include "gpu.h" @@ -137,8 +138,21 @@ long GPUinit(void) { int ret; ret = vout_init(); + + gpu.state.enhancement_available = 0; ret |= renderer_init(); + if (gpu.state.enhancement_available) { + if (gpu.enhancement_bufer == NULL) + gpu.enhancement_bufer = malloc(2048 * 1024 * 2 + 1024 * 512 * 2); + if (gpu.enhancement_bufer == NULL) + gpu_log("OOM for enhancement buffer\n"); + } + else if (gpu.enhancement_bufer != NULL) { + free(gpu.enhancement_bufer); + gpu.enhancement_bufer = NULL; + } + gpu.state.frame_count = &gpu.zero; gpu.state.hcnt = &gpu.zero; gpu.frameskip.active = 0; @@ -669,6 +683,7 @@ void GPUrearmedCallbacks(const struct rearmed_cbs *cbs) gpu.state.hcnt = cbs->gpu_hcnt; gpu.state.frame_count = cbs->gpu_frame_count; gpu.state.allow_interlace = cbs->gpu_neon.allow_interlace; + gpu.state.enhancement_enable = cbs->gpu_neon.enhancement_enable; if (cbs->pl_vout_set_raw_vram) cbs->pl_vout_set_raw_vram(gpu.vram); diff --git a/plugins/gpulib/gpu.h b/plugins/gpulib/gpu.h index 1cbe38cd..f5143957 100644 --- a/plugins/gpulib/gpu.h +++ b/plugins/gpulib/gpu.h @@ -67,6 +67,9 @@ struct psx_gpu { uint32_t old_interlace:1; uint32_t allow_interlace:2; uint32_t blanked:1; + uint32_t enhancement_available:1; + uint32_t enhancement_enable:1; + uint32_t enhancement_active:1; uint32_t *frame_count; uint32_t *hcnt; /* hsync count */ struct { @@ -87,6 +90,7 @@ struct psx_gpu { uint32_t last_flip_frame; uint32_t pending_fill[3]; } frameskip; + void *enhancement_bufer; }; extern struct psx_gpu gpu; diff --git a/plugins/gpulib/vout_pl.c b/plugins/gpulib/vout_pl.c index 0bd1ecf6..47c28f3e 100644 --- a/plugins/gpulib/vout_pl.c +++ b/plugins/gpulib/vout_pl.c @@ -31,13 +31,25 @@ static void check_mode_change(void) { static uint32_t old_status; static int old_h; + int w = gpu.screen.hres; + int h = gpu.screen.h; + + gpu.state.enhancement_active = + gpu.enhancement_bufer != NULL && gpu.state.enhancement_enable + && w <= 512 && h <= 256 && !gpu.status.rgb24; + + if (gpu.state.enhancement_active) { + w *= 2; + h *= 2; + } // width|rgb24 change? - if ((gpu.status.reg ^ old_status) & ((7<<16)|(1<<21)) || gpu.screen.h != old_h) + if ((gpu.status.reg ^ old_status) & ((7<<16)|(1<<21)) || h != old_h) { old_status = gpu.status.reg; - old_h = gpu.screen.h; - screen_buf = cbs->pl_vout_set_mode(gpu.screen.hres, gpu.screen.h, + old_h = h; + + screen_buf = cbs->pl_vout_set_mode(w, h, (gpu.status.rgb24 && !cbs->only_16bpp) ? 24 : 16); } } @@ -50,6 +62,8 @@ static void blit(void) int h = gpu.screen.h; uint16_t *vram = gpu.vram; int stride = gpu.screen.hres; + int vram_stride = 1024; + int vram_mask = 1024 * 512 - 1; int fb_offs, doffs; uint8_t *dest; @@ -57,7 +71,16 @@ static void blit(void) if (dest == NULL) return; - fb_offs = y * 1024 + x; + if (gpu.state.enhancement_active) { + vram = gpu.enhancement_bufer; + x *= 2; + y *= 2; + w *= 2; + h *= 2; + stride *= 2; + vram_mask = 1024 * 1024 - 1; + } + fb_offs = y * vram_stride + x; // only do centering, at least for now doffs = (stride - w) / 2 & ~1; @@ -66,17 +89,17 @@ static void blit(void) { if (cbs->only_16bpp) { dest += doffs * 2; - for (; h-- > 0; dest += stride * 2, fb_offs += 1024) + for (; h-- > 0; dest += stride * 2, fb_offs += vram_stride) { - fb_offs &= 1024*512-1; + fb_offs &= vram_mask; bgr888_to_rgb565(dest, vram + fb_offs, w * 3); } } else { dest += (doffs / 8) * 24; - for (; h-- > 0; dest += stride * 3, fb_offs += 1024) + for (; h-- > 0; dest += stride * 3, fb_offs += vram_stride) { - fb_offs &= 1024*512-1; + fb_offs &= vram_mask; bgr888_to_rgb888(dest, vram + fb_offs, w * 3); } } @@ -84,9 +107,9 @@ static void blit(void) else { dest += doffs * 2; - for (; h-- > 0; dest += stride * 2, fb_offs += 1024) + for (; h-- > 0; dest += stride * 2, fb_offs += vram_stride) { - fb_offs &= 1024*512-1; + fb_offs &= vram_mask; bgr555_to_rgb565(dest, vram + fb_offs, w * 2); } } -- 2.39.2