aboutsummaryrefslogtreecommitdiff
path: root/plugins/gpu_neon
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gpu_neon')
-rw-r--r--plugins/gpu_neon/gpu.c42
-rw-r--r--plugins/gpu_neon/gpu.h3
2 files changed, 30 insertions, 15 deletions
diff --git a/plugins/gpu_neon/gpu.c b/plugins/gpu_neon/gpu.c
index 990fc52..3f21fa9 100644
--- a/plugins/gpu_neon/gpu.c
+++ b/plugins/gpu_neon/gpu.c
@@ -59,14 +59,32 @@ static noinline void update_height(void)
static noinline void decide_frameskip(void)
{
- gpu.frameskip.frame_ready = !gpu.frameskip.active;
+ if (gpu.frameskip.active)
+ gpu.frameskip.cnt++;
+ else {
+ gpu.frameskip.cnt = 0;
+ gpu.frameskip.frame_ready = 1;
+ }
- if (!gpu.frameskip.active && (*gpu.frameskip.advice || gpu.frameskip.set == 1))
+ if (!gpu.frameskip.active && *gpu.frameskip.advice)
+ gpu.frameskip.active = 1;
+ else if (gpu.frameskip.set > 0 && gpu.frameskip.cnt < gpu.frameskip.set)
gpu.frameskip.active = 1;
else
gpu.frameskip.active = 0;
}
+static noinline void decide_frameskip_allow(uint32_t cmd_e3)
+{
+ // no frameskip if it decides to draw to display area,
+ // but not for interlace since it'll most likely always do that
+ uint32_t x = cmd_e3 & 0x3ff;
+ uint32_t y = (cmd_e3 >> 10) & 0x3ff;
+ gpu.frameskip.allow = gpu.status.interlace ||
+ (uint32_t)(x - gpu.screen.x) >= (uint32_t)gpu.screen.w ||
+ (uint32_t)(y - gpu.screen.y) >= (uint32_t)gpu.screen.h;
+}
+
static noinline void get_gpu_info(uint32_t data)
{
switch (data & 0x0f) {
@@ -132,9 +150,12 @@ void GPUwriteStatus(uint32_t data)
case 0x05:
gpu.screen.x = data & 0x3ff;
gpu.screen.y = (data >> 10) & 0x3ff;
- if (gpu.frameskip.set && gpu.frameskip.last_flip_frame != *gpu.state.frame_count) {
- decide_frameskip();
- gpu.frameskip.last_flip_frame = *gpu.state.frame_count;
+ 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;
case 0x06:
@@ -294,15 +315,8 @@ static int check_cmd(uint32_t *data, int count)
gpu.ex_regs[1] |= list[5] & 0x1ff;
}
else if (cmd == 0xe3)
- {
- // no frameskip if it decides to draw to display area,
- // but not for interlace since it'll most likely always do that
- uint32_t x = list[0] & 0x3ff;
- uint32_t y = (list[0] >> 10) & 0x3ff;
- gpu.frameskip.allow = gpu.status.interlace ||
- (uint32_t)(x - gpu.screen.x) >= (uint32_t)gpu.screen.w ||
- (uint32_t)(y - gpu.screen.y) >= (uint32_t)gpu.screen.h;
- }
+ decide_frameskip_allow(list[0]);
+
if (2 <= cmd && cmd < 0xc0)
vram_dirty = 1;
else if ((cmd & 0xf8) == 0xe0)
diff --git a/plugins/gpu_neon/gpu.h b/plugins/gpu_neon/gpu.h
index 8ad71c2..3b3e1de 100644
--- a/plugins/gpu_neon/gpu.h
+++ b/plugins/gpu_neon/gpu.h
@@ -74,7 +74,8 @@ struct psx_gpu {
} last_list;
} state;
struct {
- int32_t set:3; /* -1 auto, 0 off, 1 fixed */
+ int32_t set:3; /* -1 auto, 0 off, 1-3 fixed */
+ int32_t cnt:3; /* amount skipped in a row */
uint32_t active:1;
uint32_t allow:1;
uint32_t frame_ready:1;