psx_gpu: select buffers differently
authornotaz <notasas@gmail.com>
Sun, 21 Oct 2012 22:42:56 +0000 (01:42 +0300)
committernotaz <notasas@gmail.com>
Tue, 23 Oct 2012 22:10:16 +0000 (01:10 +0300)
this handles weird drawing areas better

plugins/gpu_neon/psx_gpu/psx_gpu.h
plugins/gpu_neon/psx_gpu/psx_gpu_4x.c
plugins/gpu_neon/psx_gpu/psx_gpu_parse.c
plugins/gpu_neon/psx_gpu_if.c
plugins/gpulib/vout_pl.c

index f8547f3..846658c 100644 (file)
@@ -188,10 +188,11 @@ typedef struct
   s16 saved_viewport_start_y;
   s16 saved_viewport_end_x;
   s16 saved_viewport_end_y;
+  u8 enhancement_buf_by_x16[64];
 
   // Align up to 64 byte boundary to keep the upcoming buffers cache line
   // aligned, also make reachable with single immediate addition
-  u8 reserved_a[228];
+  u8 reserved_a[164];
 
   // 8KB
   block_struct blocks[MAX_BLOCKS_PER_ROW];
index 19c4a9e..83c6680 100644 (file)
@@ -1,3 +1,7 @@
+#define select_enhancement_buf_ptr(psx_gpu, x) \\r
+  ((psx_gpu)->enhancement_buf_ptr + \\r
+   ((psx_gpu)->enhancement_buf_by_x16[(x) / 16] << 20))\r
+\r
 #ifndef NEON_BUILD\r
 void setup_sprite_16bpp_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, s32 u,\r
  s32 v, s32 width, s32 height, u32 color)\r
@@ -331,6 +335,8 @@ void render_sprite_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, u32 u, u32 v,
   if((width <= 0) || (height <= 0))\r
     return;\r
 \r
+  psx_gpu->vram_out_ptr = select_enhancement_buf_ptr(psx_gpu, x);\r
+\r
   x *= 2;\r
   y *= 2;\r
 \r
index 4260bc7..0536613 100644 (file)
@@ -762,17 +762,26 @@ breakloop:
 
 #ifdef PCSX
 
-static void *select_enhancement_buf_ptr(psx_gpu_struct *psx_gpu, u32 x)
+static void update_enhancement_buf_table(psx_gpu_struct *psx_gpu)
 {
-  u32 b;
-  for (b = 0; x >= psx_gpu->enhancement_x_threshold; b++)
-    x -= psx_gpu->enhancement_x_threshold;
-  return psx_gpu->enhancement_buf_ptr + b * 1024 * 1024;
+  u32 b, x, s;
+
+  b = 0;
+  s = psx_gpu->enhancement_x_threshold;
+  for (x = 0; x < sizeof(psx_gpu->enhancement_buf_by_x16); x++)
+  {
+    if (x * 16 >= s - 15)
+    {
+      s += psx_gpu->enhancement_x_threshold;
+      b++;
+    }
+    psx_gpu->enhancement_buf_by_x16[x] = b;
+  }
 }
 
 #define select_enhancement_buf(psx_gpu) \
   psx_gpu->enhancement_current_buf_ptr = \
-    select_enhancement_buf_ptr(psx_gpu, psx_gpu->saved_viewport_start_x + 8)
+    select_enhancement_buf_ptr(psx_gpu, psx_gpu->saved_viewport_start_x)
 
 #define enhancement_disable() { \
   psx_gpu->vram_out_ptr = psx_gpu->vram_ptr; \
@@ -939,12 +948,12 @@ static void do_sprite_enhanced(psx_gpu_struct *psx_gpu, int x, int y,
   u32 flags = (cmd_rgb >> 24);
   u32 color = cmd_rgb & 0xffffff;
 
-  psx_gpu->vram_out_ptr = psx_gpu->enhancement_current_buf_ptr;
   render_sprite_4x(psx_gpu, x, y, u, v, w, h, flags, color);
 }
 #endif
 
-u32 gpu_parse_enhanced(psx_gpu_struct *psx_gpu, u32 *list, u32 size, u32 *last_command)
+u32 gpu_parse_enhanced(psx_gpu_struct *psx_gpu, u32 *list, u32 size,
+ u32 *last_command)
 {
   u32 current_command = 0, command_length;
 
@@ -987,7 +996,7 @@ u32 gpu_parse_enhanced(psx_gpu_struct *psx_gpu, u32 *list, u32 size, u32 *last_c
 
         do_fill(psx_gpu, x, y, width, height, color);
 
-        psx_gpu->vram_out_ptr = psx_gpu->enhancement_current_buf_ptr;
+        psx_gpu->vram_out_ptr = select_enhancement_buf_ptr(psx_gpu, x);
         x *= 2;
         y *= 2;
         width *= 2;
@@ -1403,10 +1412,20 @@ u32 gpu_parse_enhanced(psx_gpu_struct *psx_gpu, u32 *list, u32 size, u32 *last_c
       }
   
       case 0xE3:
+      {
+        u32 d;
         psx_gpu->viewport_start_x = list[0] & 0x3FF;
         psx_gpu->viewport_start_y = (list[0] >> 10) & 0x1FF;
         psx_gpu->saved_viewport_start_x = psx_gpu->viewport_start_x;
         psx_gpu->saved_viewport_start_y = psx_gpu->viewport_start_y;
+
+        d = psx_gpu->enhancement_x_threshold - psx_gpu->viewport_start_x;
+        if(unlikely(0 < d && d <= 8))
+        {
+          // Grandia hack..
+          psx_gpu->enhancement_x_threshold = psx_gpu->viewport_start_x;
+          update_enhancement_buf_table(psx_gpu);
+        }
         select_enhancement_buf(psx_gpu);
 
 #ifdef TEXTURE_CACHE_4BPP
@@ -1417,7 +1436,8 @@ u32 gpu_parse_enhanced(psx_gpu_struct *psx_gpu, u32 *list, u32 size, u32 *last_c
 #endif
         SET_Ex(3, list[0]);
         break;
-  
+      }
+
       case 0xE4:
         psx_gpu->viewport_end_x = list[0] & 0x3FF;
         psx_gpu->viewport_end_y = (list[0] >> 10) & 0x1FF;
index c303742..62c4f9e 100644 (file)
@@ -85,32 +85,28 @@ void renderer_finish(void)
 static __attribute__((noinline)) void
 sync_enhancement_buffers(int x, int y, int w, int h)
 {
-  int xt = egpu.enhancement_x_threshold;
+  const int step_x = 1024 / sizeof(egpu.enhancement_buf_by_x16);
   u16 *src, *dst;
-  int wb, i;
+  int w1, fb_index;
 
-  w += x & 7;
-  x &= ~7;
-  w = (w + 7) & ~7;
+  w += x & (step_x - 1);
+  x &= ~(step_x - 1);
+  w = (w + step_x - 1) & ~(step_x - 1);
   if (y + h > 512)
     h = 512 - y;
 
-  for (i = 0; i < 4 && w > 0; i++) {
-    if (x < 512) {
-      wb = w;
-      if (x + w > 512)
-        wb = 512 - x;
-      src = gpu.vram + xt * i + y * 1024 + x;
-      dst = egpu.enhancement_buf_ptr +
-        (1024*1024 + xt * 2) * i + (y * 1024 + x) * 2;
-      scale2x_tiles8(dst, src, wb / 8, h);
-    }
-
-    x -= xt;
-    if (x < 0) {
-      w += x;
-      x = 0;
-    }
+  while (w > 0) {
+    fb_index = egpu.enhancement_buf_by_x16[x / step_x];
+    for (w1 = 0; w > 0; w1++, w -= step_x)
+      if (fb_index != egpu.enhancement_buf_by_x16[x / step_x + w1])
+        break;
+
+    src = gpu.vram + y * 1024 + x;
+    dst = select_enhancement_buf_ptr(&egpu, x);
+    dst += (y * 1024 + x) * 2;
+    scale2x_tiles8(dst, src, w1 * step_x / 8, h);
+
+    x += w1 * step_x;
   }
 }
 
@@ -143,7 +139,11 @@ void renderer_set_interlace(int enable, int is_odd)
 void renderer_notify_res_change(void)
 {
   // note: must keep it multiple of 8
-  egpu.enhancement_x_threshold = gpu.screen.hres;
+  if (egpu.enhancement_x_threshold != gpu.screen.hres)
+  {
+    egpu.enhancement_x_threshold = gpu.screen.hres;
+    update_enhancement_buf_table(&egpu);
+  }
 }
 
 #include "../../frontend/plugin_lib.h"
index 2116422..6e2764c 100644 (file)
@@ -130,11 +130,15 @@ void vout_update(void)
 
 void vout_blank(void)
 {
-  gpu.state.enhancement_active = 0;
-  check_mode_change();
   if (cbs->pl_vout_raw_flip == NULL) {
+    int w = gpu.screen.hres;
+    int h = gpu.screen.h;
     int bytespp = gpu.status.rgb24 ? 3 : 2;
-    memset(screen_buf, 0, gpu.screen.hres * gpu.screen.h * bytespp);
+    if (gpu.state.enhancement_active) {
+      w *= 2;
+      h *= 2;
+    }
+    memset(screen_buf, 0, w * h * bytespp);
     screen_buf = cbs->pl_vout_flip();
   }
 }