mirror of
https://github.com/libretro/ppsspp.git
synced 2025-01-20 23:54:48 +00:00
Merge pull request #3120 from unknownbrackets/gpu-thread
Fix some more GPU thread sync issues
This commit is contained in:
commit
c709315aff
@ -52,7 +52,8 @@ static u32 ComputeHash(u32 start, u32 size)
|
||||
|
||||
void SymbolMap::SortSymbols()
|
||||
{
|
||||
std::sort(entries.begin(), entries.end());
|
||||
lock_guard guard(lock_);
|
||||
std::sort(entries.begin(), entries.end());
|
||||
}
|
||||
|
||||
void SymbolMap::AnalyzeBackwards()
|
||||
@ -104,6 +105,7 @@ void SymbolMap::AnalyzeBackwards()
|
||||
|
||||
void SymbolMap::ResetSymbolMap()
|
||||
{
|
||||
lock_guard guard(lock_);
|
||||
#ifdef BWLINKS
|
||||
for (int i=0; i<numEntries; i++)
|
||||
{
|
||||
@ -118,6 +120,7 @@ void SymbolMap::ResetSymbolMap()
|
||||
|
||||
void SymbolMap::AddSymbol(const char *symbolname, unsigned int vaddress, size_t size, SymbolType st)
|
||||
{
|
||||
lock_guard guard(lock_);
|
||||
MapEntry e;
|
||||
strncpy(e.name, symbolname, 127);
|
||||
e.name[127] = '\0';
|
||||
@ -134,6 +137,7 @@ void SymbolMap::AddSymbol(const char *symbolname, unsigned int vaddress, size_t
|
||||
|
||||
bool SymbolMap::LoadSymbolMap(const char *filename)
|
||||
{
|
||||
lock_guard guard(lock_);
|
||||
SymbolMap::ResetSymbolMap();
|
||||
FILE *f = fopen(filename,"r");
|
||||
if (!f)
|
||||
@ -207,6 +211,7 @@ bool SymbolMap::LoadSymbolMap(const char *filename)
|
||||
|
||||
void SymbolMap::SaveSymbolMap(const char *filename) const
|
||||
{
|
||||
lock_guard guard(lock_);
|
||||
FILE *f = fopen(filename,"w");
|
||||
if (!f)
|
||||
return;
|
||||
@ -221,6 +226,7 @@ void SymbolMap::SaveSymbolMap(const char *filename) const
|
||||
|
||||
bool SymbolMap::LoadNocashSym(const char *filename)
|
||||
{
|
||||
lock_guard guard(lock_);
|
||||
FILE *f = fopen(filename,"r");
|
||||
if (!f)
|
||||
return false;
|
||||
@ -389,6 +395,8 @@ void SymbolMap::FillSymbolListBox(HWND listbox,SymbolType symmask) const
|
||||
}
|
||||
}
|
||||
|
||||
lock_guard guard(lock_);
|
||||
|
||||
SendMessage(listbox, WM_SETREDRAW, FALSE, 0);
|
||||
SendMessage(listbox, LB_INITSTORAGE, (WPARAM)entries.size(), (LPARAM)entries.size() * 30);
|
||||
for (auto it = entries.begin(), end = entries.end(); it != end; ++it)
|
||||
@ -427,11 +435,13 @@ void SymbolMap::FillSymbolComboBox(HWND listbox,SymbolType symmask) const
|
||||
//ListBox_AddString(listbox,"(0x80002000)");
|
||||
//ListBox_SetItemData(listbox,1,0x80002000);
|
||||
|
||||
lock_guard guard(lock_);
|
||||
|
||||
SendMessage(listbox, WM_SETREDRAW, FALSE, 0);
|
||||
SendMessage(listbox, CB_INITSTORAGE, (WPARAM)entries.size(), (LPARAM)entries.size() * 30);
|
||||
for (auto it = entries.begin(), end = entries.end(); it != end; ++it)
|
||||
for (size_t i = 0, end = entries.size(); i < end; ++i)
|
||||
{
|
||||
const MapEntry &entry = *it;
|
||||
const MapEntry &entry = entries[i];
|
||||
if (entry.type & symmask)
|
||||
{
|
||||
char temp[256];
|
||||
@ -449,6 +459,8 @@ void SymbolMap::FillSymbolComboBox(HWND listbox,SymbolType symmask) const
|
||||
void SymbolMap::FillListBoxBLinks(HWND listbox, int num) const
|
||||
{
|
||||
ListBox_ResetContent(listbox);
|
||||
|
||||
lock_guard guard(lock_);
|
||||
|
||||
int style = GetWindowLong(listbox,GWL_STYLE);
|
||||
|
||||
|
@ -17,7 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Globals.h"
|
||||
#include "Globals.h"
|
||||
#include "native/base/mutex.h"
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
@ -106,6 +107,7 @@ private:
|
||||
std::set<MapEntryUniqueInfo> uniqueEntries;
|
||||
std::vector<MapEntry> entries;
|
||||
std::map<u32, u32> entryRanges;
|
||||
mutable recursive_mutex lock_;
|
||||
};
|
||||
|
||||
extern SymbolMap symbolMap;
|
||||
|
@ -215,6 +215,16 @@ bool __GeTriggerInterrupt(int listid, u32 pc, u64 atTicks)
|
||||
return true;
|
||||
}
|
||||
|
||||
void __GeWaitCurrentThread(WaitType type, SceUID waitId, const char *reason)
|
||||
{
|
||||
__KernelWaitCurThread(type, waitId, 0, 0, false, reason);
|
||||
}
|
||||
|
||||
void __GeTriggerWait(WaitType type, SceUID waitId, const char *reason, bool noSwitch)
|
||||
{
|
||||
__KernelTriggerWait(type, waitId, 0, reason, noSwitch);
|
||||
}
|
||||
|
||||
bool __GeHasPendingInterrupt()
|
||||
{
|
||||
return !ge_pending_cb.empty();
|
||||
|
@ -43,6 +43,8 @@ void __GeDoState(PointerWrap &p);
|
||||
void __GeShutdown();
|
||||
bool __GeTriggerSync(WaitType waitType, int id, u64 atTicks);
|
||||
bool __GeTriggerInterrupt(int listid, u32 pc, u64 atTicks);
|
||||
void __GeWaitCurrentThread(WaitType type, SceUID waitId, const char *reason);
|
||||
void __GeTriggerWait(WaitType type, SceUID waitId, const char *reason, bool noSwitch = false);
|
||||
bool __GeHasPendingInterrupt();
|
||||
|
||||
|
||||
|
@ -112,7 +112,7 @@ bool CPU_HasPendingAction() {
|
||||
void CPU_WaitStatus(bool (*pred)()) {
|
||||
cpuThreadLock.lock();
|
||||
while (!pred())
|
||||
cpuThreadCond.wait(cpuThreadLock);
|
||||
cpuThreadCond.wait_for(cpuThreadLock, 16);
|
||||
cpuThreadLock.unlock();
|
||||
}
|
||||
|
||||
|
@ -304,6 +304,11 @@ void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat fo
|
||||
}
|
||||
|
||||
bool GLES_GPU::FramebufferDirty() {
|
||||
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
|
||||
ScheduleEvent(GPU_EVENT_PROCESS_QUEUE);
|
||||
// Allow it to process fully before deciding if it's dirty.
|
||||
SyncThread();
|
||||
|
||||
VirtualFramebuffer *vfb = framebufferManager_.GetDisplayFBO();
|
||||
if (vfb)
|
||||
return vfb->dirtyAfterDisplay;
|
||||
|
@ -10,9 +10,7 @@
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "Core/HLE/sceKernelInterrupt.h"
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
#include "Core/HLE/sceKernelThread.h"
|
||||
#include "Core/HLE/sceGe.h"
|
||||
|
||||
GPUCommon::GPUCommon() :
|
||||
@ -48,6 +46,8 @@ void GPUCommon::PopDLQueue() {
|
||||
}
|
||||
|
||||
u32 GPUCommon::DrawSync(int mode) {
|
||||
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
|
||||
ScheduleEvent(GPU_EVENT_PROCESS_QUEUE);
|
||||
// Sync first, because the CPU is usually faster than the emulated GPU.
|
||||
SyncThread();
|
||||
|
||||
@ -58,7 +58,7 @@ u32 GPUCommon::DrawSync(int mode) {
|
||||
if (mode == 0) {
|
||||
// TODO: What if dispatch / interrupts disabled?
|
||||
if (drawCompleteTicks > CoreTiming::GetTicks()) {
|
||||
__KernelWaitCurThread(WAITTYPE_GEDRAWSYNC, 1, 0, 0, false, "GeDrawSync");
|
||||
__GeWaitCurrentThread(WAITTYPE_GEDRAWSYNC, 1, "GeDrawSync");
|
||||
} else {
|
||||
for (int i = 0; i < DisplayListMaxCount; ++i) {
|
||||
if (dls[i].state == PSP_GE_DL_STATE_COMPLETED) {
|
||||
@ -95,6 +95,8 @@ void GPUCommon::CheckDrawSync() {
|
||||
}
|
||||
|
||||
int GPUCommon::ListSync(int listid, int mode) {
|
||||
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
|
||||
ScheduleEvent(GPU_EVENT_PROCESS_QUEUE);
|
||||
// Sync first, because the CPU is usually faster than the emulated GPU.
|
||||
SyncThread();
|
||||
|
||||
@ -130,8 +132,7 @@ int GPUCommon::ListSync(int listid, int mode) {
|
||||
}
|
||||
|
||||
if (dl.waitTicks > CoreTiming::GetTicks()) {
|
||||
guard.unlock();
|
||||
__KernelWaitCurThread(WAITTYPE_GELISTSYNC, listid, 0, 0, false, "GeListSync");
|
||||
__GeWaitCurrentThread(WAITTYPE_GELISTSYNC, listid, "GeListSync");
|
||||
}
|
||||
return PSP_GE_LIST_COMPLETED;
|
||||
}
|
||||
@ -244,8 +245,7 @@ u32 GPUCommon::DequeueList(int listid) {
|
||||
dlQueue.remove(listid);
|
||||
|
||||
dls[listid].waitTicks = 0;
|
||||
guard.unlock();
|
||||
__KernelTriggerWait(WAITTYPE_GELISTSYNC, listid, 0, "GeListSync");
|
||||
__GeTriggerWait(WAITTYPE_GELISTSYNC, listid, "GeListSync");
|
||||
|
||||
CheckDrawSync();
|
||||
|
||||
@ -599,7 +599,6 @@ void GPUCommon::ProcessDLQueueInternal() {
|
||||
|
||||
easy_guard guard(listLock);
|
||||
currentList = NULL;
|
||||
guard.unlock();
|
||||
|
||||
drawCompleteTicks = startingTicks + cyclesExecuted;
|
||||
busyTicks = std::max(busyTicks, drawCompleteTicks);
|
||||
@ -861,7 +860,7 @@ void GPUCommon::InterruptEnd(int listid) {
|
||||
// TODO: Unless the signal handler could change it?
|
||||
if (dl.state == PSP_GE_DL_STATE_COMPLETED || dl.state == PSP_GE_DL_STATE_NONE) {
|
||||
dl.waitTicks = 0;
|
||||
__KernelTriggerWait(WAITTYPE_GELISTSYNC, listid, 0, "GeListSync", true);
|
||||
__GeTriggerWait(WAITTYPE_GELISTSYNC, listid, "GeListSync", true);
|
||||
}
|
||||
|
||||
if (dl.signal == PSP_GE_SIGNAL_HANDLER_PAUSE)
|
||||
|
@ -28,7 +28,10 @@ public:
|
||||
virtual int ListSync(int listid, int mode);
|
||||
virtual u32 DrawSync(int mode);
|
||||
virtual void DoState(PointerWrap &p);
|
||||
virtual bool FramebufferDirty() { return true; }
|
||||
virtual bool FramebufferDirty() {
|
||||
SyncThread();
|
||||
return true;
|
||||
}
|
||||
virtual u32 Continue();
|
||||
virtual u32 Break(int mode);
|
||||
virtual void ReapplyGfxState();
|
||||
@ -65,13 +68,6 @@ protected:
|
||||
DisplayListQueue dlQueue;
|
||||
recursive_mutex listLock;
|
||||
|
||||
std::deque<GPUEvent> events;
|
||||
recursive_mutex eventsLock;
|
||||
recursive_mutex eventsWaitLock;
|
||||
recursive_mutex eventsDrainLock;
|
||||
condition_variable eventsWait;
|
||||
condition_variable eventsDrain;
|
||||
|
||||
bool interruptRunning;
|
||||
GPUState gpuState;
|
||||
bool isbreak;
|
||||
|
Loading…
x
Reference in New Issue
Block a user