mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-04 21:39:54 +00:00
Improved ThreadBase.
Improved Vertex Shader Decompiler.
This commit is contained in:
parent
d07b5f0dc8
commit
4b8d6b6919
@ -1,97 +1,149 @@
|
||||
#include "stdafx.h"
|
||||
#include "Thread.h"
|
||||
|
||||
ThreadBase* GetCurrentNamedThread()
|
||||
{
|
||||
ThreadExec* thr = (ThreadExec*)::wxThread::This();
|
||||
return thr ? thr->m_parent : nullptr;
|
||||
}
|
||||
static DWORD g_tls_this_thread = 0xFFFFFFFF;
|
||||
|
||||
ThreadBase::ThreadBase(bool detached, const std::string& name)
|
||||
: m_detached(detached)
|
||||
, m_name(name)
|
||||
, m_executor(nullptr)
|
||||
struct __init_tls
|
||||
{
|
||||
}
|
||||
//NamedThreadBase m_main_thr;
|
||||
|
||||
void ThreadBase::Start()
|
||||
{
|
||||
if(m_executor) return;
|
||||
|
||||
m_executor = new ThreadExec(m_detached, this);
|
||||
}
|
||||
|
||||
void ThreadBase::Resume()
|
||||
{
|
||||
if(m_executor)
|
||||
__init_tls()
|
||||
{
|
||||
m_executor->Resume();
|
||||
g_tls_this_thread = ::TlsAlloc();
|
||||
//m_main_thr.SetThreadName("Main Thread");
|
||||
//::TlsSetValue(g_tls_this_thread, &m_main_thr);
|
||||
::TlsSetValue(g_tls_this_thread, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadBase::Pause()
|
||||
{
|
||||
if(m_executor)
|
||||
~__init_tls()
|
||||
{
|
||||
m_executor->Pause();
|
||||
::TlsFree(g_tls_this_thread);
|
||||
}
|
||||
}
|
||||
} _init_tls;
|
||||
|
||||
void ThreadBase::Stop(bool wait)
|
||||
NamedThreadBase* GetCurrentNamedThread()
|
||||
{
|
||||
if(!m_executor) return;
|
||||
ThreadExec* exec = m_executor;
|
||||
m_executor = nullptr;
|
||||
|
||||
if(!m_detached)
|
||||
{
|
||||
if(wait)
|
||||
{
|
||||
exec->Wait();
|
||||
}
|
||||
|
||||
exec->Stop(false);
|
||||
delete exec;
|
||||
}
|
||||
else
|
||||
{
|
||||
exec->Stop(wait);
|
||||
}
|
||||
return (NamedThreadBase*)::TlsGetValue(g_tls_this_thread);
|
||||
}
|
||||
|
||||
bool ThreadBase::Wait() const
|
||||
{
|
||||
return m_executor != nullptr && m_executor->Wait() != (wxThread::ExitCode)-1;
|
||||
}
|
||||
|
||||
bool ThreadBase::IsRunning() const
|
||||
{
|
||||
return m_executor != nullptr && m_executor->IsRunning();
|
||||
}
|
||||
|
||||
bool ThreadBase::IsPaused() const
|
||||
{
|
||||
return m_executor != nullptr && m_executor->IsPaused();
|
||||
}
|
||||
|
||||
bool ThreadBase::IsAlive() const
|
||||
{
|
||||
return m_executor != nullptr;
|
||||
}
|
||||
|
||||
bool ThreadBase::TestDestroy() const
|
||||
{
|
||||
if(!m_executor || !m_executor->m_parent) return true;
|
||||
|
||||
return m_executor->TestDestroy();
|
||||
}
|
||||
|
||||
std::string ThreadBase::GetThreadName() const
|
||||
std::string NamedThreadBase::GetThreadName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void ThreadBase::SetThreadName(const std::string& name)
|
||||
void NamedThreadBase::SetThreadName(const std::string& name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
ThreadBase::ThreadBase(const std::string& name)
|
||||
: NamedThreadBase(name)
|
||||
, m_executor(nullptr)
|
||||
, m_destroy(false)
|
||||
, m_alive(false)
|
||||
{
|
||||
}
|
||||
|
||||
ThreadBase::~ThreadBase()
|
||||
{
|
||||
if(IsAlive())
|
||||
Stop(false);
|
||||
}
|
||||
|
||||
void ThreadBase::Start()
|
||||
{
|
||||
if(m_executor) Stop();
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_main_mutex);
|
||||
|
||||
m_destroy = false;
|
||||
m_alive = true;
|
||||
|
||||
m_executor = new std::thread(
|
||||
[this]()
|
||||
{
|
||||
::TlsSetValue(g_tls_this_thread, this);
|
||||
|
||||
Task();
|
||||
|
||||
m_alive = false;
|
||||
});
|
||||
}
|
||||
|
||||
void ThreadBase::Stop(bool wait)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_main_mutex);
|
||||
|
||||
m_destroy = true;
|
||||
|
||||
if(!m_executor)
|
||||
return;
|
||||
|
||||
if(wait && m_executor->joinable() && m_alive)
|
||||
{
|
||||
m_executor->join();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_executor->detach();
|
||||
}
|
||||
|
||||
delete m_executor;
|
||||
m_executor = nullptr;
|
||||
}
|
||||
|
||||
bool ThreadBase::Join() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_main_mutex);
|
||||
if(m_executor->joinable() && m_alive && m_executor != nullptr)
|
||||
{
|
||||
m_executor->join();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ThreadBase::IsAlive() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_main_mutex);
|
||||
return m_alive;
|
||||
}
|
||||
|
||||
bool ThreadBase::TestDestroy() const
|
||||
{
|
||||
return m_destroy;
|
||||
}
|
||||
|
||||
thread::thread(const std::string& name, std::function<void()> func) : m_name(name)
|
||||
{
|
||||
start(func);
|
||||
}
|
||||
|
||||
thread::thread(const std::string& name) : m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
thread::thread()
|
||||
{
|
||||
}
|
||||
|
||||
void thread::start(std::function<void()> func)
|
||||
{
|
||||
m_thr = std::thread([this, func]() { NamedThreadBase info(m_name); ::TlsSetValue(g_tls_this_thread, &info); func(); });
|
||||
}
|
||||
|
||||
void thread::detach()
|
||||
{
|
||||
m_thr.detach();
|
||||
}
|
||||
|
||||
void thread::join()
|
||||
{
|
||||
m_thr.join();
|
||||
}
|
||||
|
||||
bool thread::joinable() const
|
||||
{
|
||||
return m_thr.joinable();
|
||||
}
|
@ -3,84 +3,68 @@
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
|
||||
class ThreadExec;
|
||||
|
||||
class ThreadBase
|
||||
class NamedThreadBase
|
||||
{
|
||||
protected:
|
||||
std::string m_name;
|
||||
bool m_detached;
|
||||
|
||||
public:
|
||||
std::mutex m_main_mutex;
|
||||
NamedThreadBase(const std::string& name) : m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
ThreadBase(bool detached = true, const std::string& name = "Unknown ThreadBase");
|
||||
NamedThreadBase()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
ThreadExec* m_executor;
|
||||
|
||||
virtual void Task()=0;
|
||||
|
||||
virtual void Start();
|
||||
virtual void Resume();
|
||||
virtual void Pause();
|
||||
virtual void Stop(bool wait = true);
|
||||
|
||||
virtual bool Wait() const;
|
||||
virtual bool IsRunning() const;
|
||||
virtual bool IsPaused() const;
|
||||
virtual bool IsAlive() const;
|
||||
virtual bool TestDestroy() const;
|
||||
virtual std::string GetThreadName() const;
|
||||
virtual void SetThreadName(const std::string& name);
|
||||
};
|
||||
|
||||
ThreadBase* GetCurrentNamedThread();
|
||||
NamedThreadBase* GetCurrentNamedThread();
|
||||
|
||||
class ThreadExec : public wxThread
|
||||
class ThreadBase : public NamedThreadBase
|
||||
{
|
||||
std::mutex m_wait_for_exit;
|
||||
volatile bool m_alive;
|
||||
protected:
|
||||
std::atomic<bool> m_destroy;
|
||||
std::atomic<bool> m_alive;
|
||||
std::thread* m_executor;
|
||||
|
||||
mutable std::mutex m_main_mutex;
|
||||
|
||||
ThreadBase(const std::string& name);
|
||||
~ThreadBase();
|
||||
|
||||
public:
|
||||
ThreadBase* m_parent;
|
||||
void Start();
|
||||
void Stop(bool wait = true);
|
||||
|
||||
ThreadExec(bool detached, ThreadBase* parent)
|
||||
: wxThread(detached ? wxTHREAD_DETACHED : wxTHREAD_JOINABLE)
|
||||
, m_parent(parent)
|
||||
, m_alive(true)
|
||||
{
|
||||
Create();
|
||||
Run();
|
||||
}
|
||||
bool Join() const;
|
||||
bool IsAlive() const;
|
||||
bool TestDestroy() const;
|
||||
|
||||
void Stop(bool wait = true)
|
||||
{
|
||||
if(!m_alive) return;
|
||||
|
||||
m_parent = nullptr;
|
||||
|
||||
if(wait)
|
||||
{
|
||||
Delete();
|
||||
//std::lock_guard<std::mutex> lock(m_wait_for_exit);
|
||||
}
|
||||
}
|
||||
|
||||
ExitCode Entry()
|
||||
{
|
||||
//std::lock_guard<std::mutex> lock(m_wait_for_exit);
|
||||
m_parent->Task();
|
||||
m_alive = false;
|
||||
if(m_parent) m_parent->m_executor = nullptr;
|
||||
return (ExitCode)0;
|
||||
}
|
||||
virtual void Task() = 0;
|
||||
};
|
||||
|
||||
//ThreadBase* GetCurrentThread();
|
||||
class thread
|
||||
{
|
||||
std::string m_name;
|
||||
std::thread m_thr;
|
||||
|
||||
public:
|
||||
thread(const std::string& name, std::function<void()> func);
|
||||
thread(const std::string& name);
|
||||
thread();
|
||||
|
||||
void start(std::function<void()> func);
|
||||
void detach();
|
||||
void join();
|
||||
bool joinable() const;
|
||||
};
|
||||
|
||||
template<typename T> class MTPacketBuffer
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ CPUThread* GetCurrentCPUThread()
|
||||
}
|
||||
|
||||
CPUThread::CPUThread(CPUThreadType type)
|
||||
: ThreadBase(true, "CPUThread")
|
||||
: ThreadBase("CPUThread")
|
||||
, m_type(type)
|
||||
, m_stack_size(0)
|
||||
, m_stack_addr(0)
|
||||
@ -15,30 +15,24 @@ CPUThread::CPUThread(CPUThreadType type)
|
||||
, m_prio(0)
|
||||
, m_sync_wait(false)
|
||||
, m_wait_thread_id(-1)
|
||||
, m_free_data(false)
|
||||
, m_dec(nullptr)
|
||||
, m_is_step(false)
|
||||
, m_is_branch(false)
|
||||
, m_status(Stopped)
|
||||
{
|
||||
}
|
||||
|
||||
CPUThread::~CPUThread()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void CPUThread::Close()
|
||||
{
|
||||
if(IsAlive())
|
||||
{
|
||||
m_free_data = true;
|
||||
ThreadBase::Stop(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_dec;
|
||||
m_dec = nullptr;
|
||||
}
|
||||
ThreadBase::Stop();
|
||||
DoStop();
|
||||
|
||||
delete m_dec;
|
||||
m_dec = nullptr;
|
||||
}
|
||||
|
||||
void CPUThread::Reset()
|
||||
@ -77,7 +71,7 @@ void CPUThread::SetId(const u32 id)
|
||||
|
||||
void CPUThread::SetName(const std::string& name)
|
||||
{
|
||||
m_name = name;
|
||||
NamedThreadBase::SetThreadName(name);
|
||||
}
|
||||
|
||||
void CPUThread::Wait(bool wait)
|
||||
@ -189,12 +183,10 @@ wxArrayString CPUThread::ErrorToString(const u32 error)
|
||||
|
||||
void CPUThread::Run()
|
||||
{
|
||||
if(IsRunning()) Stop();
|
||||
if(IsPaused())
|
||||
{
|
||||
Resume();
|
||||
return;
|
||||
}
|
||||
if(!IsStopped())
|
||||
Stop();
|
||||
|
||||
Reset();
|
||||
|
||||
#ifndef QT_UI
|
||||
wxGetApp().SendDbgCommand(DID_START_THREAD, this);
|
||||
@ -244,7 +236,7 @@ void CPUThread::Pause()
|
||||
DoPause();
|
||||
Emu.CheckStatus();
|
||||
|
||||
ThreadBase::Stop(false);
|
||||
ThreadBase::Stop();
|
||||
#ifndef QT_UI
|
||||
wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this);
|
||||
#endif
|
||||
@ -259,9 +251,15 @@ void CPUThread::Stop()
|
||||
#endif
|
||||
|
||||
m_status = Stopped;
|
||||
ThreadBase::Stop(false);
|
||||
Reset();
|
||||
DoStop();
|
||||
|
||||
if(CPUThread* thr = GetCurrentCPUThread())
|
||||
{
|
||||
if(thr->GetId() != GetId())
|
||||
ThreadBase::Stop();
|
||||
}
|
||||
else
|
||||
ThreadBase::Stop();
|
||||
|
||||
Emu.CheckStatus();
|
||||
|
||||
#ifndef QT_UI
|
||||
@ -275,7 +273,9 @@ void CPUThread::Exec()
|
||||
#ifndef QT_UI
|
||||
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
|
||||
#endif
|
||||
ThreadBase::Start();
|
||||
|
||||
if(IsRunning())
|
||||
ThreadBase::Start();
|
||||
}
|
||||
|
||||
void CPUThread::ExecOnce()
|
||||
@ -285,7 +285,7 @@ void CPUThread::ExecOnce()
|
||||
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
|
||||
#endif
|
||||
ThreadBase::Start();
|
||||
if(!ThreadBase::Wait()) while(m_is_step) Sleep(1);
|
||||
ThreadBase::Stop();
|
||||
#ifndef QT_UI
|
||||
wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, this);
|
||||
wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this);
|
||||
@ -294,7 +294,7 @@ void CPUThread::ExecOnce()
|
||||
|
||||
void CPUThread::Task()
|
||||
{
|
||||
//ConLog.Write("%s enter", CPUThread::GetFName());
|
||||
ConLog.Write("%s enter", CPUThread::GetFName());
|
||||
|
||||
const Array<u64>& bp = Emu.GetBreakPoints();
|
||||
|
||||
@ -354,15 +354,7 @@ void CPUThread::Task()
|
||||
catch(int exitcode)
|
||||
{
|
||||
ConLog.Success("Exit Code: %d", exitcode);
|
||||
return;
|
||||
}
|
||||
|
||||
//ConLog.Write("%s leave", CPUThread::GetFName());
|
||||
|
||||
if(m_free_data)
|
||||
{
|
||||
delete m_dec;
|
||||
m_dec = nullptr;
|
||||
free(this);
|
||||
}
|
||||
ConLog.Write("%s leave", CPUThread::GetFName());
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ protected:
|
||||
CPUThreadType m_type;
|
||||
bool m_joinable;
|
||||
bool m_joining;
|
||||
bool m_free_data;
|
||||
bool m_is_step;
|
||||
|
||||
u64 m_stack_addr;
|
||||
@ -68,7 +67,7 @@ public:
|
||||
u32 GetExitStatus() const { return m_exit_status; }
|
||||
u64 GetPrio() const { return m_prio; }
|
||||
|
||||
std::string GetName() const { return m_name; }
|
||||
std::string GetName() const { return NamedThreadBase::GetThreadName(); }
|
||||
wxString GetFName() const
|
||||
{
|
||||
return
|
||||
|
@ -64,16 +64,7 @@ void CPUThreadManager::RemoveThread(const u32 id)
|
||||
#ifndef QT_UI
|
||||
wxGetApp().SendDbgCommand(DID_REMOVE_THREAD, thr);
|
||||
#endif
|
||||
if(thr->IsAlive())
|
||||
{
|
||||
//thr->Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
//thr->Close();
|
||||
//delete thr;
|
||||
}
|
||||
|
||||
thr->Close();
|
||||
|
||||
m_threads.RemoveFAt(i);
|
||||
break;
|
||||
|
@ -21,7 +21,7 @@ RawSPUThread::~RawSPUThread()
|
||||
}
|
||||
}
|
||||
|
||||
Close();
|
||||
//Close();
|
||||
}
|
||||
|
||||
bool RawSPUThread::Read8(const u64 addr, u8* value)
|
||||
|
@ -78,7 +78,7 @@ void SPUThread::DoRun()
|
||||
break;
|
||||
}
|
||||
|
||||
Pause();
|
||||
//Pause();
|
||||
//Emu.Pause();
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,8 @@ BEGIN_EVENT_TABLE(DbgConsole, FrameBase)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
DbgConsole::DbgConsole()
|
||||
: FrameBase(NULL, wxID_ANY, "DbgConsole", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxDEFAULT_FRAME_STYLE, true)
|
||||
, ThreadBase(false, "DbgConsole thread")
|
||||
: FrameBase(nullptr, wxID_ANY, "DbgConsole", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxDEFAULT_FRAME_STYLE, true)
|
||||
, ThreadBase("DbgConsole thread")
|
||||
{
|
||||
m_console = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
||||
wxSize(500, 500), wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
|
||||
@ -39,8 +39,14 @@ void DbgConsole::Clear()
|
||||
|
||||
void DbgConsole::Task()
|
||||
{
|
||||
while(m_dbg_buffer.HasNewPacket() && !TestDestroy())
|
||||
while(!TestDestroy())
|
||||
{
|
||||
if(!m_dbg_buffer.HasNewPacket())
|
||||
{
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
DbgPacket packet = m_dbg_buffer.Pop();
|
||||
m_console->SetDefaultStyle(packet.m_ch == 1 ? *m_color_red : *m_color_white);
|
||||
m_console->SetInsertionPointEnd();
|
||||
@ -52,7 +58,7 @@ void DbgConsole::Task()
|
||||
|
||||
void DbgConsole::OnQuit(wxCloseEvent& event)
|
||||
{
|
||||
ThreadBase::Stop();
|
||||
ThreadBase::Stop(false);
|
||||
Hide();
|
||||
//event.Skip();
|
||||
}
|
@ -54,7 +54,7 @@ bool vfsLocalFile::Open(const wxString& path, vfsOpenMode mode)
|
||||
bool vfsLocalFile::Create(const wxString& path)
|
||||
{
|
||||
ConLog.Warning("vfsLocalFile::Create('%s')", path.c_str());
|
||||
for(uint p=1;p<path.Length();p++)
|
||||
for(uint p=1; path[p] != '\0'; p++)
|
||||
{
|
||||
for(; path[p] != '\0'; p++)
|
||||
if(path[p] == '\\') break;
|
||||
|
@ -12,11 +12,12 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
|
||||
{
|
||||
static const char f[4] = {'x', 'y', 'z', 'w'};
|
||||
|
||||
std::string swizzle = "";
|
||||
std::string swizzle;
|
||||
swizzle += f[src0.cond_swizzle_x];
|
||||
swizzle += f[src0.cond_swizzle_y];
|
||||
swizzle += f[src0.cond_swizzle_z];
|
||||
swizzle += f[src0.cond_swizzle_w];
|
||||
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
|
||||
|
||||
if(src0.exec_if_gr && src0.exec_if_eq)
|
||||
{
|
||||
@ -43,10 +44,7 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
|
||||
cond = "equal";
|
||||
}
|
||||
|
||||
cond = std::string("if(all(" + cond + "(" + AddCond(dst.no_dest) + "." + swizzle +", vec4(0, 0, 0, 0)))) ");
|
||||
//ConLog.Error("cond! [eq: %d gr: %d lt: %d] (%s)", src0.exec_if_eq, src0.exec_if_gr, src0.exec_if_lt, cond);
|
||||
//Emu.Pause();
|
||||
//return;
|
||||
cond = "if(all(" + cond + "(" + AddCond(dst.no_dest) + swizzle + ", vec4(0.0)))) ";
|
||||
}
|
||||
|
||||
if(src1.scale)
|
||||
@ -72,16 +70,32 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
|
||||
code = "clamp(" + code + ", 0.0, 1.0)";
|
||||
}
|
||||
|
||||
code = cond + (dst.set_cond ? m_parr.AddParam(PARAM_NONE , "vec4", std::string(dst.fp16 ? "hc" : "rc") + std::to_string(src0.cond_reg_index))
|
||||
: AddReg(dst.dest_reg, dst.fp16)) + mask
|
||||
+ " = " + code + (append_mask ? mask : "");
|
||||
if(!dst.no_dest)
|
||||
{
|
||||
std::string dest;
|
||||
|
||||
if(dst.set_cond)
|
||||
{
|
||||
dest = m_parr.AddParam(PARAM_NONE , "vec4", std::string(dst.fp16 ? "hc" : "rc") + std::to_string(src0.cond_reg_index));
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = AddReg(dst.dest_reg, dst.fp16);
|
||||
}
|
||||
|
||||
code = cond + dest + mask + " = " + code + (append_mask ? mask : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
code = cond + code + (append_mask ? mask : "");
|
||||
}
|
||||
|
||||
main += "\t" + code + ";\n";
|
||||
}
|
||||
|
||||
std::string GLFragmentDecompilerThread::GetMask()
|
||||
{
|
||||
std::string ret = "";
|
||||
std::string ret;
|
||||
|
||||
static const char dst_mask[4] =
|
||||
{
|
||||
@ -98,13 +112,13 @@ std::string GLFragmentDecompilerThread::GetMask()
|
||||
|
||||
std::string GLFragmentDecompilerThread::AddReg(u32 index, int fp16)
|
||||
{
|
||||
if(index >= 2 && index <= 4)
|
||||
{
|
||||
return m_parr.AddParam(PARAM_OUT, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index),
|
||||
(fp16) ? -1 : (index - 1));
|
||||
}
|
||||
if(index >= 2 && index <= 4)
|
||||
{
|
||||
return m_parr.AddParam(PARAM_OUT, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index),
|
||||
(fp16) ? -1 : (index - 1));
|
||||
}
|
||||
|
||||
return m_parr.AddParam(PARAM_NONE, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index), "vec4(0.0)");
|
||||
return m_parr.AddParam(PARAM_NONE, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index), "vec4(0.0, 0.0, 0.0, 0.0)");
|
||||
|
||||
//return m_parr.AddParam((index >= 2 && index <= 4) ? PARAM_OUT : PARAM_NONE, "vec4",
|
||||
// std::string(fp16 ? "h" : "r") + std::to_string(index), (fp16 || !index) ? -1 : ((index >= 2 && index <= 4) ? (index - 1) : -1));
|
||||
|
@ -109,7 +109,7 @@ struct GLFragmentDecompilerThread : public ThreadBase
|
||||
u32 m_ctrl;
|
||||
|
||||
GLFragmentDecompilerThread(std::string& shader, GLParamArray& parr, u32 addr, u32& size, u32 ctrl)
|
||||
: ThreadBase(false, "Fragment Shader Decompiler Thread")
|
||||
: ThreadBase("Fragment Shader Decompiler Thread")
|
||||
, m_shader(shader)
|
||||
, m_parr(parr)
|
||||
, m_addr(addr)
|
||||
@ -155,7 +155,7 @@ struct GLShaderProgram
|
||||
{
|
||||
if(m_decompiler_thread && m_decompiler_thread->IsAlive())
|
||||
{
|
||||
m_decompiler_thread->Wait();
|
||||
m_decompiler_thread->Join();
|
||||
}
|
||||
}
|
||||
void Decompile(RSXShaderProgram& prog);
|
||||
|
@ -109,7 +109,7 @@ extern CellGcmContextData current_context;
|
||||
|
||||
void GLGSRender::Close()
|
||||
{
|
||||
if(IsAlive()) Stop();
|
||||
Stop();
|
||||
|
||||
if(m_frame->IsShown()) m_frame->Hide();
|
||||
m_ctrl = nullptr;
|
||||
|
@ -151,7 +151,7 @@ wxString GLVertexDecompilerThread::GetSRC(const u32 n, bool isSca)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask, bool set_dst)
|
||||
void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask, bool set_dst, bool set_cond)
|
||||
{
|
||||
if(d0.cond == 0) return;
|
||||
enum
|
||||
@ -161,28 +161,42 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
|
||||
gt = 0x4,
|
||||
};
|
||||
|
||||
static const char* cond_string_table[(lt | gt | eq) + 1] =
|
||||
{
|
||||
"error",
|
||||
"lessThan",
|
||||
"equal",
|
||||
"lessThanEqual",
|
||||
"greaterThan",
|
||||
"notEqual",
|
||||
"greaterThanEqual",
|
||||
"error"
|
||||
};
|
||||
|
||||
wxString cond;
|
||||
|
||||
if(d0.cond != (lt | gt | eq))
|
||||
if((set_cond || d0.cond_test_enable) && d0.cond != (lt | gt | eq))
|
||||
{
|
||||
if((d0.cond & (lt | gt)) == (lt | gt))
|
||||
{
|
||||
cond = "!=";
|
||||
}
|
||||
else
|
||||
{
|
||||
if(d0.cond & lt) cond = "<";
|
||||
else if(d0.cond & gt) cond = ">";
|
||||
else if(d0.cond & eq) cond = "=";
|
||||
static const char f[4] = {'x', 'y', 'z', 'w'};
|
||||
|
||||
if(d0.cond & eq) cond += "=";
|
||||
}
|
||||
std::string swizzle;
|
||||
swizzle += f[d0.mask_x];
|
||||
swizzle += f[d0.mask_y];
|
||||
swizzle += f[d0.mask_z];
|
||||
swizzle += f[d0.mask_w];
|
||||
|
||||
//ConLog.Error("cond! %d (%d %s %d %d)", d0.cond, d0.dst_tmp, cond, d1.input_src, d1.const_src);
|
||||
cond = wxString::Format("if(rc %s 0) ", cond.mb_str());
|
||||
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
|
||||
|
||||
cond = wxString::Format("if(all(%s(rc%s, vec4(0.0)%s))) ", cond_string_table[d0.cond], swizzle.c_str(), swizzle.c_str());
|
||||
}
|
||||
|
||||
wxString value = src_mask ? code + GetMask(is_sca) : code;
|
||||
wxString mask = GetMask(is_sca);
|
||||
wxString value = src_mask ? code + mask : code;
|
||||
|
||||
if(is_sca && d0.vec_result)
|
||||
{
|
||||
value = "vec4(" + value + ")" + mask;
|
||||
}
|
||||
|
||||
if(d0.staturate)
|
||||
{
|
||||
@ -194,26 +208,28 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
|
||||
wxString dest;
|
||||
if(d0.cond_update_enable_0)
|
||||
{
|
||||
dest = m_parr.AddParam(PARAM_NONE, "float", "rc");
|
||||
dest = m_parr.AddParam(PARAM_NONE, "vec4", "rc", "vec4(0.0)") + mask;
|
||||
}
|
||||
else if(d3.dst == 5 || d3.dst == 6)
|
||||
{
|
||||
int num = d3.dst == 5 ? 0 : 3;
|
||||
|
||||
if(d3.vec_writemask_x)
|
||||
{
|
||||
ConLog.Error("Bad clip mask.");
|
||||
dest = "gl_FogFragCoord";
|
||||
}
|
||||
else
|
||||
{
|
||||
int num = d3.dst == 5 ? 0 : 3;
|
||||
|
||||
//if(d3.vec_writemask_y) num += 0;
|
||||
if(d3.vec_writemask_z) num += 1;
|
||||
else if(d3.vec_writemask_w) num += 2;
|
||||
//if(d3.vec_writemask_y) num += 0;
|
||||
if(d3.vec_writemask_z) num += 1;
|
||||
else if(d3.vec_writemask_w) num += 2;
|
||||
|
||||
dest = wxString::Format(GetDST(is_sca), num);
|
||||
dest = wxString::Format(GetDST(is_sca) + "/*" + mask + "*/", num);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = GetDST(is_sca) + GetMask(is_sca);
|
||||
dest = GetDST(is_sca) + mask;
|
||||
}
|
||||
|
||||
code = cond + dest + " = " + value;
|
||||
@ -223,7 +239,7 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
|
||||
code = cond + value;
|
||||
}
|
||||
|
||||
m_body.Add(code + wxString::Format(";//%d %d %d %d", d0.cond_reg_sel_1, d0.cond_test_enable, d0.cond_update_enable_0, d0.cond_update_enable_1));
|
||||
m_body.Add(code + ";");
|
||||
}
|
||||
|
||||
wxString GLVertexDecompilerThread::GetFunc()
|
||||
@ -249,9 +265,9 @@ void GLVertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask, b
|
||||
AddCode(false, code, src_mask, set_dst);
|
||||
}
|
||||
|
||||
void GLVertexDecompilerThread::AddScaCode(const wxString& code, bool set_dst)
|
||||
void GLVertexDecompilerThread::AddScaCode(const wxString& code, bool set_dst, bool set_cond)
|
||||
{
|
||||
AddCode(true, code, false, set_dst);
|
||||
AddCode(true, code, false, set_dst, set_cond);
|
||||
}
|
||||
|
||||
wxString GLVertexDecompilerThread::BuildFuncBody(const FuncInfo& func)
|
||||
@ -296,7 +312,7 @@ wxString GLVertexDecompilerThread::BuildCode()
|
||||
|
||||
wxString fp = wxEmptyString;
|
||||
|
||||
for(int i=m_funcs.GetCount() - 1; i>=0; --i)
|
||||
for(int i=m_funcs.GetCount() - 1; i>0; --i)
|
||||
{
|
||||
fp += wxString::Format("void %s();\n", m_funcs[i].name.mb_str());
|
||||
}
|
||||
@ -339,17 +355,17 @@ void GLVertexDecompilerThread::Task()
|
||||
{
|
||||
case 0x00: break; // NOP
|
||||
case 0x01: AddScaCode(GetSRC(2, true)); break; // MOV
|
||||
case 0x02: AddScaCode("1 / (" + GetSRC(2, true) + ")"); break; // RCP
|
||||
case 0x03: AddScaCode("clamp(1 / (" + GetSRC(2, true) + "), 5.42101e-20, 1.884467e19)"); break; // RCC
|
||||
case 0x02: AddScaCode("1.0 / " + GetSRC(2, true)); break; // RCP
|
||||
case 0x03: AddScaCode("clamp(1.0 / " + GetSRC(2, true) + ", 5.42101e-20, 1.884467e19)"); break; // RCC
|
||||
case 0x04: AddScaCode("inversesqrt(" + GetSRC(2, true) + ")"); break; // RSQ
|
||||
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
|
||||
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
|
||||
//case 0x07: break; // LIT
|
||||
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false); break; // BRA
|
||||
case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false); break; // BRI : works differently (BRI o[1].x(TR) L0;)
|
||||
case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false); break; // CAL : works same as BRI
|
||||
case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false); break; // CLI : works same as BRI
|
||||
case 0x0c: AddScaCode("return", false); break; // RET : works like BRI but shorter (RET o[1].x(TR);)
|
||||
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false, true); break; // BRA
|
||||
case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false, true); break; // BRI : works differently (BRI o[1].x(TR) L0;)
|
||||
case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false, true); break; // CAL : works same as BRI
|
||||
case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false, true); break; // CLI : works same as BRI
|
||||
case 0x0c: AddScaCode("return", false, true); break; // RET : works like BRI but shorter (RET o[1].x(TR);)
|
||||
case 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2
|
||||
case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
|
||||
case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN
|
||||
|
@ -143,7 +143,7 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||
GLParamArray& m_parr;
|
||||
|
||||
GLVertexDecompilerThread(Array<u32>& data, wxString& shader, GLParamArray& parr)
|
||||
: ThreadBase(false, "Vertex Shader Decompiler Thread")
|
||||
: ThreadBase("Vertex Shader Decompiler Thread")
|
||||
, m_data(data)
|
||||
, m_shader(shader)
|
||||
, m_parr(parr)
|
||||
@ -160,9 +160,9 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||
wxString GetDST(bool is_sca = false);
|
||||
wxString GetSRC(const u32 n, bool is_sca = false);
|
||||
wxString GetFunc();
|
||||
void AddCode(bool is_sca, wxString code, bool src_mask = true, bool set_dst = true);
|
||||
void AddCode(bool is_sca, wxString code, bool src_mask = true, bool set_dst = true, bool set_cond = true);
|
||||
void AddVecCode(const wxString& code, bool src_mask = true, bool set_dst = true);
|
||||
void AddScaCode(const wxString& code, bool set_dst = true);
|
||||
void AddScaCode(const wxString& code, bool set_dst = true, bool set_cond = true);
|
||||
wxString BuildFuncBody(const FuncInfo& func);
|
||||
wxString BuildCode();
|
||||
|
||||
@ -182,9 +182,9 @@ struct GLVertexProgram
|
||||
|
||||
void Wait()
|
||||
{
|
||||
if(m_decompiler_thread && m_decompiler_thread->IsRunning())
|
||||
if(m_decompiler_thread && m_decompiler_thread->IsAlive())
|
||||
{
|
||||
m_decompiler_thread->Wait();
|
||||
m_decompiler_thread->Join();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,17 +9,17 @@ struct NullGSFrame : public GSFrame
|
||||
}
|
||||
|
||||
void Draw()
|
||||
{
|
||||
wxClientDC dc(this);
|
||||
Draw(&dc);
|
||||
}
|
||||
{
|
||||
wxClientDC dc(this);
|
||||
Draw(&dc);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void OnPaint(wxPaintEvent& event)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
Draw(&dc);
|
||||
}
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
Draw(&dc);
|
||||
}
|
||||
virtual void OnSize(wxSizeEvent& event)
|
||||
{
|
||||
GSFrame::OnSize(event);
|
||||
@ -77,7 +77,7 @@ private:
|
||||
|
||||
virtual void Close()
|
||||
{
|
||||
if(IsAlive()) Stop();
|
||||
Stop();
|
||||
|
||||
if(m_frame->IsShown()) m_frame->Hide();
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ public:
|
||||
|
||||
protected:
|
||||
RSXThread()
|
||||
: ThreadBase(false, "RSXThread")
|
||||
: ThreadBase("RSXThread")
|
||||
, m_ctrl(nullptr)
|
||||
, m_flip_status(0)
|
||||
, m_flip_mode(CELL_GCM_DISPLAY_VSYNC)
|
||||
|
@ -53,23 +53,29 @@ void Callback::Branch(bool wait)
|
||||
{
|
||||
m_has_data = false;
|
||||
|
||||
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
CPUThread& thr = Emu.GetCallbackThread();
|
||||
|
||||
new_thread.SetEntry(m_addr);
|
||||
new_thread.SetPrio(1001);
|
||||
new_thread.SetStackSize(0x10000);
|
||||
new_thread.SetName(m_name);
|
||||
while(Emu.IsRunning() && thr.IsAlive())
|
||||
Sleep(1);
|
||||
|
||||
new_thread.SetArg(0, a1);
|
||||
new_thread.SetArg(1, a2);
|
||||
new_thread.SetArg(2, a3);
|
||||
new_thread.SetArg(3, a4);
|
||||
new_thread.Run();
|
||||
thr.Stop();
|
||||
thr.Reset();
|
||||
|
||||
new_thread.Exec();
|
||||
thr.SetEntry(m_addr);
|
||||
thr.SetPrio(1001);
|
||||
thr.SetStackSize(0x10000);
|
||||
thr.SetName(m_name);
|
||||
|
||||
thr.SetArg(0, a1);
|
||||
thr.SetArg(1, a2);
|
||||
thr.SetArg(2, a3);
|
||||
thr.SetArg(3, a4);
|
||||
thr.Run();
|
||||
|
||||
thr.Exec();
|
||||
|
||||
if(wait)
|
||||
GetCurrentPPCThread()->Wait(new_thread);
|
||||
GetCurrentPPCThread()->Wait(thr);
|
||||
}
|
||||
|
||||
void Callback::SetName(const std::string& name)
|
||||
|
@ -193,11 +193,8 @@ int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void
|
||||
//get a unique id for the callback (may be used by cellFsAioCancel)
|
||||
const u32 xid = g_FsAioReadID++;
|
||||
|
||||
//read data in another thread (doesn't work correctly):
|
||||
//std::thread t(fsAioRead, fd, aio, xid, func);
|
||||
//t.detach();
|
||||
//read data immediately (actually it should be read in special thread):
|
||||
fsAioRead(fd, aio, xid, func);
|
||||
thread t("fsAioRead", std::bind(fsAioRead, fd, aio, xid, func));
|
||||
t.detach();
|
||||
|
||||
aio_id = xid;
|
||||
|
||||
|
@ -23,9 +23,11 @@ void sys_ppu_thread_exit(int errorcode)
|
||||
|
||||
PPUThread& thr = GetCurrentPPUThread();
|
||||
thr.SetExitStatus(errorcode);
|
||||
Emu.GetCPU().RemoveThread(thr.GetId());
|
||||
thr.Stop();
|
||||
|
||||
throw errorcode;
|
||||
//Emu.GetCPU().RemoveThread(thr.GetId());
|
||||
|
||||
//throw errorcode;
|
||||
}
|
||||
|
||||
int sys_ppu_thread_yield()
|
||||
|
@ -27,6 +27,7 @@ Emulator::Emulator()
|
||||
, m_mode(DisAsm)
|
||||
, m_dbg_console(nullptr)
|
||||
, m_rsx_callback(0)
|
||||
, m_ppu_callback_thr(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -310,6 +311,8 @@ void Emulator::Load()
|
||||
|
||||
case MACHINE_PPC64:
|
||||
{
|
||||
m_ppu_callback_thr = &GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
thread.SetEntry(l.GetEntry());
|
||||
Memory.StackMem.Alloc(0x1000);
|
||||
thread.InitStack();
|
||||
|
@ -88,6 +88,8 @@ class Emulator
|
||||
GSManager m_gs_manager;
|
||||
AudioManager m_audio_manager;
|
||||
CallbackManager m_callback_manager;
|
||||
CPUThread* m_ppu_callback_thr;
|
||||
|
||||
VFS m_vfs;
|
||||
|
||||
EmuInfo m_info;
|
||||
@ -125,6 +127,7 @@ public:
|
||||
VFS& GetVFS() { return m_vfs; }
|
||||
Array<u64>& GetBreakPoints() { return m_break_points; }
|
||||
Array<u64>& GetMarkedPoints() { return m_marked_points; }
|
||||
CPUThread& GetCallbackThread() { return *m_ppu_callback_thr; }
|
||||
|
||||
void AddModuleInit(ModuleInitializer* m)
|
||||
{
|
||||
|
@ -114,13 +114,16 @@ LogWriter::LogWriter()
|
||||
|
||||
void LogWriter::WriteToLog(std::string prefix, std::string value, std::string colour/*, wxColour bgcolour*/)
|
||||
{
|
||||
if(ThreadBase* thr = GetCurrentNamedThread())
|
||||
if(!prefix.empty())
|
||||
{
|
||||
prefix = (prefix.empty() ? "" : prefix + " : ") + thr->GetThreadName();
|
||||
if(NamedThreadBase* thr = GetCurrentNamedThread())
|
||||
{
|
||||
prefix += " : " + thr->GetThreadName();
|
||||
}
|
||||
}
|
||||
|
||||
if(m_logfile.IsOpened())
|
||||
m_logfile.Write((prefix.empty() ? wxString(wxEmptyString) : std::string("[" + prefix + "]: ") + value + "\n").c_str());
|
||||
m_logfile.Write((prefix.empty() ? "" : std::string("[" + prefix + "]: ") + value + "\n").c_str());
|
||||
|
||||
if(!ConLogFrame) return;
|
||||
|
||||
@ -221,7 +224,7 @@ END_EVENT_TABLE()
|
||||
|
||||
LogFrame::LogFrame(wxWindow* parent)
|
||||
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(600, 500))
|
||||
, ThreadBase(false, "LogThread")
|
||||
, ThreadBase("LogThread")
|
||||
, m_log(*new wxListView(this))
|
||||
{
|
||||
m_log.InsertColumn(0, wxEmptyString);
|
||||
@ -243,8 +246,8 @@ LogFrame::~LogFrame()
|
||||
|
||||
bool LogFrame::Close(bool force)
|
||||
{
|
||||
Stop();
|
||||
ConLogFrame = NULL;
|
||||
Stop(false);
|
||||
ConLogFrame = nullptr;
|
||||
return wxWindowBase::Close(force);
|
||||
}
|
||||
|
||||
@ -286,7 +289,7 @@ void LogFrame::Task()
|
||||
|
||||
void LogFrame::OnQuit(wxCloseEvent& event)
|
||||
{
|
||||
Stop();
|
||||
ConLogFrame = NULL;
|
||||
Stop(false);
|
||||
ConLogFrame = nullptr;
|
||||
event.Skip();
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ class DumperThread : public ThreadBase
|
||||
wxArrayString** arr;
|
||||
|
||||
public:
|
||||
DumperThread() : ThreadBase(true, "DumperThread")
|
||||
DumperThread() : ThreadBase("DumperThread")
|
||||
{
|
||||
}
|
||||
|
||||
@ -200,7 +200,7 @@ struct WaitDumperThread : public ThreadBase
|
||||
wxArrayString** arr;
|
||||
|
||||
WaitDumperThread(bool* _done, u8 _cores, wxString _patch, MTProgressDialog& _prog_dial, wxArrayString** _arr)
|
||||
: ThreadBase()
|
||||
: ThreadBase("WaitDumperThread")
|
||||
, done(_done)
|
||||
, cores(_cores)
|
||||
, patch(_patch)
|
||||
|
Loading…
x
Reference in New Issue
Block a user