aboutsummaryrefslogtreecommitdiff
path: root/plugins/gpulib
diff options
context:
space:
mode:
authorJustin Weiss2020-10-28 21:30:22 -0700
committerJustin Weiss2020-10-28 21:30:22 -0700
commit847f57a01f6d17d44b6c8eca4ad93527b739b93d (patch)
treed55301da6739e7d3248fd52396bf467348c4770a /plugins/gpulib
parent6ff2f6b3e7e69fbb38fd8f8ffd5526d1e838cd1d (diff)
downloadpcsx_rearmed-847f57a01f6d17d44b6c8eca4ad93527b739b93d.tar.gz
pcsx_rearmed-847f57a01f6d17d44b6c8eca4ad93527b739b93d.tar.bz2
pcsx_rearmed-847f57a01f6d17d44b6c8eca4ad93527b739b93d.zip
Fix unnecessary threaded rendering frame drops
When DMA requests force a background queue flush, the update lace handler can no longer know there was a pending frame. If this happens often enough, it can delay the next frame indefinitely. Whenever the background queue is emptied, the next update_lace needs to force a render.
Diffstat (limited to 'plugins/gpulib')
-rw-r--r--plugins/gpulib/gpulib_thread_if.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/plugins/gpulib/gpulib_thread_if.c b/plugins/gpulib/gpulib_thread_if.c
index c95f529..1583783 100644
--- a/plugins/gpulib/gpulib_thread_if.c
+++ b/plugins/gpulib/gpulib_thread_if.c
@@ -60,6 +60,7 @@ static video_thread_queue queues[2];
static int thread_rendering;
static BOOL hold_cmds;
static BOOL needs_display;
+static BOOL flushed;
extern const unsigned char cmd_lengths[];
@@ -132,7 +133,6 @@ static void cmd_queue_swap() {
tmp = thread.queue;
thread.queue = thread.bg_queue;
thread.bg_queue = tmp;
- needs_display = TRUE;
pthread_cond_signal(&thread.cond_msg_avail);
}
pthread_mutex_unlock(&thread.queue_lock);
@@ -168,6 +168,13 @@ void renderer_sync(void) {
return;
}
+ if (thread.bg_queue->used) {
+ /* When we flush the background queue, the vblank handler can't
+ * know that we had a frame pending, and we delay rendering too
+ * long. Force it. */
+ flushed = TRUE;
+ }
+
/* Flush both queues. This is necessary because gpulib could be
* trying to process a DMA write that a command in the queue should
* run beforehand. For example, Xenogears sprites write a black
@@ -433,7 +440,7 @@ void renderer_notify_update_lace(int updated) {
}
pthread_mutex_lock(&thread.queue_lock);
- if (thread.bg_queue->used) {
+ if (thread.bg_queue->used || flushed) {
/* We have commands for a future frame to run. Force a wait until
* the current frame is finished, and start processing the next
* frame after it's drawn (see the `updated` clause above). */
@@ -444,6 +451,7 @@ void renderer_notify_update_lace(int updated) {
/* We are no longer holding commands back, so the next frame may
* get mixed into the following frame. This is usually fine, but can
* result in frameskip-like effects for 60fps games. */
+ flushed = FALSE;
hold_cmds = FALSE;
needs_display = TRUE;
gpu.state.fb_dirty = TRUE;