add support for software-enhanced rendering
authornotaz <notasas@gmail.com>
Sun, 12 Aug 2012 21:02:23 +0000 (00:02 +0300)
committernotaz <notasas@gmail.com>
Thu, 11 Oct 2012 21:05:07 +0000 (00:05 +0300)
frontend/main.c
frontend/menu.c
frontend/plugin_lib.h
plugins/gpulib/gpu.c
plugins/gpulib/gpu.h
plugins/gpulib/vout_pl.c

index 19e8319..c98e9e0 100644 (file)
@@ -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 =
index 42a53e1..2fc56ba 100644 (file)
@@ -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;
 }
index bcf74ac..7687bf8 100644 (file)
@@ -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;
index 46e92d1..462e301 100644 (file)
@@ -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);
index 1cbe38c..f514395 100644 (file)
@@ -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;
index 0bd1ecf..47c28f3 100644 (file)
@@ -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);
     }
   }