Merge pull request #3120 from unknownbrackets/gpu-thread

Fix some more GPU thread sync issues
This commit is contained in:
Henrik Rydgård 2013-08-11 01:29:14 -07:00
commit c709315aff
8 changed files with 48 additions and 22 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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();
}

View File

@ -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;

View File

@ -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)

View File

@ -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;