From 0b02eb7712f1272fa7f38b0af41968b53af3b5a8 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 13 Aug 2012 00:02:23 +0300 Subject: add support for software-enhanced rendering --- frontend/main.c | 2 ++ frontend/menu.c | 8 +++++++- frontend/plugin_lib.h | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'frontend') diff --git a/frontend/main.c b/frontend/main.c index 19e8319..c98e9e0 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 42a53e1..2fc56ba 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 bcf74ac..7687bf8 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; -- cgit v1.2.3 From d81b8e972678928ffece2d38213de8048f5e872d Mon Sep 17 00:00:00 2001 From: notaz Date: Wed, 15 Aug 2012 21:52:52 +0300 Subject: frontend: add renderer toggle option --- frontend/main.c | 5 +++++ frontend/main.h | 1 + frontend/menu.c | 1 + frontend/plat_pandora.c | 1 + 4 files changed, 8 insertions(+) (limited to 'frontend') diff --git a/frontend/main.c b/frontend/main.c index c98e9e0..7c15cb0 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -232,6 +232,11 @@ do_state_slot: pl_rearmed_cbs.frameskip == 0 ? "OFF" : "1" ); plugin_call_rearmed_cbs(); break; + case SACTION_TOGGLE_RENDERER: + pl_rearmed_cbs.gpu_neon.enhancement_enable = + !pl_rearmed_cbs.gpu_neon.enhancement_enable; + plugin_call_rearmed_cbs(); + break; case SACTION_SCREENSHOT: { char buf[MAXPATHLEN]; diff --git a/frontend/main.h b/frontend/main.h index bdb4870..56e1e73 100644 --- a/frontend/main.h +++ b/frontend/main.h @@ -65,6 +65,7 @@ enum sched_action { SACTION_NEXT_SSLOT, SACTION_PREV_SSLOT, SACTION_TOGGLE_FSKIP, + SACTION_TOGGLE_RENDERER, SACTION_SCREENSHOT, SACTION_VOLUME_UP, SACTION_VOLUME_DOWN, diff --git a/frontend/menu.c b/frontend/menu.c index 2fc56ba..f0fd17c 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -663,6 +663,7 @@ me_bind_action emuctrl_actions[] = { "Next Save Slot ", 1 << SACTION_NEXT_SSLOT }, { "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP }, { "Take Screenshot ", 1 << SACTION_SCREENSHOT }, + { "Toggle Renderer ", 1 << SACTION_TOGGLE_RENDERER }, { "Enter Menu ", 1 << SACTION_ENTER_MENU }, #ifdef __ARM_ARCH_7A__ /* XXX */ { "Minimize ", 1 << SACTION_MINIMIZE }, diff --git a/frontend/plat_pandora.c b/frontend/plat_pandora.c index 9ec747d..b6447cf 100644 --- a/frontend/plat_pandora.c +++ b/frontend/plat_pandora.c @@ -65,6 +65,7 @@ static const struct in_default_bind in_evdev_defbinds[] = { { KEY_4, IN_BINDTYPE_EMU, SACTION_NEXT_SSLOT }, { KEY_5, IN_BINDTYPE_EMU, SACTION_TOGGLE_FSKIP }, { KEY_6, IN_BINDTYPE_EMU, SACTION_SCREENSHOT }, + { KEY_7, IN_BINDTYPE_EMU, SACTION_TOGGLE_RENDERER }, { 0, 0, 0 } }; -- cgit v1.2.3 From 99d767a0cbf8ee7406000cbac647d9681d885282 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 18 Aug 2012 01:39:37 +0300 Subject: frontend: omap; increase vram allocation --- frontend/plat_omap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'frontend') diff --git a/frontend/plat_omap.c b/frontend/plat_omap.c index b01c634..e5b6c04 100644 --- a/frontend/plat_omap.c +++ b/frontend/plat_omap.c @@ -52,8 +52,9 @@ static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h) perror("SETUP_PLANE"); } - if (mi.size < 640*512*3*3) { - mi.size = 640*512*3*3; + // upto 1024x512 (2x resolution enhancement) + if (mi.size < 1024*512*2 * 3) { + mi.size = 1024*512*2 * 3; ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi); if (ret != 0) { perror("SETUP_MEM"); -- cgit v1.2.3 From 9ee0fd5b333039b1140d90f935aa9299825f1e42 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 19 Aug 2012 22:39:49 +0300 Subject: start mmap'ing vram, with hugetlb if possible --- frontend/common/plat.h | 4 ++++ frontend/linux/plat.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- frontend/plugin_lib.c | 13 +++++++++++++ frontend/plugin_lib.h | 2 ++ 4 files changed, 61 insertions(+), 5 deletions(-) (limited to 'frontend') diff --git a/frontend/common/plat.h b/frontend/common/plat.h index 0a9fc0b..416f8ac 100644 --- a/frontend/common/plat.h +++ b/frontend/common/plat.h @@ -45,6 +45,10 @@ int plat_is_dir(const char *path); int plat_wait_event(int *fds_hnds, int count, int timeout_ms); void plat_sleep_ms(int ms); +void *plat_mmap(unsigned long addr, size_t size, int need_exec); +void *plat_mremap(void *ptr, size_t oldsize, size_t newsize); +void plat_munmap(void *ptr, size_t size); + /* timers, to be used for time diff and must refer to the same clock */ unsigned int plat_get_ticks_ms(void); unsigned int plat_get_ticks_us(void); diff --git a/frontend/linux/plat.c b/frontend/linux/plat.c index b7152b5..044084e 100644 --- a/frontend/linux/plat.c +++ b/frontend/linux/plat.c @@ -17,9 +17,17 @@ #include #include #include +#include #include "../common/plat.h" +/* XXX: maybe unhardcode pagesize? */ +#define HUGETLB_PAGESIZE (2 * 1024 * 1024) +#define HUGETLB_THRESHOLD (HUGETLB_PAGESIZE / 2) +#ifndef MAP_HUGETLB +#define MAP_HUGETLB 0x40000 /* arch specific */ +#endif + int plat_is_dir(const char *path) { @@ -126,16 +134,34 @@ int plat_wait_event(int *fds_hnds, int count, int timeout_ms) return ret; } -void *plat_mmap(unsigned long addr, size_t size) +void *plat_mmap(unsigned long addr, size_t size, int need_exec) { + static int hugetlb_disabled; + int prot = PROT_READ | PROT_WRITE; + int flags = MAP_PRIVATE | MAP_ANONYMOUS; void *req, *ret; req = (void *)addr; - ret = mmap(req, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (need_exec) + prot |= PROT_EXEC; + if (size >= HUGETLB_THRESHOLD && !hugetlb_disabled) + flags |= MAP_HUGETLB; + + ret = mmap(req, size, prot, flags, -1, 0); + if (ret == MAP_FAILED && (flags & MAP_HUGETLB)) { + fprintf(stderr, + "warning: failed to do hugetlb mmap (%p, %zu): %d\n", + req, size, errno); + hugetlb_disabled = 1; + flags &= ~MAP_HUGETLB; + ret = mmap(req, size, prot, flags, -1, 0); + } if (ret == MAP_FAILED) return NULL; - if (ret != req) - printf("warning: mmaped to %p, requested %p\n", ret, req); + + if (req != NULL && ret != req) + fprintf(stderr, + "warning: mmaped to %p, requested %p\n", ret, req); return ret; } @@ -155,7 +181,18 @@ void *plat_mremap(void *ptr, size_t oldsize, size_t newsize) void plat_munmap(void *ptr, size_t size) { - munmap(ptr, size); + int ret; + + ret = munmap(ptr, size); + if (ret != 0 && (size & (HUGETLB_PAGESIZE - 1))) { + // prehaps an autorounded hugetlb mapping? + size = (size + HUGETLB_PAGESIZE - 1) & ~(HUGETLB_PAGESIZE - 1); + ret = munmap(ptr, size); + } + if (ret != 0) { + fprintf(stderr, + "munmap(%p, %zu) failed: %d\n", ptr, size, errno); + } } /* lprintf */ diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index 4dbb9a7..c2e2ab4 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -21,6 +21,7 @@ #include "linux/fbdev.h" #include "common/fonts.h" #include "common/input.h" +#include "common/plat.h" #include "menu.h" #include "main.h" #include "plat.h" @@ -484,12 +485,24 @@ static void pl_get_layer_pos(int *x, int *y, int *w, int *h) *h = g_layer_h; } +static void *pl_mmap(unsigned int size) +{ + return plat_mmap(0, size, 0); +} + +static void pl_munmap(void *ptr, unsigned int size) +{ + plat_munmap(ptr, size); +} + struct rearmed_cbs pl_rearmed_cbs = { pl_get_layer_pos, pl_vout_open, pl_vout_set_mode, pl_vout_flip, pl_vout_close, + pl_mmap, + pl_munmap, }; /* watchdog */ diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h index 7687bf8..1701d06 100644 --- a/frontend/plugin_lib.h +++ b/frontend/plugin_lib.h @@ -44,6 +44,8 @@ struct rearmed_cbs { void *(*pl_vout_set_mode)(int w, int h, int bpp); void *(*pl_vout_flip)(void); void (*pl_vout_close)(void); + void *(*mmap)(unsigned int size); + void (*munmap)(void *ptr, unsigned int size); // these are only used by some frontends void (*pl_vout_raw_flip)(int x, int y); void (*pl_vout_set_raw_vram)(void *vram); -- cgit v1.2.3 From a2ad8cc5a68892c8ae7d1964f4081f755654d325 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 21 Aug 2012 02:04:46 +0300 Subject: use plat_mmap for RAM too --- frontend/common/plat.h | 2 +- frontend/linux/plat.c | 4 +++- frontend/plugin_lib.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'frontend') diff --git a/frontend/common/plat.h b/frontend/common/plat.h index 416f8ac..1fb8767 100644 --- a/frontend/common/plat.h +++ b/frontend/common/plat.h @@ -45,7 +45,7 @@ int plat_is_dir(const char *path); int plat_wait_event(int *fds_hnds, int count, int timeout_ms); void plat_sleep_ms(int ms); -void *plat_mmap(unsigned long addr, size_t size, int need_exec); +void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed); void *plat_mremap(void *ptr, size_t oldsize, size_t newsize); void plat_munmap(void *ptr, size_t size); diff --git a/frontend/linux/plat.c b/frontend/linux/plat.c index 044084e..4ed1e65 100644 --- a/frontend/linux/plat.c +++ b/frontend/linux/plat.c @@ -134,7 +134,7 @@ int plat_wait_event(int *fds_hnds, int count, int timeout_ms) return ret; } -void *plat_mmap(unsigned long addr, size_t size, int need_exec) +void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed) { static int hugetlb_disabled; int prot = PROT_READ | PROT_WRITE; @@ -144,6 +144,8 @@ void *plat_mmap(unsigned long addr, size_t size, int need_exec) req = (void *)addr; if (need_exec) prot |= PROT_EXEC; + if (is_fixed) + flags |= MAP_FIXED; if (size >= HUGETLB_THRESHOLD && !hugetlb_disabled) flags |= MAP_HUGETLB; diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index c2e2ab4..484d67b 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -487,7 +487,7 @@ static void pl_get_layer_pos(int *x, int *y, int *w, int *h) static void *pl_mmap(unsigned int size) { - return plat_mmap(0, size, 0); + return plat_mmap(0, size, 0, 0); } static void pl_munmap(void *ptr, unsigned int size) -- cgit v1.2.3 From cd5abe38be33f4ac20627cbeac5246b9bee22715 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 22 Sep 2012 19:32:10 +0300 Subject: frontend: pandora: update run script --- frontend/pandora/pcsx.sh | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'frontend') diff --git a/frontend/pandora/pcsx.sh b/frontend/pandora/pcsx.sh index 0957b94..bc1d6c5 100755 --- a/frontend/pandora/pcsx.sh +++ b/frontend/pandora/pcsx.sh @@ -5,10 +5,15 @@ nub0mode=`cat /proc/pandora/nub0/mode` nub1mode=`cat /proc/pandora/nub1/mode` /usr/pandora/scripts/op_nubchange.sh absolute absolute +# 4MB for RAM (2+align) + 2MB for vram (1+overdraw) + 10MB for gpu_neon (8+overdraw) +# no big deal if this fails, only performance loss +sudo -n /usr/pandora/scripts/op_hugetlb.sh 16 + ./pcsx "$@" # restore stuff if pcsx crashes ./picorestore sudo -n /usr/pandora/scripts/op_lcdrate.sh 60 +sudo -n /usr/pandora/scripts/op_hugetlb.sh 0 /usr/pandora/scripts/op_nubchange.sh $nub0mode $nub1mode -- cgit v1.2.3 From fa56d36096cd4ab2b227ce2aa61c8404b8874689 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 29 Oct 2012 01:08:35 +0200 Subject: move blit to core, allow filtering while blitting also adds libpicofe to pull filters from, and filter related UI stuff --- frontend/libpicofe | 1 + frontend/libretro.c | 43 +++++++--- frontend/main.c | 9 +- frontend/main.h | 2 +- frontend/menu.c | 27 ++++-- frontend/menu.h | 8 +- frontend/plat_pandora.c | 2 +- frontend/plat_pollux.c | 33 ++++---- frontend/plugin_lib.c | 219 ++++++++++++++++++++++++++++++++++++++++++------ frontend/plugin_lib.h | 19 +++-- 10 files changed, 292 insertions(+), 71 deletions(-) create mode 160000 frontend/libpicofe (limited to 'frontend') diff --git a/frontend/libpicofe b/frontend/libpicofe new file mode 160000 index 0000000..6ce097b --- /dev/null +++ b/frontend/libpicofe @@ -0,0 +1 @@ +Subproject commit 6ce097ba2f3cd1c269bacd032b775b6d296433fc diff --git a/frontend/libretro.c b/frontend/libretro.c index 9bbea5b..d1cb400 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -13,6 +13,7 @@ #include "../libpcsxcore/psxcounters.h" #include "../libpcsxcore/new_dynarec/new_dynarec.h" #include "../plugins/dfsound/out.h" +#include "../plugins/gpulib/cspace.h" #include "main.h" #include "plugin.h" #include "plugin_lib.h" @@ -26,7 +27,6 @@ static retro_environment_t environ_cb; static retro_audio_sample_batch_t audio_batch_cb; static void *vout_buf; -static int vout_width, vout_height; static int samples_sent, samples_to_send; static int plugins_opened; @@ -41,11 +41,8 @@ static int vout_open(void) return 0; } -static void *vout_set_mode(int w, int h, int bpp) +static void vout_set_mode(int w, int h, int bpp) { - vout_width = w; - vout_height = h; - return vout_buf; } /* FIXME: either teach PCSX to blit to RGB1555 or RetroArch to support RGB565 */ @@ -59,13 +56,39 @@ static void convert(void *buf, size_t bytes) } } -static void *vout_flip(void) +static void vout_flip(const void *vram, int stride, int bgr24, int w, int h) { - pl_rearmed_cbs.flip_cnt++; - convert(vout_buf, vout_width * vout_height * 2); - video_cb(vout_buf, vout_width, vout_height, vout_width * 2); + unsigned short *dest = vout_buf; + const unsigned short *src = vram; + int dstride = w, h1 = h; + + if (vram == NULL) { + // blanking + memset(pl_vout_buf, 0, dstride * h * 2); + goto out; + } + + if (bgr24) + { + // XXX: could we switch to RETRO_PIXEL_FORMAT_XRGB8888 here? + for (; h1-- > 0; dest += dstride, src += stride) + { + bgr888_to_rgb565(dest, src, w * 3); + } + } + else + { + for (; h1-- > 0; dest += dstride, src += stride) + { + bgr555_to_rgb565(dest, src, w * 2); + } + } + - return vout_buf; +out: + convert(vout_buf, w * h * 2); + video_cb(vout_buf, w, h, w * 2); + pl_rearmed_cbs.flip_cnt++; } static void vout_close(void) diff --git a/frontend/main.c b/frontend/main.c index 7c15cb0..56b5cb7 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -232,10 +232,13 @@ do_state_slot: pl_rearmed_cbs.frameskip == 0 ? "OFF" : "1" ); plugin_call_rearmed_cbs(); break; - case SACTION_TOGGLE_RENDERER: - pl_rearmed_cbs.gpu_neon.enhancement_enable = - !pl_rearmed_cbs.gpu_neon.enhancement_enable; + case SACTION_SWITCH_DISPMODE: + pl_switch_dispmode(); plugin_call_rearmed_cbs(); + if (GPU_open != NULL && GPU_close != NULL) { + GPU_close(); + GPU_open(&gpuDisp, "PCSX", NULL); + } break; case SACTION_SCREENSHOT: { diff --git a/frontend/main.h b/frontend/main.h index 56e1e73..a03db8b 100644 --- a/frontend/main.h +++ b/frontend/main.h @@ -65,7 +65,7 @@ enum sched_action { SACTION_NEXT_SSLOT, SACTION_PREV_SSLOT, SACTION_TOGGLE_FSKIP, - SACTION_TOGGLE_RENDERER, + SACTION_SWITCH_DISPMODE, SACTION_SCREENSHOT, SACTION_VOLUME_UP, SACTION_VOLUME_DOWN, diff --git a/frontend/menu.c b/frontend/menu.c index f0fd17c..d3ce06c 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -75,6 +75,7 @@ typedef enum MA_OPT_SCALER, MA_OPT_SCALER2, MA_OPT_FILTERING, + MA_OPT_FILTERING2, MA_OPT_SCALER_C, } menu_id; @@ -87,7 +88,7 @@ static int psx_clock; static int memcard1_sel, memcard2_sel; int g_opts, g_scaler; int soft_scaling, analog_deadzone; // for Caanoo -int filter; +int filter, soft_filter; #ifdef __ARM_ARCH_7A__ #define DEFAULT_PSX_CLOCK 57 @@ -213,6 +214,7 @@ static void menu_set_defconfig(void) frameskip = 0; analog_deadzone = 50; soft_scaling = 1; + soft_filter = 0; psx_clock = DEFAULT_PSX_CLOCK; region = 0; @@ -274,6 +276,7 @@ static const struct { CE_INTVAL(g_layer_w), CE_INTVAL(g_layer_h), CE_INTVAL(filter), + CE_INTVAL(soft_filter), CE_INTVAL(state_slot), CE_INTVAL(cpu_clock), CE_INTVAL(g_opts), @@ -663,7 +666,7 @@ me_bind_action emuctrl_actions[] = { "Next Save Slot ", 1 << SACTION_NEXT_SSLOT }, { "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP }, { "Take Screenshot ", 1 << SACTION_SCREENSHOT }, - { "Toggle Renderer ", 1 << SACTION_TOGGLE_RENDERER }, + { "Switch Renderer ", 1 << SACTION_SWITCH_DISPMODE }, { "Enter Menu ", 1 << SACTION_ENTER_MENU }, #ifdef __ARM_ARCH_7A__ /* XXX */ { "Minimize ", 1 << SACTION_MINIMIZE }, @@ -1032,9 +1035,15 @@ static int menu_loop_keyconfig(int id, int keys) // ------------ gfx options menu ------------ static const char *men_scaler[] = { "1x1", "scaled 4:3", "integer scaled 4:3", "fullscreen", "custom", NULL }; +static const char *men_soft_filter[] = { "None", +#ifdef __ARM_NEON__ + "scale2x", "eagle2x", +#endif + NULL }; +static const char *men_dummy[] = { NULL }; static const char h_cscaler[] = "Displays the scaler layer, you can resize it\n" "using d-pad or move it using R+d-pad"; -static const char *men_dummy[] = { NULL }; +static const char h_soft_filter[] = "Works only if game uses low resolution modes"; static int menu_loop_cscaler(int id, int keys) { @@ -1093,6 +1102,7 @@ static menu_entry e_menu_gfx_options[] = mee_enum ("Scaler", MA_OPT_SCALER, g_scaler, men_scaler), mee_onoff ("Software Scaling", MA_OPT_SCALER2, soft_scaling, 1), mee_enum ("Filter", MA_OPT_FILTERING, filter, men_dummy), + mee_enum_h ("Software Filter", MA_OPT_FILTERING2, soft_filter, men_soft_filter, h_soft_filter), // mee_onoff ("Vsync", 0, vsync, 1), mee_cust_h ("Setup custom scaler", MA_OPT_SCALER_C, menu_loop_cscaler, NULL, h_cscaler), mee_end, @@ -1121,9 +1131,13 @@ 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 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\n" + "(not available for high resolution games)"; +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[] = @@ -2254,6 +2268,7 @@ void menu_init(void) #ifndef __ARM_ARCH_7A__ /* XXX */ me_enable(e_menu_gfx_options, MA_OPT_SCALER, 0); me_enable(e_menu_gfx_options, MA_OPT_FILTERING, 0); + me_enable(e_menu_gfx_options, MA_OPT_FILTERING2, 0); me_enable(e_menu_gfx_options, MA_OPT_SCALER_C, 0); me_enable(e_menu_keyconfig, MA_CTRL_NUBS_BTNS, 0); #else diff --git a/frontend/menu.h b/frontend/menu.h index 2062acd..221be15 100644 --- a/frontend/menu.h +++ b/frontend/menu.h @@ -22,9 +22,15 @@ enum g_scaler_opts { SCALE_CUSTOM, }; +enum g_soft_filter_opts { + SOFT_FILTER_NONE, + SOFT_FILTER_SCALE2X, + SOFT_FILTER_EAGLE2X, +}; + extern int g_opts, g_scaler; extern int soft_scaling, analog_deadzone; -extern int filter; +extern int filter, soft_filter; extern int g_menuscreen_w; extern int g_menuscreen_h; diff --git a/frontend/plat_pandora.c b/frontend/plat_pandora.c index b6447cf..b82450c 100644 --- a/frontend/plat_pandora.c +++ b/frontend/plat_pandora.c @@ -65,7 +65,7 @@ static const struct in_default_bind in_evdev_defbinds[] = { { KEY_4, IN_BINDTYPE_EMU, SACTION_NEXT_SSLOT }, { KEY_5, IN_BINDTYPE_EMU, SACTION_TOGGLE_FSKIP }, { KEY_6, IN_BINDTYPE_EMU, SACTION_SCREENSHOT }, - { KEY_7, IN_BINDTYPE_EMU, SACTION_TOGGLE_RENDERER }, + { KEY_7, IN_BINDTYPE_EMU, SACTION_SWITCH_DISPMODE }, { 0, 0, 0 } }; diff --git a/frontend/plat_pollux.c b/frontend/plat_pollux.c index 1dafb7c..52a09b1 100644 --- a/frontend/plat_pollux.c +++ b/frontend/plat_pollux.c @@ -305,12 +305,13 @@ static void spend_cycles(int loops) #define DMA_REG(x) memregl[(DMA_BASE6 + x) >> 2] /* this takes ~1.5ms, while ldm/stm ~1.95ms */ -static void raw_flip_dma(int x, int y) +static void raw_flip_dma(const void *vram, int stride, int bgr24, int w, int h) { + unsigned int pixel_offset = psx_vram - (unsigned short *)vram; unsigned int dst = fb_paddrs[fb_work_buf] + (fb_offset_y * 320 + fb_offset_x) * psx_bpp / 8; - int spsx_line = y + psx_offset_y; - int spsx_offset = (x + psx_offset_x) & 0x3f8; + int spsx_line = pixel_offset / 1024 + psx_offset_y; + int spsx_offset = (pixel_offset + psx_offset_x) & 0x3f8; int dst_stride = 320 * psx_bpp / 8; int len = psx_src_width * psx_bpp / 8; int i; @@ -344,7 +345,7 @@ static void raw_flip_dma(int x, int y) if (psx_bpp == 16) { pl_vout_buf = g_menuscreen_ptr; - pl_print_hud(fb_offset_x); + pl_print_hud(w, h, fb_offset_x); } g_menuscreen_ptr = fb_flip(); @@ -354,26 +355,24 @@ static void raw_flip_dma(int x, int y) } #define make_flip_func(name, blitfunc) \ -static void name(int x, int y) \ +static void name(const void *vram_, int stride, int bgr24, int w, int h) \ { \ - unsigned short *vram = psx_vram; \ + const unsigned short *vram = vram_; \ unsigned char *dst = (unsigned char *)g_menuscreen_ptr + \ (fb_offset_y * 320 + fb_offset_x) * psx_bpp / 8; \ - unsigned int src = (y + psx_offset_y) * 1024 + x + psx_offset_x; \ int dst_stride = 320 * psx_bpp / 8; \ int len = psx_src_width * psx_bpp / 8; \ int i; \ \ pcnt_start(PCNT_BLIT); \ \ - for (i = psx_src_height; i > 0; i--, src += psx_step * 1024, dst += dst_stride) { \ - src &= 1024*512-1; \ - blitfunc(dst, vram + src, len); \ - } \ + vram += psx_offset_y * 1024 + psx_offset_x; \ + for (i = psx_src_height; i > 0; i--, vram += psx_step * 1024, dst += dst_stride)\ + blitfunc(dst, vram, len); \ \ if (psx_bpp == 16) { \ pl_vout_buf = g_menuscreen_ptr; \ - pl_print_hud(fb_offset_x); \ + pl_print_hud(w, h, fb_offset_x); \ } \ \ g_menuscreen_ptr = fb_flip(); \ @@ -402,20 +401,20 @@ void *plat_gvideo_set_mode(int *w_, int *h_, int *bpp_) switch (w + (bpp != 16) + !soft_scaling) { case 640: - pl_rearmed_cbs.pl_vout_raw_flip = raw_flip_soft_640; + pl_rearmed_cbs.pl_vout_flip = raw_flip_soft_640; w_max = 640; break; case 512: - pl_rearmed_cbs.pl_vout_raw_flip = raw_flip_soft_512; + pl_rearmed_cbs.pl_vout_flip = raw_flip_soft_512; w_max = 512; break; case 384: case 368: - pl_rearmed_cbs.pl_vout_raw_flip = raw_flip_soft_368; + pl_rearmed_cbs.pl_vout_flip = raw_flip_soft_368; w_max = 368; break; default: - pl_rearmed_cbs.pl_vout_raw_flip = have_warm ? raw_flip_dma : raw_flip_soft; + pl_rearmed_cbs.pl_vout_flip = have_warm ? raw_flip_dma : raw_flip_soft; w_max = 320; break; } @@ -621,7 +620,7 @@ void plat_init(void) if (mixerdev == -1) perror("open(/dev/mixer)"); - pl_rearmed_cbs.pl_vout_raw_flip = have_warm ? raw_flip_dma : raw_flip_soft; + pl_rearmed_cbs.pl_vout_flip = have_warm ? raw_flip_dma : raw_flip_soft; pl_rearmed_cbs.pl_vout_set_raw_vram = pl_vout_set_raw_vram; psx_src_width = 320; diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index 484d67b..bf213dd 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -27,8 +27,11 @@ #include "plat.h" #include "pcnt.h" #include "pl_gun_ts.h" +#include "libpicofe/arm/neon_scale2x.h" +#include "libpicofe/arm/neon_eagle2x.h" #include "../libpcsxcore/new_dynarec/new_dynarec.h" #include "../libpcsxcore/psemu_plugin_defs.h" +#include "../plugins/gpulib/cspace.h" int in_type1, in_type2; int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 }; @@ -39,6 +42,7 @@ void *tsdev; void *pl_vout_buf; int g_layer_x, g_layer_y, g_layer_w, g_layer_h; static int pl_vout_w, pl_vout_h, pl_vout_bpp; /* output display/layer */ +static int pl_vout_scale; static int psx_w, psx_h, psx_bpp; static int vsync_cnt; static int is_pal, frame_interval, frame_interval1024; @@ -114,10 +118,8 @@ static __attribute__((noinline)) void draw_active_chans(int vout_w, int vout_h) } } -void pl_print_hud(int xborder) +void pl_print_hud(int w, int h, int xborder) { - int w = pl_vout_w, h = pl_vout_h; - if (h < 16) return; @@ -185,55 +187,142 @@ static void update_layer_size(int w, int h) if (g_layer_h > g_menuscreen_h) g_layer_h = g_menuscreen_h; } -static void *pl_vout_set_mode(int w, int h, int bpp) +// XXX: this is platform specific really +static int resolution_ok(int w, int h) { + return w <= 1024 && h <= 512; +} + +static void pl_vout_set_mode(int w, int h, int bpp) +{ + int vout_w, vout_h, vout_bpp; + // special h handling, Wipeout likes to change it by 1-6 static int vsync_cnt_ms_prev; if ((unsigned int)(vsync_cnt - vsync_cnt_ms_prev) < 5*60) h = (h + 7) & ~7; vsync_cnt_ms_prev = vsync_cnt; - if (w == psx_w && h == psx_h && bpp == psx_bpp) - return pl_vout_buf; + vout_w = psx_w = w; + vout_h = psx_h = h; + vout_bpp = psx_bpp = bpp; + + pl_vout_scale = 1; +#ifdef __ARM_NEON__ + if (soft_filter) { + if (resolution_ok(w * 2, h * 2) && bpp == 16) { + vout_w *= 2; + vout_h *= 2; + pl_vout_scale = 2; + } + else { + // filter unavailable + hud_msg[0] = 0; + } + } +#endif - pl_vout_w = psx_w = w; - pl_vout_h = psx_h = h; - pl_vout_bpp = psx_bpp = bpp; + if (pl_vout_buf != NULL && vout_w == pl_vout_w && vout_h == pl_vout_h + && vout_bpp == pl_vout_bpp) + return; - update_layer_size(pl_vout_w, pl_vout_h); + update_layer_size(vout_w, vout_h); - pl_vout_buf = plat_gvideo_set_mode(&pl_vout_w, &pl_vout_h, &pl_vout_bpp); - if (pl_vout_buf == NULL && pl_rearmed_cbs.pl_vout_raw_flip == NULL) + pl_vout_buf = plat_gvideo_set_mode(&vout_w, &vout_h, &vout_bpp); + if (pl_vout_buf == NULL) fprintf(stderr, "failed to set mode %dx%d@%d\n", psx_w, psx_h, psx_bpp); + else { + pl_vout_w = vout_w; + pl_vout_h = vout_h; + pl_vout_bpp = vout_bpp; + } menu_notify_mode_change(pl_vout_w, pl_vout_h, pl_vout_bpp); - - return pl_vout_buf; } -// only used if raw flip is not defined -static void *pl_vout_flip(void) +static void pl_vout_flip(const void *vram, int stride, int bgr24, int w, int h) { - pl_rearmed_cbs.flip_cnt++; + static int doffs_old, clear_counter; + unsigned char *dest = pl_vout_buf; + const unsigned short *src = vram; + int dstride = pl_vout_w, h1 = h; + int doffs; + + if (dest == NULL) + goto out; + + if (vram == NULL) { + // blanking + memset(pl_vout_buf, 0, dstride * pl_vout_h * pl_vout_bpp / 8); + goto out; + } + + // borders + doffs = (dstride - w * pl_vout_scale) / 2 & ~1; + dest += doffs * 2; + + if (doffs > doffs_old) + clear_counter = 2; + doffs_old = doffs; + + if (clear_counter > 0) { + memset(pl_vout_buf, 0, dstride * pl_vout_h * pl_vout_bpp / 8); + clear_counter--; + } + + if (bgr24) + { + if (pl_rearmed_cbs.only_16bpp) { + for (; h1-- > 0; dest += dstride * 2, src += stride) + { + bgr888_to_rgb565(dest, src, w * 3); + } + } + else { + dest -= doffs * 2; + dest += (doffs / 8) * 24; + + for (; h1-- > 0; dest += dstride * 3, src += stride) + { + bgr888_to_rgb888(dest, src, w * 3); + } + } + } +#ifdef __ARM_NEON__ + else if (soft_filter == SOFT_FILTER_SCALE2X && pl_vout_scale == 2) + { + neon_scale2x_16_16(src, (void *)dest, w, + stride * 2, dstride * 2, h1); + } + else if (soft_filter == SOFT_FILTER_EAGLE2X && pl_vout_scale == 2) + { + neon_eagle2x_16_16(src, (void *)dest, w, + stride * 2, dstride * 2, h1); + } +#endif + else + { + for (; h1-- > 0; dest += dstride * 2, src += stride) + { + bgr555_to_rgb565(dest, src, w * 2); + } + } - if (pl_vout_buf != NULL) - pl_print_hud(0); + pl_print_hud(w * pl_vout_scale, h * pl_vout_scale, 0); +out: // let's flip now pl_vout_buf = plat_gvideo_flip(); - return pl_vout_buf; + pl_rearmed_cbs.flip_cnt++; } static int pl_vout_open(void) { struct timeval now; - int h; - // force mode update - h = psx_h; - psx_h--; - pl_vout_buf = pl_vout_set_mode(psx_w, h, psx_bpp); + // force mode update on pl_vout_set_mode() call from gpulib/vout_pl + pl_vout_buf = NULL; plat_gvideo_open(is_pal); @@ -250,6 +339,11 @@ static void pl_vout_close(void) plat_gvideo_close(); } +static void pl_set_gpu_caps(int caps) +{ + pl_rearmed_cbs.gpu_caps = caps; +} + void *pl_prepare_screenshot(int *w, int *h, int *bpp) { void *ret = plat_prepare_screenshot(w, h, bpp); @@ -263,6 +357,75 @@ void *pl_prepare_screenshot(int *w, int *h, int *bpp) return pl_vout_buf; } +/* display/redering mode switcher */ +static int dispmode_default(void) +{ + pl_rearmed_cbs.gpu_neon.enhancement_enable = 0; + soft_filter = SOFT_FILTER_NONE; + snprintf(hud_msg, sizeof(hud_msg), "default mode"); + return 1; +} + +int dispmode_doubleres(void) +{ + if (!(pl_rearmed_cbs.gpu_caps & GPU_CAP_SUPPORTS_2X) + || !resolution_ok(psx_w * 2, psx_h * 2) || psx_bpp != 16) + return 0; + + dispmode_default(); + pl_rearmed_cbs.gpu_neon.enhancement_enable = 1; + snprintf(hud_msg, sizeof(hud_msg), "double resolution"); + return 1; +} + +int dispmode_scale2x(void) +{ + if (psx_bpp != 16) + return 0; + + dispmode_default(); + soft_filter = SOFT_FILTER_SCALE2X; + snprintf(hud_msg, sizeof(hud_msg), "scale2x"); + return 1; +} + +int dispmode_eagle2x(void) +{ + if (psx_bpp != 16) + return 0; + + dispmode_default(); + soft_filter = SOFT_FILTER_EAGLE2X; + snprintf(hud_msg, sizeof(hud_msg), "eagle2x"); + return 1; +} + +static int (*dispmode_switchers[])(void) = { + dispmode_default, +#ifdef __ARM_NEON__ + dispmode_doubleres, + dispmode_scale2x, + dispmode_eagle2x, +#endif +}; + +static int dispmode_current; + +void pl_switch_dispmode(void) +{ + if (pl_rearmed_cbs.gpu_caps & GPU_CAP_OWNS_DISPLAY) + return; + + while (1) { + dispmode_current++; + if (dispmode_current >= + sizeof(dispmode_switchers) / sizeof(dispmode_switchers[0])) + dispmode_current = 0; + if (dispmode_switchers[dispmode_current]()) + break; + } +} + #ifndef MAEMO static void update_analogs(void) { @@ -501,8 +664,10 @@ struct rearmed_cbs pl_rearmed_cbs = { pl_vout_set_mode, pl_vout_flip, pl_vout_close, - pl_mmap, - pl_munmap, + + .mmap = pl_mmap, + .munmap = pl_munmap, + .pl_set_gpu_caps = pl_set_gpu_caps, }; /* watchdog */ diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h index 1701d06..332fbc2 100644 --- a/frontend/plugin_lib.h +++ b/frontend/plugin_lib.h @@ -31,7 +31,8 @@ void pl_text_out16(int x, int y, const char *texto, ...); void pl_start_watchdog(void); void *pl_prepare_screenshot(int *w, int *h, int *bpp); void pl_init(void); -void pl_print_hud(int xborder); +void pl_print_hud(int width, int height, int xborder); +void pl_switch_dispmode(void); void pl_timing_prepare(int is_pal); void pl_frame_limit(void); @@ -41,14 +42,15 @@ void pl_update_gun(int *xn, int *xres, int *y, int *in); struct rearmed_cbs { void (*pl_get_layer_pos)(int *x, int *y, int *w, int *h); int (*pl_vout_open)(void); - void *(*pl_vout_set_mode)(int w, int h, int bpp); - void *(*pl_vout_flip)(void); + void (*pl_vout_set_mode)(int w, int h, int bpp); + void (*pl_vout_flip)(const void *vram, int stride, int bgr24, + int w, int h); void (*pl_vout_close)(void); void *(*mmap)(unsigned int size); void (*munmap)(void *ptr, unsigned int size); - // these are only used by some frontends - void (*pl_vout_raw_flip)(int x, int y); + // only used by some frontends void (*pl_vout_set_raw_vram)(void *vram); + void (*pl_set_gpu_caps)(int caps); // some stats, for display by some plugins int flips_per_sec, cpu_usage; float vsps_cur; // currect vsync/s @@ -82,10 +84,17 @@ struct rearmed_cbs { int iUseMask, bOpaquePass, bAdvancedBlend, bUseFastMdec; int iVRamSize, iTexGarbageCollection; } gpu_peopsgl; + // misc + int gpu_caps; }; extern struct rearmed_cbs pl_rearmed_cbs; +enum gpu_plugin_caps { + GPU_CAP_OWNS_DISPLAY = (1 << 0), + GPU_CAP_SUPPORTS_2X = (1 << 1), +}; + #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif -- cgit v1.2.3 From bcb62992749a7f66e9a16a8022e090ff334c4424 Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 1 Nov 2012 20:11:39 +0200 Subject: frontend: make text bg dark --- frontend/plugin_lib.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'frontend') diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index bf213dd..3ee5947 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -606,16 +606,31 @@ void pl_timing_prepare(int is_pal_) static void pl_text_out16_(int x, int y, const char *text) { - int i, l, len = strlen(text), w = pl_vout_w; - unsigned short *screen = (unsigned short *)pl_vout_buf + x + y * w; + int i, l, w = pl_vout_w; + unsigned short *screen; unsigned short val = 0xffff; - for (i = 0; i < len; i++, screen += 8) + x &= ~1; + screen = (unsigned short *)pl_vout_buf + x + y * w; + for (i = 0; ; i++, screen += 8) { + char c = text[i]; + if (c == 0) + break; + if (c == ' ') + continue; + for (l = 0; l < 8; l++) { - unsigned char fd = fontdata8x8[text[i] * 8 + l]; + unsigned char fd = fontdata8x8[c * 8 + l]; unsigned short *s = screen + l * w; + unsigned int *s32 = (void *)s; + + s32[0] = (s32[0] >> 1) & 0x7bef7bef; + s32[1] = (s32[1] >> 1) & 0x7bef7bef; + s32[2] = (s32[2] >> 1) & 0x7bef7bef; + s32[3] = (s32[3] >> 1) & 0x7bef7bef; + if (fd&0x80) s[0] = val; if (fd&0x40) s[1] = val; if (fd&0x20) s[2] = val; -- cgit v1.2.3