Fixed conflicts

This commit is contained in:
Nekotekina 2014-02-01 01:56:44 +04:00
commit 6553909dc5
25 changed files with 367 additions and 291 deletions

View File

@ -1,97 +1,149 @@
#include "stdafx.h" #include "stdafx.h"
#include "Thread.h" #include "Thread.h"
ThreadBase* GetCurrentNamedThread() static DWORD g_tls_this_thread = 0xFFFFFFFF;
{
ThreadExec* thr = (ThreadExec*)::wxThread::This();
return thr ? thr->m_parent : nullptr;
}
ThreadBase::ThreadBase(bool detached, const std::string& name) struct __init_tls
: m_detached(detached)
, m_name(name)
, m_executor(nullptr)
{ {
} //NamedThreadBase m_main_thr;
void ThreadBase::Start() __init_tls()
{
if(m_executor) return;
m_executor = new ThreadExec(m_detached, this);
}
void ThreadBase::Resume()
{
if(m_executor)
{ {
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() ~__init_tls()
{
if(m_executor)
{ {
m_executor->Pause(); ::TlsFree(g_tls_this_thread);
} }
} } _init_tls;
void ThreadBase::Stop(bool wait) NamedThreadBase* GetCurrentNamedThread()
{ {
if(!m_executor) return; return (NamedThreadBase*)::TlsGetValue(g_tls_this_thread);
ThreadExec* exec = m_executor;
m_executor = nullptr;
if(!m_detached)
{
if(wait)
{
exec->Wait();
}
exec->Stop(false);
delete exec;
}
else
{
exec->Stop(wait);
}
} }
bool ThreadBase::Wait() const std::string NamedThreadBase::GetThreadName() 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
{ {
return m_name; return m_name;
} }
void ThreadBase::SetThreadName(const std::string& name) void NamedThreadBase::SetThreadName(const std::string& name)
{ {
m_name = 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();
} }

View File

@ -3,84 +3,68 @@
#include <functional> #include <functional>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <atomic>
#include <condition_variable> #include <condition_variable>
class ThreadExec; class ThreadExec;
class ThreadBase class NamedThreadBase
{ {
protected:
std::string m_name; std::string m_name;
bool m_detached;
public: public:
std::mutex m_main_mutex; NamedThreadBase(const std::string& name) : m_name(name)
{
}
protected: NamedThreadBase()
ThreadBase(bool detached = true, const std::string& name = "Unknown ThreadBase"); {
}
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 std::string GetThreadName() const;
virtual void SetThreadName(const std::string& name); 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; protected:
volatile bool m_alive; 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: public:
ThreadBase* m_parent; void Start();
void Stop(bool wait = true);
ThreadExec(bool detached, ThreadBase* parent) bool Join() const;
: wxThread(detached ? wxTHREAD_DETACHED : wxTHREAD_JOINABLE) bool IsAlive() const;
, m_parent(parent) bool TestDestroy() const;
, m_alive(true)
{
Create();
Run();
}
void Stop(bool wait = true) virtual void Task() = 0;
{
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;
}
}; };
//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 template<typename T> class MTPacketBuffer
{ {

View File

@ -7,7 +7,7 @@ CPUThread* GetCurrentCPUThread()
} }
CPUThread::CPUThread(CPUThreadType type) CPUThread::CPUThread(CPUThreadType type)
: ThreadBase(true, "CPUThread") : ThreadBase("CPUThread")
, m_type(type) , m_type(type)
, m_stack_size(0) , m_stack_size(0)
, m_stack_addr(0) , m_stack_addr(0)
@ -15,30 +15,24 @@ CPUThread::CPUThread(CPUThreadType type)
, m_prio(0) , m_prio(0)
, m_sync_wait(false) , m_sync_wait(false)
, m_wait_thread_id(-1) , m_wait_thread_id(-1)
, m_free_data(false)
, m_dec(nullptr) , m_dec(nullptr)
, m_is_step(false) , m_is_step(false)
, m_is_branch(false) , m_is_branch(false)
, m_status(Stopped)
{ {
} }
CPUThread::~CPUThread() CPUThread::~CPUThread()
{ {
Close();
} }
void CPUThread::Close() void CPUThread::Close()
{ {
if(IsAlive()) ThreadBase::Stop();
{ DoStop();
m_free_data = true;
ThreadBase::Stop(false); delete m_dec;
} m_dec = nullptr;
else
{
delete m_dec;
m_dec = nullptr;
}
} }
void CPUThread::Reset() void CPUThread::Reset()
@ -77,7 +71,7 @@ void CPUThread::SetId(const u32 id)
void CPUThread::SetName(const std::string& name) void CPUThread::SetName(const std::string& name)
{ {
m_name = name; NamedThreadBase::SetThreadName(name);
} }
void CPUThread::Wait(bool wait) void CPUThread::Wait(bool wait)
@ -189,12 +183,10 @@ wxArrayString CPUThread::ErrorToString(const u32 error)
void CPUThread::Run() void CPUThread::Run()
{ {
if(IsRunning()) Stop(); if(!IsStopped())
if(IsPaused()) Stop();
{
Resume(); Reset();
return;
}
#ifndef QT_UI #ifndef QT_UI
wxGetApp().SendDbgCommand(DID_START_THREAD, this); wxGetApp().SendDbgCommand(DID_START_THREAD, this);
@ -244,7 +236,7 @@ void CPUThread::Pause()
DoPause(); DoPause();
Emu.CheckStatus(); Emu.CheckStatus();
ThreadBase::Stop(false); ThreadBase::Stop();
#ifndef QT_UI #ifndef QT_UI
wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this); wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this);
#endif #endif
@ -259,9 +251,15 @@ void CPUThread::Stop()
#endif #endif
m_status = Stopped; m_status = Stopped;
ThreadBase::Stop(false);
Reset(); if(CPUThread* thr = GetCurrentCPUThread())
DoStop(); {
if(thr->GetId() != GetId())
ThreadBase::Stop();
}
else
ThreadBase::Stop();
Emu.CheckStatus(); Emu.CheckStatus();
#ifndef QT_UI #ifndef QT_UI
@ -275,7 +273,9 @@ void CPUThread::Exec()
#ifndef QT_UI #ifndef QT_UI
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this); wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
#endif #endif
ThreadBase::Start();
if(IsRunning())
ThreadBase::Start();
} }
void CPUThread::ExecOnce() void CPUThread::ExecOnce()
@ -285,7 +285,7 @@ void CPUThread::ExecOnce()
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this); wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
#endif #endif
ThreadBase::Start(); ThreadBase::Start();
if(!ThreadBase::Wait()) while(m_is_step) Sleep(1); ThreadBase::Stop();
#ifndef QT_UI #ifndef QT_UI
wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, this); wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, this);
wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this); wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this);
@ -294,7 +294,7 @@ void CPUThread::ExecOnce()
void CPUThread::Task() void CPUThread::Task()
{ {
//ConLog.Write("%s enter", CPUThread::GetFName()); ConLog.Write("%s enter", CPUThread::GetFName());
const Array<u64>& bp = Emu.GetBreakPoints(); const Array<u64>& bp = Emu.GetBreakPoints();
@ -354,15 +354,7 @@ void CPUThread::Task()
catch(int exitcode) catch(int exitcode)
{ {
ConLog.Success("Exit Code: %d", exitcode); ConLog.Success("Exit Code: %d", exitcode);
return;
} }
//ConLog.Write("%s leave", CPUThread::GetFName()); ConLog.Write("%s leave", CPUThread::GetFName());
if(m_free_data)
{
delete m_dec;
m_dec = nullptr;
free(this);
}
} }

View File

@ -32,7 +32,6 @@ protected:
CPUThreadType m_type; CPUThreadType m_type;
bool m_joinable; bool m_joinable;
bool m_joining; bool m_joining;
bool m_free_data;
bool m_is_step; bool m_is_step;
u64 m_stack_addr; u64 m_stack_addr;
@ -68,7 +67,7 @@ public:
u32 GetExitStatus() const { return m_exit_status; } u32 GetExitStatus() const { return m_exit_status; }
u64 GetPrio() const { return m_prio; } u64 GetPrio() const { return m_prio; }
std::string GetName() const { return m_name; } std::string GetName() const { return NamedThreadBase::GetThreadName(); }
wxString GetFName() const wxString GetFName() const
{ {
return return

View File

@ -64,16 +64,7 @@ void CPUThreadManager::RemoveThread(const u32 id)
#ifndef QT_UI #ifndef QT_UI
wxGetApp().SendDbgCommand(DID_REMOVE_THREAD, thr); wxGetApp().SendDbgCommand(DID_REMOVE_THREAD, thr);
#endif #endif
if(thr->IsAlive()) thr->Close();
{
//thr->Close();
}
else
{
//thr->Close();
//delete thr;
}
m_threads.RemoveFAt(i); m_threads.RemoveFAt(i);
break; break;

View File

@ -21,7 +21,7 @@ RawSPUThread::~RawSPUThread()
} }
} }
Close(); //Close();
} }
bool RawSPUThread::Read8(const u64 addr, u8* value) bool RawSPUThread::Read8(const u64 addr, u8* value)

View File

@ -78,7 +78,7 @@ void SPUThread::DoRun()
break; break;
} }
Pause(); //Pause();
//Emu.Pause(); //Emu.Pause();
} }

View File

@ -6,8 +6,8 @@ BEGIN_EVENT_TABLE(DbgConsole, FrameBase)
END_EVENT_TABLE() END_EVENT_TABLE()
DbgConsole::DbgConsole() DbgConsole::DbgConsole()
: FrameBase(NULL, wxID_ANY, "DbgConsole", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxDEFAULT_FRAME_STYLE, true) : FrameBase(nullptr, wxID_ANY, "DbgConsole", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxDEFAULT_FRAME_STYLE, true)
, ThreadBase(false, "DbgConsole thread") , ThreadBase("DbgConsole thread")
{ {
m_console = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, m_console = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(500, 500), wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2); wxSize(500, 500), wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
@ -39,8 +39,14 @@ void DbgConsole::Clear()
void DbgConsole::Task() 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(); DbgPacket packet = m_dbg_buffer.Pop();
m_console->SetDefaultStyle(packet.m_ch == 1 ? *m_color_red : *m_color_white); m_console->SetDefaultStyle(packet.m_ch == 1 ? *m_color_red : *m_color_white);
m_console->SetInsertionPointEnd(); m_console->SetInsertionPointEnd();
@ -52,7 +58,7 @@ void DbgConsole::Task()
void DbgConsole::OnQuit(wxCloseEvent& event) void DbgConsole::OnQuit(wxCloseEvent& event)
{ {
ThreadBase::Stop(); ThreadBase::Stop(false);
Hide(); Hide();
//event.Skip(); //event.Skip();
} }

View File

@ -54,7 +54,7 @@ bool vfsLocalFile::Open(const wxString& path, vfsOpenMode mode)
bool vfsLocalFile::Create(const wxString& path) bool vfsLocalFile::Create(const wxString& path)
{ {
ConLog.Warning("vfsLocalFile::Create('%s')", path.c_str()); 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++) for(; path[p] != '\0'; p++)
if(path[p] == '\\') break; if(path[p] == '\\') break;

View File

@ -6,17 +6,18 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return; if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return;
const std::string mask = GetMask().c_str(); const std::string mask = GetMask().c_str();
std::string cond = ""; std::string cond;
if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq) if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq)
{ {
static const char f[4] = {'x', 'y', 'z', 'w'}; 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_x];
swizzle += f[src0.cond_swizzle_y]; swizzle += f[src0.cond_swizzle_y];
swizzle += f[src0.cond_swizzle_z]; swizzle += f[src0.cond_swizzle_z];
swizzle += f[src0.cond_swizzle_w]; swizzle += f[src0.cond_swizzle_w];
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
if(src0.exec_if_gr && src0.exec_if_eq) 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 = "equal";
} }
cond = std::string("if(all(" + cond + "(" + AddCond(dst.no_dest) + "." + swizzle +", vec4(0, 0, 0, 0)))) "); cond = "if(all(" + cond + "(" + AddCond(dst.no_dest) + swizzle + ", vec4(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;
} }
if(src1.scale) if(src1.scale)
@ -72,16 +70,28 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
code = "clamp(" + code + ", 0.0, 1.0)"; 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)) std::string dest;
: AddReg(dst.dest_reg, dst.fp16)) + mask
+ " = " + code + (append_mask ? mask : ""); if(dst.no_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.length() ? dest + mask + " = " : "") + code + (append_mask ? mask : "");
main += "\t" + code + ";\n"; main += "\t" + code + ";\n";
} }
std::string GLFragmentDecompilerThread::GetMask() std::string GLFragmentDecompilerThread::GetMask()
{ {
std::string ret = ""; std::string ret;
static const char dst_mask[4] = static const char dst_mask[4] =
{ {
@ -98,17 +108,16 @@ std::string GLFragmentDecompilerThread::GetMask()
std::string GLFragmentDecompilerThread::AddReg(u32 index, int fp16) std::string GLFragmentDecompilerThread::AddReg(u32 index, int fp16)
{ {
/* if(index >= 2 && index <= 4)
if(HasReg(index, fp16))
{ {
return wxString::Format((fp16 ? "h%u" : "r%u"), index); return m_parr.AddParam(PARAM_OUT, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index),
(fp16) ? -1 : (index - 1));
} }
*/
//ConLog.Warning("%c%d: %d %d", (fp16 ? 'h' : 'r'), index, dst.tex_num, src2.use_index_reg); 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", //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)); // std::string(fp16 ? "h" : "r") + std::to_string(index), (fp16 || !index) ? -1 : ((index >= 2 && index <= 4) ? (index - 1) : -1));
} }
bool GLFragmentDecompilerThread::HasReg(u32 index, int fp16) bool GLFragmentDecompilerThread::HasReg(u32 index, int fp16)
@ -219,6 +228,15 @@ std::string GLFragmentDecompilerThread::BuildCode()
p += m_parr.params[i].Format(); p += m_parr.params[i].Format();
} }
//return "#version 330\n\
\n\
out vec3 color;\n\
in vec4 tc1;\n\
\n\
void main()\n\
{\n\
color = tc1.rgb;\n\
}";
return std::string("#version 330\n" return std::string("#version 330\n"
"\n" "\n"
+ p + "\n" + p + "\n"

View File

@ -109,7 +109,7 @@ struct GLFragmentDecompilerThread : public ThreadBase
u32 m_ctrl; u32 m_ctrl;
GLFragmentDecompilerThread(std::string& shader, GLParamArray& parr, u32 addr, u32& size, u32 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_shader(shader)
, m_parr(parr) , m_parr(parr)
, m_addr(addr) , m_addr(addr)
@ -155,7 +155,7 @@ struct GLShaderProgram
{ {
if(m_decompiler_thread && m_decompiler_thread->IsAlive()) if(m_decompiler_thread && m_decompiler_thread->IsAlive())
{ {
m_decompiler_thread->Wait(); m_decompiler_thread->Join();
} }
} }
void Decompile(RSXShaderProgram& prog); void Decompile(RSXShaderProgram& prog);

View File

@ -109,7 +109,7 @@ extern CellGcmContextData current_context;
void GLGSRender::Close() void GLGSRender::Close()
{ {
if(IsAlive()) Stop(); Stop();
if(m_frame->IsShown()) m_frame->Hide(); if(m_frame->IsShown()) m_frame->Hide();
m_ctrl = nullptr; m_ctrl = nullptr;

View File

@ -151,7 +151,7 @@ wxString GLVertexDecompilerThread::GetSRC(const u32 n, bool isSca)
return ret; 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; if(d0.cond == 0) return;
enum enum
@ -161,28 +161,42 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
gt = 0x4, gt = 0x4,
}; };
static const char* cond_string_table[(lt | gt | eq) + 1] =
{
"error",
"lessThan",
"equal",
"lessThanEqual",
"greaterThan",
"notEqual",
"greaterThanEqual",
"error"
};
wxString cond; 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)) static const char f[4] = {'x', 'y', 'z', 'w'};
{
cond = "!=";
}
else
{
if(d0.cond & lt) cond = "<";
else if(d0.cond & gt) cond = ">";
else if(d0.cond & eq) cond = "=";
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); swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
cond = wxString::Format("if(rc %s 0) ", cond.mb_str());
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) if(d0.staturate)
{ {
@ -194,26 +208,28 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
wxString dest; wxString dest;
if(d0.cond_update_enable_0) 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) else if(d3.dst == 5 || d3.dst == 6)
{ {
int num = d3.dst == 5 ? 0 : 3;
if(d3.vec_writemask_x) if(d3.vec_writemask_x)
{ {
ConLog.Error("Bad clip mask."); dest = m_parr.AddParam(PARAM_OUT, "vec4", "fogc") + mask;
} }
else
{
int num = d3.dst == 5 ? 0 : 3;
//if(d3.vec_writemask_y) num += 0; //if(d3.vec_writemask_y) num += 0;
if(d3.vec_writemask_z) num += 1; if(d3.vec_writemask_z) num += 1;
else if(d3.vec_writemask_w) num += 2; else if(d3.vec_writemask_w) num += 2;
dest = wxString::Format(GetDST(is_sca), num); dest = wxString::Format(GetDST(is_sca) + "/*" + mask + "*/", num);
}
} }
else else
{ {
dest = GetDST(is_sca) + GetMask(is_sca); dest = GetDST(is_sca) + mask;
} }
code = cond + dest + " = " + value; code = cond + dest + " = " + value;
@ -223,7 +239,7 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
code = cond + value; 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() wxString GLVertexDecompilerThread::GetFunc()
@ -249,9 +265,9 @@ void GLVertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask, b
AddCode(false, code, src_mask, set_dst); 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) wxString GLVertexDecompilerThread::BuildFuncBody(const FuncInfo& func)
@ -296,7 +312,7 @@ wxString GLVertexDecompilerThread::BuildCode()
wxString fp = wxEmptyString; 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()); fp += wxString::Format("void %s();\n", m_funcs[i].name.mb_str());
} }
@ -322,6 +338,8 @@ wxString GLVertexDecompilerThread::BuildCode()
void GLVertexDecompilerThread::Task() void GLVertexDecompilerThread::Task()
{ {
m_parr.params.Clear();
for(u32 i=0;;) for(u32 i=0;;)
{ {
d0.HEX = m_data[i++]; d0.HEX = m_data[i++];
@ -339,17 +357,17 @@ void GLVertexDecompilerThread::Task()
{ {
case 0x00: break; // NOP case 0x00: break; // NOP
case 0x01: AddScaCode(GetSRC(2, true)); break; // MOV case 0x01: AddScaCode(GetSRC(2, true)); break; // MOV
case 0x02: AddScaCode("1 / (" + GetSRC(2, true) + ")"); break; // RCP case 0x02: AddScaCode("1.0 / " + GetSRC(2, true)); break; // RCP
case 0x03: AddScaCode("clamp(1 / (" + GetSRC(2, true) + "), 5.42101e-20, 1.884467e19)"); break; // RCC 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 0x04: AddScaCode("inversesqrt(" + GetSRC(2, true) + ")"); break; // RSQ
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
//case 0x07: break; // LIT //case 0x07: break; // LIT
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false); break; // BRA case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false, true); break; // BRA
case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false); break; // BRI : works differently (BRI o[1].x(TR) L0;) case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false, true); break; // BRI : works differently (BRI o[1].x(TR) L0;)
case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false); break; // CAL : works same as BRI case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false, true); break; // CAL : works same as BRI
case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false); break; // CLI : works same as BRI case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false, true); break; // CLI : works same as BRI
case 0x0c: AddScaCode("return", false); break; // RET : works like BRI but shorter (RET o[1].x(TR);) 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 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2
case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2 case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN

View File

@ -143,7 +143,7 @@ struct GLVertexDecompilerThread : public ThreadBase
GLParamArray& m_parr; GLParamArray& m_parr;
GLVertexDecompilerThread(Array<u32>& data, wxString& shader, GLParamArray& parr) GLVertexDecompilerThread(Array<u32>& data, wxString& shader, GLParamArray& parr)
: ThreadBase(false, "Vertex Shader Decompiler Thread") : ThreadBase("Vertex Shader Decompiler Thread")
, m_data(data) , m_data(data)
, m_shader(shader) , m_shader(shader)
, m_parr(parr) , m_parr(parr)
@ -160,9 +160,9 @@ struct GLVertexDecompilerThread : public ThreadBase
wxString GetDST(bool is_sca = false); wxString GetDST(bool is_sca = false);
wxString GetSRC(const u32 n, bool is_sca = false); wxString GetSRC(const u32 n, bool is_sca = false);
wxString GetFunc(); 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 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 BuildFuncBody(const FuncInfo& func);
wxString BuildCode(); wxString BuildCode();
@ -182,9 +182,9 @@ struct GLVertexProgram
void Wait() 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();
} }
} }

View File

@ -9,17 +9,17 @@ struct NullGSFrame : public GSFrame
} }
void Draw() void Draw()
{ {
wxClientDC dc(this); wxClientDC dc(this);
Draw(&dc); Draw(&dc);
} }
private: private:
virtual void OnPaint(wxPaintEvent& event) virtual void OnPaint(wxPaintEvent& event)
{ {
wxPaintDC dc(this); wxPaintDC dc(this);
Draw(&dc); Draw(&dc);
} }
virtual void OnSize(wxSizeEvent& event) virtual void OnSize(wxSizeEvent& event)
{ {
GSFrame::OnSize(event); GSFrame::OnSize(event);
@ -77,7 +77,7 @@ private:
virtual void Close() virtual void Close()
{ {
if(IsAlive()) Stop(); Stop();
if(m_frame->IsShown()) m_frame->Hide(); if(m_frame->IsShown()) m_frame->Hide();
} }

View File

@ -265,7 +265,6 @@ public:
u32 m_report_main_addr; u32 m_report_main_addr;
u32 m_local_mem_addr, m_main_mem_addr; u32 m_local_mem_addr, m_main_mem_addr;
Array<MemInfo> m_main_mem_info;
public: public:
uint m_draw_mode; uint m_draw_mode;
@ -520,7 +519,7 @@ public:
protected: protected:
RSXThread() RSXThread()
: ThreadBase(false, "RSXThread") : ThreadBase("RSXThread")
, m_ctrl(nullptr) , m_ctrl(nullptr)
, m_flip_status(0) , m_flip_status(0)
, m_flip_mode(CELL_GCM_DISPLAY_VSYNC) , m_flip_mode(CELL_GCM_DISPLAY_VSYNC)
@ -637,7 +636,7 @@ protected:
switch(location) switch(location)
{ {
case CELL_GCM_LOCATION_LOCAL: return m_local_mem_addr + offset; case CELL_GCM_LOCATION_LOCAL: return m_local_mem_addr + offset;
case CELL_GCM_LOCATION_MAIN: return m_main_mem_addr + offset; case CELL_GCM_LOCATION_MAIN: return Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + offset);
} }
ConLog.Error("GetAddress(offset=0x%x, location=0x%x)", location); ConLog.Error("GetAddress(offset=0x%x, location=0x%x)", location);

View File

@ -691,12 +691,17 @@ struct _func_arg
template<typename T> template<typename T>
struct _func_arg<mem_base_t<T>> struct _func_arg<mem_base_t<T>>
{ {
__forceinline static u64 get_value(const mem_base_t<T>& arg) __forceinline static u64 get_value(const mem_base_t<T> arg)
{ {
return arg.GetAddr(); return arg.GetAddr();
} }
}; };
template<typename T> struct _func_arg<mem_ptr_t<T>> : public _func_arg<mem_base_t<T>> {};
template<> struct _func_arg<mem_ptr_t<void>> : public _func_arg<mem_base_t<u8>> {};
template<typename T> struct _func_arg<mem_list_ptr_t<T>> : public _func_arg<mem_base_t<T>> {};
template<typename T> struct _func_arg<mem_t<T>> : public _func_arg<mem_base_t<T>> {};
template<typename T> template<typename T>
struct _func_arg<be_t<T>> struct _func_arg<be_t<T>>
{ {

View File

@ -53,23 +53,29 @@ void Callback::Branch(bool wait)
{ {
m_has_data = false; m_has_data = false;
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); CPUThread& thr = Emu.GetCallbackThread();
new_thread.SetEntry(m_addr); while(Emu.IsRunning() && thr.IsAlive())
new_thread.SetPrio(1001); Sleep(1);
new_thread.SetStackSize(0x10000);
new_thread.SetName(m_name);
new_thread.SetArg(0, a1); thr.Stop();
new_thread.SetArg(1, a2); thr.Reset();
new_thread.SetArg(2, a3);
new_thread.SetArg(3, a4);
new_thread.Run();
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) if(wait)
GetCurrentPPCThread()->Wait(new_thread); GetCurrentPPCThread()->Wait(thr);
} }
void Callback::SetName(const std::string& name) void Callback::SetName(const std::string& name)

View File

@ -107,7 +107,6 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
render.m_tiles_addr = Memory.Alloc(sizeof(CellGcmTileInfo) * 15, sizeof(CellGcmTileInfo)); render.m_tiles_addr = Memory.Alloc(sizeof(CellGcmTileInfo) * 15, sizeof(CellGcmTileInfo));
render.m_gcm_buffers_count = 0; render.m_gcm_buffers_count = 0;
render.m_gcm_current_buffer = 0; render.m_gcm_current_buffer = 0;
render.m_main_mem_info.Clear();
render.m_main_mem_addr = 0; render.m_main_mem_addr = 0;
render.Init(ctx_begin, ctx_size, gcm_info.control_addr, local_addr); render.Init(ctx_begin, ctx_size, gcm_info.control_addr, local_addr);
@ -725,7 +724,6 @@ int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset)
} }
Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress; Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress;
Emu.GetGSManager().GetRender().m_main_mem_info.AddCpy(MemInfo(ea, size));
return CELL_OK; return CELL_OK;
} }

View File

@ -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) //get a unique id for the callback (may be used by cellFsAioCancel)
const u32 xid = g_FsAioReadID++; const u32 xid = g_FsAioReadID++;
//read data in another thread (doesn't work correctly): thread t("fsAioRead", std::bind(fsAioRead, fd, aio, xid, func));
//std::thread t(fsAioRead, fd, aio, xid, func); t.detach();
//t.detach();
//read data immediately (actually it should be read in special thread):
fsAioRead(fd, aio, xid, func);
aio_id = xid; aio_id = xid;

View File

@ -23,9 +23,11 @@ void sys_ppu_thread_exit(int errorcode)
PPUThread& thr = GetCurrentPPUThread(); PPUThread& thr = GetCurrentPPUThread();
thr.SetExitStatus(errorcode); thr.SetExitStatus(errorcode);
Emu.GetCPU().RemoveThread(thr.GetId()); thr.Stop();
throw errorcode; //Emu.GetCPU().RemoveThread(thr.GetId());
//throw errorcode;
} }
int sys_ppu_thread_yield() int sys_ppu_thread_yield()

View File

@ -27,6 +27,7 @@ Emulator::Emulator()
, m_mode(DisAsm) , m_mode(DisAsm)
, m_dbg_console(nullptr) , m_dbg_console(nullptr)
, m_rsx_callback(0) , m_rsx_callback(0)
, m_ppu_callback_thr(0)
{ {
} }
@ -310,6 +311,8 @@ void Emulator::Load()
case MACHINE_PPC64: case MACHINE_PPC64:
{ {
m_ppu_callback_thr = &GetCPU().AddThread(CPU_THREAD_PPU);
thread.SetEntry(l.GetEntry()); thread.SetEntry(l.GetEntry());
Memory.StackMem.Alloc(0x1000); Memory.StackMem.Alloc(0x1000);
thread.InitStack(); thread.InitStack();

View File

@ -88,6 +88,8 @@ class Emulator
GSManager m_gs_manager; GSManager m_gs_manager;
AudioManager m_audio_manager; AudioManager m_audio_manager;
CallbackManager m_callback_manager; CallbackManager m_callback_manager;
CPUThread* m_ppu_callback_thr;
VFS m_vfs; VFS m_vfs;
EmuInfo m_info; EmuInfo m_info;
@ -125,6 +127,7 @@ public:
VFS& GetVFS() { return m_vfs; } VFS& GetVFS() { return m_vfs; }
Array<u64>& GetBreakPoints() { return m_break_points; } Array<u64>& GetBreakPoints() { return m_break_points; }
Array<u64>& GetMarkedPoints() { return m_marked_points; } Array<u64>& GetMarkedPoints() { return m_marked_points; }
CPUThread& GetCallbackThread() { return *m_ppu_callback_thr; }
void AddModuleInit(ModuleInitializer* m) void AddModuleInit(ModuleInitializer* m)
{ {

View File

@ -114,13 +114,16 @@ LogWriter::LogWriter()
void LogWriter::WriteToLog(std::string prefix, std::string value, std::string colour/*, wxColour bgcolour*/) 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()) 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; if(!ConLogFrame) return;
@ -221,7 +224,7 @@ END_EVENT_TABLE()
LogFrame::LogFrame(wxWindow* parent) LogFrame::LogFrame(wxWindow* parent)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(600, 500)) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(600, 500))
, ThreadBase(false, "LogThread") , ThreadBase("LogThread")
, m_log(*new wxListView(this)) , m_log(*new wxListView(this))
{ {
m_log.InsertColumn(0, wxEmptyString); m_log.InsertColumn(0, wxEmptyString);
@ -243,8 +246,8 @@ LogFrame::~LogFrame()
bool LogFrame::Close(bool force) bool LogFrame::Close(bool force)
{ {
Stop(); Stop(false);
ConLogFrame = NULL; ConLogFrame = nullptr;
return wxWindowBase::Close(force); return wxWindowBase::Close(force);
} }
@ -286,7 +289,7 @@ void LogFrame::Task()
void LogFrame::OnQuit(wxCloseEvent& event) void LogFrame::OnQuit(wxCloseEvent& event)
{ {
Stop(); Stop(false);
ConLogFrame = NULL; ConLogFrame = nullptr;
event.Skip(); event.Skip();
} }

View File

@ -121,7 +121,7 @@ class DumperThread : public ThreadBase
wxArrayString** arr; wxArrayString** arr;
public: public:
DumperThread() : ThreadBase(true, "DumperThread") DumperThread() : ThreadBase("DumperThread")
{ {
} }
@ -200,7 +200,7 @@ struct WaitDumperThread : public ThreadBase
wxArrayString** arr; wxArrayString** arr;
WaitDumperThread(bool* _done, u8 _cores, wxString _patch, MTProgressDialog& _prog_dial, wxArrayString** _arr) WaitDumperThread(bool* _done, u8 _cores, wxString _patch, MTProgressDialog& _prog_dial, wxArrayString** _arr)
: ThreadBase() : ThreadBase("WaitDumperThread")
, done(_done) , done(_done)
, cores(_cores) , cores(_cores)
, patch(_patch) , patch(_patch)