diff --git a/Common/Thread/ThreadManager.cpp b/Common/Thread/ThreadManager.cpp index 4dad152ed3..514632f1f7 100644 --- a/Common/Thread/ThreadManager.cpp +++ b/Common/Thread/ThreadManager.cpp @@ -258,13 +258,13 @@ void ThreadManager::EnqueueTask(Task *task) { chosenThread->cond.notify_one(); } -void ThreadManager::EnqueueTaskOnThread(int threadNum, Task *task) { +void ThreadManager::EnqueueTaskOnThread(int threadNum, Task *task, bool enforceSequence) { _assert_msg_(threadNum >= 0 && threadNum < (int)global_->threads_.size(), "Bad threadnum or not initialized"); ThreadContext *thread = global_->threads_[threadNum]; // Try first atomically, as highest priority. Task *expected = nullptr; - bool queued = thread->private_single.compare_exchange_weak(expected, task); + bool queued = !enforceSequence && thread->private_single.compare_exchange_weak(expected, task); // Whether we got that or will have to wait, increase the queue counter. thread->queue_size++; diff --git a/Common/Thread/ThreadManager.h b/Common/Thread/ThreadManager.h index f6ddd842b2..bb7b5fd44e 100644 --- a/Common/Thread/ThreadManager.h +++ b/Common/Thread/ThreadManager.h @@ -46,7 +46,8 @@ public: // just ignore it and let the OS handle it. void Init(int numCores, int numLogicalCoresPerCpu); void EnqueueTask(Task *task); - void EnqueueTaskOnThread(int threadNum, Task *task); + // Use enforceSequence if this must run after all previously queued tasks. + void EnqueueTaskOnThread(int threadNum, Task *task, bool enforceSequence = false); void Teardown(); bool IsInitialized() const; diff --git a/GPU/Software/BinManager.cpp b/GPU/Software/BinManager.cpp index 9684f7fb3b..714b8b1678 100644 --- a/GPU/Software/BinManager.cpp +++ b/GPU/Software/BinManager.cpp @@ -257,7 +257,7 @@ void BinManager::Drain() { waitable_->Fill(); DrawBinItemTask *task = new DrawBinItemTask(waitable_, item, range, states_[item.stateIndex]); - g_threadManager.EnqueueTaskOnThread(i, task); + g_threadManager.EnqueueTaskOnThread(i, task, true); } } }