aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontend/main.c2
-rw-r--r--frontend/menu.c8
-rw-r--r--frontend/plugin_lib.h2
-rw-r--r--plugins/gpulib/gpu.c15
-rw-r--r--plugins/gpulib/gpu.h4
-rw-r--r--plugins/gpulib/vout_pl.c43
6 files changed, 63 insertions, 11 deletions
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;
diff --git a/plugins/gpulib/gpu.c b/plugins/gpulib/gpu.c
index 46e92d1..462e301 100644
--- a/plugins/gpulib/gpu.c
+++ b/plugins/gpulib/gpu.c
@@ -9,6 +9,7 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#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 1cbe38c..f514395 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 0bd1ecf..47c28f3 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);
}
}