Improved OpenGL renderer & RAW SPU

- Improved Fragment Shader Decompiler.
- Fixed NV308A_COLOR cmd.
- Fixed break points for RAW SPU Thread.
- Added cellMsgDialogOpen2 to cellSysutil module.
This commit is contained in:
DH 2013-11-26 06:34:19 +02:00
parent dae31c44e0
commit 9ce30fdd74
15 changed files with 154 additions and 121 deletions

View File

@ -314,7 +314,7 @@ void CPUThread::Task()
for(uint i=0; i<bp.GetCount(); ++i)
{
if(bp[i] == m_offset + PC)
if(bp[i] == PC)
{
Emu.Pause();
break;

View File

@ -284,7 +284,7 @@ void RawSPUThread::Task()
}
}
bool is_last_paused = false;
bool is_last_paused = SPU.RunCntl.GetValue() == SPU_RUNCNTL_STOP;
while(true)
{
int status = ThreadStatus();
@ -327,9 +327,15 @@ void RawSPUThread::Task()
Step();
NextPc(m_dec->DecodeMemory(PC + m_offset));
if(status == CPUThread_Step)
{
m_is_step = false;
break;
}
for(uint i=0; i<bp.GetCount(); ++i)
{
if(bp[i] == m_offset + PC)
if(bp[i] == PC)
{
Emu.Pause();
break;

View File

@ -317,9 +317,9 @@ private:
}
void BISL(u32 rt, u32 ra)
{
CPU.SetBranch(CPU.GPR[ra]._u32[3] & 0xfffffffc);
CPU.SetBranch(branchTarget(CPU.GPR[ra]._u32[3], 0));
CPU.GPR[rt].Reset();
CPU.GPR[rt]._u32[0] = CPU.PC + 4;
CPU.GPR[rt]._u32[3] = CPU.PC + 4;
}
void IRET(u32 ra)
{
@ -393,10 +393,19 @@ private:
}
void ROTQBYBI(u32 rt, u32 ra, u32 rb)
{
const int nShift = (CPU.GPR[rb]._u32[0] >> 3) & 0xf;
const int s = (CPU.GPR[rb]._u32[0] >> 3) & 0xf;
for (int b = 0; b < 8; b++)
CPU.GPR[rt]._u8[b] = nShift == 0 ? CPU.GPR[ra]._u8[b] : (CPU.GPR[ra]._u8[b] << nShift) | (CPU.GPR[ra]._u8[b] >> (16 - nShift));
{
if(b + s < 16)
{
CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s];
}
else
{
CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s - 16];
}
}
}
void ROTQMBYBI(u32 rt, u32 ra, u32 rb)
{

View File

@ -107,13 +107,13 @@ wxString GLFragmentDecompilerThread::AddReg(u32 index, int fp16)
//ConLog.Warning("%c%d: %d %d", (fp16 ? 'h' : 'r'), index, dst.tex_num, src2.use_index_reg);
return m_parr.AddParam(fp16 ? PARAM_NONE : PARAM_OUT, "vec4",
wxString::Format((fp16 ? "h%u" : "r%u"), index), fp16 ? -1 : (!index ? 0 : ((index >= 2 && index <= 4) ? (index - 1) : -1)));
return m_parr.AddParam((index >= 2 && index <= 4) ? PARAM_OUT : PARAM_NONE, "vec4",
wxString::Format((fp16 ? "h%u" : "r%u"), index), (fp16 || !index) ? -1 : ((index >= 2 && index <= 4) ? (index - 1) : -1));
}
bool GLFragmentDecompilerThread::HasReg(u32 index, int fp16)
{
return m_parr.HasParam(PARAM_OUT, "vec4",
return m_parr.HasParam((index >= 2 && index <= 4) ? PARAM_OUT : PARAM_NONE, "vec4",
wxString::Format((fp16 ? "h%u" : "r%u"), index));
}
@ -207,6 +207,10 @@ template<typename T> wxString GLFragmentDecompilerThread::GetSRC(T src)
wxString GLFragmentDecompilerThread::BuildCode()
{
//main += wxString::Format("\tgl_FragColor = %c0;\n", m_ctrl & 0x40 ? 'r' : 'h');
main += "\t" + m_parr.AddParam(PARAM_OUT, "vec4", "ocol", 0) + " = " + (m_ctrl & 0x40 ? "r0" : "h0") + ";\n";
if(m_ctrl & 0xe) main += "\tgl_FragDepth = r1.z;\n";
wxString p = wxEmptyString;
for(u32 i=0; i<m_parr.params.GetCount(); ++i)
@ -365,7 +369,7 @@ void GLShaderProgram::Decompile(RSXShaderProgram& prog)
m_decompiler_thread = nullptr;
}
m_decompiler_thread = new GLFragmentDecompilerThread(shader, parr, prog.addr, prog.size);
m_decompiler_thread = new GLFragmentDecompilerThread(shader, parr, prog.addr, prog.size, prog.ctrl);
m_decompiler_thread->Start();
#endif
}

View File

@ -106,8 +106,9 @@ struct GLFragmentDecompilerThread : public ThreadBase
u32 m_const_index;
u32 m_offset;
u32 m_location;
u32 m_ctrl;
GLFragmentDecompilerThread(wxString& shader, GLParamArray& parr, u32 addr, u32& size)
GLFragmentDecompilerThread(wxString& shader, GLParamArray& parr, u32 addr, u32& size, u32 ctrl)
: ThreadBase(false, "Fragment Shader Decompiler Thread")
, m_shader(shader)
, m_parr(parr)
@ -115,6 +116,7 @@ struct GLFragmentDecompilerThread : public ThreadBase
, m_size(size)
, m_const_index(0)
, m_location(0)
, m_ctrl(ctrl)
{
m_size = 0;
}

View File

@ -333,16 +333,20 @@ void GLGSRender::InitFragmentData()
{
const RSXTransformConstant& c = m_fragment_constants[i];
u32 id = c.id - m_cur_shader_prog->offset + 2 * 4 * 4;
u32 id = c.id - m_cur_shader_prog->offset;
//ConLog.Warning("fc%u[0x%x - 0x%x] = (%f, %f, %f, %f)", id, c.id, m_cur_shader_prog->offset, c.x, c.y, c.z, c.w);
const wxString name = wxString::Format("fc%u", id);
const int l = m_program.GetLocation(name);
checkForGlError("glGetUniformLocation " + name);
//ConLog.Write(name + " x: %.02f y: %.02f z: %.02f w: %.02f", c.x, c.y, c.z, c.w);
glUniform4f(l, c.x, c.y, c.z, c.w);
checkForGlError("glUniform4f " + name + wxString::Format(" %d [%f %f %f %f]", l, c.x, c.y, c.z, c.w));
}
//if(m_fragment_constants.GetCount())
// ConLog.SkipLn();
}
bool GLGSRender::LoadProgram()
@ -804,7 +808,7 @@ void GLGSRender::ExecCMD()
Enable(m_depth_test_enable, GL_DEPTH_TEST);
Enable(m_set_alpha_test, GL_ALPHA_TEST);
Enable(m_set_depth_bounds_test, GL_DEPTH_CLAMP);
Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT);
Enable(m_set_blend, GL_BLEND);
Enable(m_set_logic_op, GL_LOGIC_OP);
Enable(m_set_cull_face_enable, GL_CULL_FACE);
@ -815,7 +819,7 @@ void GLGSRender::ExecCMD()
Enable(m_set_poly_offset_fill, GL_POLYGON_OFFSET_FILL);
Enable(m_set_poly_offset_line, GL_POLYGON_OFFSET_LINE);
Enable(m_set_poly_offset_point, GL_POLYGON_OFFSET_POINT);
Enable(m_set_restart_index, GL_PRIMITIVE_RESTART); //Requires OpenGL 3.1+
//Enable(m_set_restart_index, GL_PRIMITIVE_RESTART); //Requires OpenGL 3.1+
if(m_set_clip_plane)
{
@ -905,17 +909,20 @@ void GLGSRender::ExecCMD()
if(m_set_depth_func)
{
glDepthFunc(m_depth_func);
//ConLog.Warning("glDepthFunc(0x%x)", m_depth_func);
checkForGlError("glDepthFunc");
}
if(m_set_depth_bounds)
{
glDepthRange(m_depth_bounds_min, m_depth_bounds_max);
//ConLog.Warning("glDepthRange(%f, %f)", m_depth_bounds_min, m_depth_bounds_max);
glDepthBounds(m_depth_bounds_min, m_depth_bounds_max);
checkForGlError("glDepthRange");
}
if(m_set_clip)
{
//ConLog.Warning("glDepthRangef(%f, %f)", m_clip_min, m_clip_max);
glDepthRangef(m_clip_min, m_clip_max);
checkForGlError("glDepthRangef");
}

View File

@ -5,11 +5,13 @@ struct RSXShaderProgram
u32 size;
u32 addr;
u32 offset;
u32 ctrl;
RSXShaderProgram()
: size(0)
, addr(0)
, offset(0)
, ctrl(0)
{
}
};

View File

@ -166,6 +166,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
location = 1;
}
u32 tex_addr = GetAddress(offset, location);
if(!Memory.IsGoodAddr(tex_addr))
ConLog.Error("Bad texture[%d] addr = 0x%x #offset = 0x%x, location=%d", index, tex_addr, offset, location);
//ConLog.Warning("texture addr = 0x%x #offset = 0x%x, location=%d", tex_addr, offset, location);
tex.SetOffset(tex_addr);
tex.SetFormat(cubemap, dimension, format, mipmap);
@ -637,6 +639,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
u32 a0 = args[0];
m_cur_shader_prog->offset = a0 & ~0x3;
m_cur_shader_prog->addr = GetAddress(m_cur_shader_prog->offset, (a0 & 0x3) - 1);
m_cur_shader_prog->ctrl = 0x40;
}
break;
@ -649,11 +652,13 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
case NV4097_SET_SHADER_CONTROL:
{
const u32 arg0 = args[0];
if(!m_cur_shader_prog)
{
ConLog.Error("NV4097_SET_SHADER_CONTROL: m_cur_shader_prog == NULL");
break;
}
//const u8 controlTxp = (arg0 >> 15) & 0x1;
//FragmentData.prog.registerCount = arg0 >> 24;
//FragmentData.prog.
m_cur_shader_prog->ctrl = args[0];
}
break;
@ -1118,8 +1123,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
case NV4097_SET_ZCULL_CONTROL0:
{
m_set_depth_func = true;
m_depth_func = args[0] >> 4;
//m_set_depth_func = true;
//m_depth_func = args[0] >> 4;
}
break;
@ -1180,7 +1185,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
case NV308A_COLOR:
{
RSXTransformConstant c;
c.id = m_dst_offset;
c.id = m_dst_offset | ((u32)m_point_x << 2);
if(count >= 1)
{
@ -1221,7 +1226,11 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
break;
case NV308A_POINT:
//TODO
{
u32 a0 = args[0];
m_point_x = a0 & 0xffff;
m_point_y = a0 >> 16;
}
break;
case NV3062_SET_COLOR_FORMAT:

View File

@ -511,6 +511,8 @@ public:
u8 m_shader_window_origin;
u16 m_shader_window_pixel_centers;
u16 m_point_x, m_point_y;
u32 m_surface_colour_target;
u8 m_begin_end;
@ -554,6 +556,9 @@ protected:
m_depth_bounds_max = 1.0;
m_restart_index = 0xffffffff;
m_point_x = 0;
m_point_y = 0;
Reset();
}

View File

@ -142,11 +142,16 @@ bool IsLoadedFunc(u32 id)
bool CallFunc(u32 num)
{
if(num - 1024 >= g_modules_funcs_list.GetCount())
return false;
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
{
if(g_modules_funcs_list[i].id == num)
{
(*g_modules_funcs_list[i].func)();
return true;
}
}
(*g_modules_funcs_list[num - 1024].func)();
return true;
return false;
}
bool UnloadFunc(u32 id)
@ -166,14 +171,6 @@ bool UnloadFunc(u32 id)
u32 GetFuncNumById(u32 id)
{
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
{
if(g_modules_funcs_list[i].id == id)
{
return 1024 + i;
}
}
return id;
}

View File

@ -102,6 +102,29 @@ enum
void cellSysutil_init();
Module cellSysutil(0x0015, cellSysutil_init);
enum
{
CELL_MSGDIALOG_BUTTON_NONE = -1,
CELL_MSGDIALOG_BUTTON_INVALID = 0,
CELL_MSGDIALOG_BUTTON_OK = 1,
CELL_MSGDIALOG_BUTTON_YES = 1,
CELL_MSGDIALOG_BUTTON_NO = 2,
CELL_MSGDIALOG_BUTTON_ESCAPE = 3,
};
enum CellMsgDialogType
{
CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000,
CELL_MSGDIALOG_DIALOG_TYPE_NORMAL = 0x00000001,
CELL_MSGDIALOG_BUTTON_TYPE_NONE = 0x00000000,
CELL_MSGDIALOG_BUTTON_TYPE_YESNO = 0x00000010,
CELL_MSGDIALOG_DEFAULT_CURSOR_YES = 0x00000000,
CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100,
};
int cellSysutilGetSystemParamInt(int id, mem32_t value)
{
cellSysutil.Log("cellSysutilGetSystemParamInt(id=0x%x, value_addr=0x%x)", id, value.GetAddr());
@ -408,6 +431,55 @@ int cellSysutilUnregisterCallback(int slot)
return CELL_OK;
}
int cellMsgDialogOpen2(u32 type, u32 msgString_addr, u32 callback_addr, u32 userData, u32 extParam)
{
long style = 0;
if(type & CELL_MSGDIALOG_DIALOG_TYPE_NORMAL)
{
style |= wxICON_EXCLAMATION;
}
else
{
style |= wxICON_ERROR;
}
if(type & CELL_MSGDIALOG_BUTTON_TYPE_YESNO)
{
style |= wxYES_NO;
}
else
{
style |= wxOK;
}
int res = wxMessageBox(Memory.ReadString(msgString_addr), wxGetApp().GetAppName(), style);
u64 status;
switch(res)
{
case wxOK: status = CELL_MSGDIALOG_BUTTON_OK; break;
case wxYES: status = CELL_MSGDIALOG_BUTTON_YES; break;
case wxNO: status = CELL_MSGDIALOG_BUTTON_NO; break;
default:
if(res)
{
status = CELL_MSGDIALOG_BUTTON_INVALID;
break;
}
status = CELL_MSGDIALOG_BUTTON_NONE;
break;
}
Callback2 callback(0, callback_addr, userData);
callback.Handle(status);
callback.Branch(true);
return CELL_OK;
}
void cellSysutil_init()
{
@ -424,4 +496,6 @@ void cellSysutil_init()
cellSysutil.AddFunc(0x189a74da, cellSysutilCheckCallback);
cellSysutil.AddFunc(0x9d98afa0, cellSysutilRegisterCallback);
cellSysutil.AddFunc(0x02ff3c1b, cellSysutilUnregisterCallback);
cellSysutil.AddFunc(0x7603d3db, cellMsgDialogOpen2);
}

View File

@ -1,76 +0,0 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
SysCallBase sc_md("cellMsgDialog");
enum
{
CELL_MSGDIALOG_BUTTON_NONE = -1,
CELL_MSGDIALOG_BUTTON_INVALID = 0,
CELL_MSGDIALOG_BUTTON_OK = 1,
CELL_MSGDIALOG_BUTTON_YES = 1,
CELL_MSGDIALOG_BUTTON_NO = 2,
CELL_MSGDIALOG_BUTTON_ESCAPE = 3,
};
enum CellMsgDialogType
{
CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000,
CELL_MSGDIALOG_DIALOG_TYPE_NORMAL = 0x00000001,
CELL_MSGDIALOG_BUTTON_TYPE_NONE = 0x00000000,
CELL_MSGDIALOG_BUTTON_TYPE_YESNO = 0x00000010,
CELL_MSGDIALOG_DEFAULT_CURSOR_YES = 0x00000000,
CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100,
};
int cellMsgDialogOpen2(u32 type, u32 msgString_addr, u32 callback_addr, u32 userData, u32 extParam)
{
long style = 0;
if(type & CELL_MSGDIALOG_DIALOG_TYPE_NORMAL)
{
style |= wxICON_EXCLAMATION;
}
else
{
style |= wxICON_ERROR;
}
if(type & CELL_MSGDIALOG_BUTTON_TYPE_YESNO)
{
style |= wxYES_NO;
}
else
{
style |= wxOK;
}
int res = wxMessageBox(Memory.ReadString(msgString_addr), wxGetApp().GetAppName(), style);
u64 status;
switch(res)
{
case wxOK: status = CELL_MSGDIALOG_BUTTON_OK; break;
case wxYES: status = CELL_MSGDIALOG_BUTTON_YES; break;
case wxNO: status = CELL_MSGDIALOG_BUTTON_NO; break;
default:
if(res)
{
status = CELL_MSGDIALOG_BUTTON_INVALID;
break;
}
status = CELL_MSGDIALOG_BUTTON_NONE;
break;
}
Callback2 callback(0, callback_addr, userData);
callback.Handle(status);
callback.Branch(true);
return CELL_OK;
}

View File

@ -248,8 +248,8 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr)
{
if(!Memory.IsGoodAddr(CPU->GetOffset() + PC, 4))
{
m_list->SetItem(i, 0, wxString::Format("[%08llx] illegal address", PC));
count = 2;
m_list->SetItem(i, 0, wxString(IsBreakPoint(PC) ? ">>> " : " ") + wxString::Format("[%08llx] illegal address", PC));
count = 4;
continue;
}
@ -529,8 +529,6 @@ void InterpreterDisAsmFrame::DClick(wxListEvent& event)
const u64 pc = start_pc + i*4;
//ConLog.Write("pc=0x%llx", pc);
if(!Memory.IsGoodAddr(pc, 4)) return;
if(IsBreakPoint(pc))
{
RemoveBreakPoint(pc);

View File

@ -253,7 +253,6 @@
<ClCompile Include="Emu\SysCalls\lv2\SC_Rwlock.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\SC_Semaphore.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\SC_SPU_Thread.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\SC_SysUtil_MsgDialog.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\SC_Time.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\SC_Timer.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\SC_Trace.cpp" />

View File

@ -205,9 +205,6 @@
<ClCompile Include="Emu\FS\vfsStreamMemory.cpp">
<Filter>Emu\FS</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\lv2\SC_SysUtil_MsgDialog.cpp">
<Filter>Emu\SysCalls\lv2</Filter>
</ClCompile>
<ClCompile Include="Emu\FS\vfsDevice.cpp">
<Filter>Emu\FS</Filter>
</ClCompile>