adjust vita's mappings to more resemble other platforms
[pcsx_rearmed.git] / plugins / gpulib / gpu.c
index 5e2e9e1..24fbf3b 100644 (file)
 #include <stdlib.h> /* for calloc */
 
 #include "gpu.h"
+#include "../../libpcsxcore/gpu.h" // meh
+#include "../../frontend/plugin_lib.h"
 
+#ifndef ARRAY_SIZE
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
 #ifdef __GNUC__
 #define unlikely(x) __builtin_expect((x), 0)
 #define preload __builtin_prefetch
@@ -74,7 +78,10 @@ static noinline void update_width(void)
   int hres = hres_all[(gpu.status >> 16) & 7];
   int pal = gpu.status & PSX_GPU_STATUS_PAL;
   int sw = gpu.screen.x2 - gpu.screen.x1;
+  int type = gpu.state.screen_centering_type;
   int x = 0, x_auto;
+  if (type == C_AUTO)
+    type = gpu.state.screen_centering_type_default;
   if (sw <= 0)
     /* nothing displayed? */;
   else {
@@ -83,10 +90,10 @@ static noinline void update_width(void)
     x = (x + 1) & ~1;   // blitter limitation
     sw /= hdiv;
     sw = (sw + 2) & ~3; // according to nocash
-    switch (gpu.state.screen_centering_type) {
-    case 1:
+    switch (type) {
+    case C_INGAME:
       break;
-    case 2:
+    case C_MANUAL:
       x = gpu.state.screen_centering_x;
       break;
     default:
@@ -128,9 +135,12 @@ static noinline void update_height(void)
     /* nothing displayed? */;
   else {
     switch (gpu.state.screen_centering_type) {
-    case 1:
+    case C_INGAME:
       break;
-    case 2:
+    case C_BORDERLESS:
+      y = 0;
+      break;
+    case C_MANUAL:
       y = gpu.state.screen_centering_y;
       break;
     default:
@@ -212,8 +222,9 @@ static noinline void get_gpu_info(uint32_t data)
   }
 }
 
-// double, for overdraw guard
-#define VRAM_SIZE ((1024 * 512 * 2 * 2) + 4096)
+#ifndef max
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#endif
 
 //  Minimum 16-byte VRAM alignment needed by gpu_unai's pixel-skipping
 //  renderer/downscaler it uses in high res modes:
@@ -225,18 +236,31 @@ static noinline void get_gpu_info(uint32_t data)
        #define VRAM_ALIGN 16
 #endif
 
+// double, for overdraw guard + at least 1 page before
+#define VRAM_SIZE ((1024 * 512 * 2 * 2) + max(VRAM_ALIGN, 4096))
+
 // vram ptr received from mmap/malloc/alloc (will deallocate using this)
 static uint16_t *vram_ptr_orig = NULL;
 
-#ifdef GPULIB_USE_MMAP
+#ifndef GPULIB_USE_MMAP
+# ifdef __linux__
+#  define GPULIB_USE_MMAP 1
+# else
+#  define GPULIB_USE_MMAP 0
+# endif
+#endif
 static int map_vram(void)
 {
-  gpu.vram = vram_ptr_orig = gpu.mmap(VRAM_SIZE + (VRAM_ALIGN-1));
-  if (gpu.vram != NULL) {
-       // 4kb guard in front
+#if GPULIB_USE_MMAP
+  gpu.vram = vram_ptr_orig = gpu.mmap(VRAM_SIZE);
+#else
+  gpu.vram = vram_ptr_orig = calloc(VRAM_SIZE, 1);
+#endif
+  if (gpu.vram != NULL && gpu.vram != (void *)(intptr_t)-1) {
+    // 4kb guard in front
     gpu.vram += (4096 / 2);
-       // Align
-       gpu.vram = (uint16_t*)(((uintptr_t)gpu.vram + (VRAM_ALIGN-1)) & ~(VRAM_ALIGN-1));
+    // Align
+    gpu.vram = (uint16_t*)(((uintptr_t)gpu.vram + (VRAM_ALIGN-1)) & ~(VRAM_ALIGN-1));
     return 0;
   }
   else {
@@ -244,54 +268,9 @@ static int map_vram(void)
     return -1;
   }
 }
-#else
-static int map_vram(void)
-{
-  gpu.vram = vram_ptr_orig = (uint16_t*)calloc(VRAM_SIZE + (VRAM_ALIGN-1), 1);
-  if (gpu.vram != NULL) {
-       // 4kb guard in front
-    gpu.vram += (4096 / 2);
-       // Align
-       gpu.vram = (uint16_t*)(((uintptr_t)gpu.vram + (VRAM_ALIGN-1)) & ~(VRAM_ALIGN-1));
-    return 0;
-  } else {
-    fprintf(stderr, "could not allocate vram, expect crashes\n");
-    return -1;
-  }
-}
-
-static int allocate_vram(void)
-{
-  gpu.vram = vram_ptr_orig = (uint16_t*)calloc(VRAM_SIZE + (VRAM_ALIGN-1), 1);
-  if (gpu.vram != NULL) {
-       // 4kb guard in front
-    gpu.vram += (4096 / 2);
-       // Align
-       gpu.vram = (uint16_t*)(((uintptr_t)gpu.vram + (VRAM_ALIGN-1)) & ~(VRAM_ALIGN-1));
-    return 0;
-  } else {
-    fprintf(stderr, "could not allocate vram, expect crashes\n");
-    return -1;
-  }
-}
-#endif
 
 long GPUinit(void)
 {
-#ifndef GPULIB_USE_MMAP
-  if (gpu.vram == NULL) {
-    if (allocate_vram() != 0) {
-      printf("ERROR: could not allocate VRAM, exiting..\n");
-         exit(1);
-       }
-  }
-#endif
-
-  //extern uint32_t hSyncCount;         // in psxcounters.cpp
-  //extern uint32_t frame_counter;      // in psxcounters.cpp
-  //gpu.state.hcnt = &hSyncCount;
-  //gpu.state.frame_count = &frame_counter;
-
   int ret;
   ret  = vout_init();
   ret |= renderer_init();
@@ -319,7 +298,7 @@ long GPUshutdown(void)
   ret = vout_finish();
 
   if (vram_ptr_orig != NULL) {
-#ifdef GPULIB_USE_MMAP
+#if GPULIB_USE_MMAP
     gpu.munmap(vram_ptr_orig, VRAM_SIZE);
 #else
     free(vram_ptr_orig);
@@ -333,6 +312,7 @@ long GPUshutdown(void)
 void GPUwriteStatus(uint32_t data)
 {
   uint32_t cmd = data >> 24;
+  int src_x, src_y;
 
   if (cmd < ARRAY_SIZE(gpu.regs)) {
     if (cmd > 1 && cmd != 5 && gpu.regs[cmd] == data)
@@ -362,14 +342,17 @@ void GPUwriteStatus(uint32_t data)
       gpu.status |= PSX_GPU_STATUS_DMA(data & 3);
       break;
     case 0x05:
-      gpu.screen.src_x = data & 0x3ff;
-      gpu.screen.src_y = (data >> 10) & 0x1ff;
-      renderer_notify_scanout_x_change(gpu.screen.src_x, gpu.screen.hres);
-      if (gpu.frameskip.set) {
-        decide_frameskip_allow(gpu.ex_regs[3]);
-        if (gpu.frameskip.last_flip_frame != *gpu.state.frame_count) {
-          decide_frameskip();
-          gpu.frameskip.last_flip_frame = *gpu.state.frame_count;
+      src_x = data & 0x3ff; src_y = (data >> 10) & 0x1ff;
+      if (src_x != gpu.screen.src_x || src_y != gpu.screen.src_y) {
+        gpu.screen.src_x = src_x;
+        gpu.screen.src_y = src_y;
+        renderer_notify_scanout_change(src_x, src_y);
+        if (gpu.frameskip.set) {
+          decide_frameskip_allow(gpu.ex_regs[3]);
+          if (gpu.frameskip.last_flip_frame != *gpu.state.frame_count) {
+            decide_frameskip();
+            gpu.frameskip.last_flip_frame = *gpu.state.frame_count;
+          }
         }
       }
       break;
@@ -517,15 +500,21 @@ static void start_vram_transfer(uint32_t pos_word, uint32_t size_word, int is_re
 
   log_io("start_vram_transfer %c (%d, %d) %dx%d\n", is_read ? 'r' : 'w',
     gpu.dma.x, gpu.dma.y, gpu.dma.w, gpu.dma.h);
+  if (gpu.gpu_state_change)
+    gpu.gpu_state_change(PGS_VRAM_TRANSFER_START);
 }
 
 static void finish_vram_transfer(int is_read)
 {
   if (is_read)
     gpu.status &= ~PSX_GPU_STATUS_IMG;
-  else
+  else {
+    gpu.state.fb_dirty = 1;
     renderer_update_caches(gpu.dma_start.x, gpu.dma_start.y,
                            gpu.dma_start.w, gpu.dma_start.h, 0);
+  }
+  if (gpu.gpu_state_change)
+    gpu.gpu_state_change(PGS_VRAM_TRANSFER_END);
 }
 
 static void do_vram_copy(const uint32_t *params)
@@ -674,6 +663,7 @@ static noinline int do_cmd_buffer(uint32_t *data, int count)
         break;
       }
       do_vram_copy(data + pos + 1);
+      vram_dirty = 1;
       pos += 4;
       continue;
     }
@@ -703,12 +693,16 @@ static noinline int do_cmd_buffer(uint32_t *data, int count)
   return count - pos;
 }
 
-static void flush_cmd_buffer(void)
+static noinline void flush_cmd_buffer(void)
 {
   int left = do_cmd_buffer(gpu.cmd_buffer, gpu.cmd_len);
   if (left > 0)
     memmove(gpu.cmd_buffer, gpu.cmd_buffer + gpu.cmd_len - left, left * 4);
-  gpu.cmd_len = left;
+  if (left != gpu.cmd_len) {
+    if (!gpu.dma.h && gpu.gpu_state_change)
+      gpu.gpu_state_change(PGS_PRIMITIVE_START);
+    gpu.cmd_len = left;
+  }
 }
 
 void GPUwriteDataMem(uint32_t *mem, int count)
@@ -892,7 +886,7 @@ long GPUfreeze(uint32_t type, struct GPUFreeze *freeze)
         GPUwriteStatus((i << 24) | (gpu.regs[i] ^ 1));
       }
       renderer_sync_ecmds(gpu.ex_regs);
-      renderer_update_caches(0, 0, 1024, 512, 1);
+      renderer_update_caches(0, 0, 1024, 512, 0);
       break;
   }
 
@@ -961,7 +955,13 @@ void GPUvBlank(int is_vblank, int lcf)
   }
 }
 
-#include "../../frontend/plugin_lib.h"
+void GPUgetScreenInfo(int *y, int *base_hres)
+{
+  *y = gpu.screen.y;
+  *base_hres = gpu.screen.vres;
+  if (gpu.status & PSX_GPU_STATUS_DHEIGHT)
+    *base_hres >>= 1;
+}
 
 void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
 {
@@ -975,6 +975,7 @@ void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
   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;
+  gpu.state.screen_centering_type_default = cbs->screen_centering_type_default;
   if (gpu.state.screen_centering_type != cbs->screen_centering_type
       || gpu.state.screen_centering_x != cbs->screen_centering_x
       || gpu.state.screen_centering_y != cbs->screen_centering_y) {
@@ -987,6 +988,7 @@ void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
 
   gpu.mmap = cbs->mmap;
   gpu.munmap = cbs->munmap;
+  gpu.gpu_state_change = cbs->gpu_state_change;
 
   // delayed vram mmap
   if (gpu.vram == NULL)