mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01:00
OpenGL Renderer fixes:
- Fixed Vertex & Fragment Shader Decompilers. - Fixed Transform Constants loading.
This commit is contained in:
parent
81e874c9e2
commit
f42d4b6572
@ -141,7 +141,7 @@ public:
|
|||||||
virtual void SetCount(const u32 count, bool memzero = true)
|
virtual void SetCount(const u32 count, bool memzero = true)
|
||||||
{
|
{
|
||||||
if(m_count >= count) return;
|
if(m_count >= count) return;
|
||||||
|
|
||||||
_InsertRoomEnd(count - m_count);
|
_InsertRoomEnd(count - m_count);
|
||||||
|
|
||||||
if(memzero) memset(m_array + m_count - count, 0, sizeof(T) * (m_count - count));
|
if(memzero) memset(m_array + m_count - count, 0, sizeof(T) * (m_count - count));
|
||||||
|
@ -381,7 +381,11 @@ public:
|
|||||||
, m_parent(nullptr)
|
, m_parent(nullptr)
|
||||||
, m_opcode(-1)
|
, m_opcode(-1)
|
||||||
{
|
{
|
||||||
memset(m_instrs, 0, sizeof(InstrCaller<TO>*) * count);
|
for(int i=0; i<count; ++i)
|
||||||
|
{
|
||||||
|
m_instrs[i] = error_func;
|
||||||
|
}
|
||||||
|
|
||||||
memset(m_instrs_info, 0, sizeof(InstrBase<TO>*) * count);
|
memset(m_instrs_info, 0, sizeof(InstrBase<TO>*) * count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,6 +417,14 @@ public:
|
|||||||
|
|
||||||
void set_error_func(InstrCaller<TO>* error_func)
|
void set_error_func(InstrCaller<TO>* error_func)
|
||||||
{
|
{
|
||||||
|
for(int i=0; i<count; ++i)
|
||||||
|
{
|
||||||
|
if(m_instrs[i] == m_error_func || !m_instrs[i])
|
||||||
|
{
|
||||||
|
m_instrs[i] = error_func;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_error_func = error_func;
|
m_error_func = error_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,16 +454,7 @@ public:
|
|||||||
|
|
||||||
void decode(TO* op, u32 entry, u32 code) const
|
void decode(TO* op, u32 entry, u32 code) const
|
||||||
{
|
{
|
||||||
InstrCaller<TO>* instr = m_instrs[entry];
|
(*m_instrs[entry])(op, code);
|
||||||
|
|
||||||
if(instr)
|
|
||||||
{
|
|
||||||
(*instr)(op, code);
|
|
||||||
}
|
|
||||||
else if(m_error_func)
|
|
||||||
{
|
|
||||||
(*m_error_func)(op, code);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void operator ()(TO* op, u32 code) const
|
virtual void operator ()(TO* op, u32 code) const
|
||||||
|
@ -3564,7 +3564,7 @@ private:
|
|||||||
}
|
}
|
||||||
void FNEG(u32 frd, u32 frb, bool rc)
|
void FNEG(u32 frd, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = -CPU.FPR[frb];
|
CPU.FPR[frd] = ((u64&)CPU.FPR[frb]) ^ (1ULL << 63);
|
||||||
if(rc) UNK("fneg.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
if(rc) UNK("fneg.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FMR(u32 frd, u32 frb, bool rc)
|
void FMR(u32 frd, u32 frb, bool rc)
|
||||||
|
@ -3,10 +3,38 @@
|
|||||||
|
|
||||||
void FragmentDecompilerThread::AddCode(wxString code)
|
void FragmentDecompilerThread::AddCode(wxString code)
|
||||||
{
|
{
|
||||||
if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_le) return;
|
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_le)
|
|
||||||
|
wxString cond;
|
||||||
|
|
||||||
|
if(src0.exec_if_gr)
|
||||||
{
|
{
|
||||||
ConLog.Error("Bad cond! eq: %d gr: %d le: %d", src0.exec_if_eq, src0.exec_if_gr, src0.exec_if_le);
|
cond = ">";
|
||||||
|
}
|
||||||
|
else if(src0.exec_if_lt)
|
||||||
|
{
|
||||||
|
cond = "<";
|
||||||
|
}
|
||||||
|
else if(src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
cond = "=";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
cond += "=";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(src0.exec_if_gr && src0.exec_if_lt)
|
||||||
|
{
|
||||||
|
cond = "!=";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cond)
|
||||||
|
{
|
||||||
|
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();
|
Emu.Pause();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -29,7 +57,7 @@ void FragmentDecompilerThread::AddCode(wxString code)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code = AddReg(dst.dest_reg) + GetMask() + " = " + code + GetMask();
|
code = AddReg(dst.dest_reg, dst.fp16) + GetMask() + " = " + code + GetMask();
|
||||||
|
|
||||||
main += "\t" + code + ";\n";
|
main += "\t" + code + ";\n";
|
||||||
}
|
}
|
||||||
@ -46,20 +74,29 @@ wxString FragmentDecompilerThread::GetMask()
|
|||||||
return ret.IsEmpty() || ret == "xyzw" ? wxEmptyString : ("." + ret);
|
return ret.IsEmpty() || ret == "xyzw" ? wxEmptyString : ("." + ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString FragmentDecompilerThread::AddReg(u32 index)
|
wxString FragmentDecompilerThread::AddReg(u32 index, int fp16)
|
||||||
{
|
{
|
||||||
//if(!index) return "gl_FragColor";
|
//if(!index) return "gl_FragColor";
|
||||||
return m_parr.AddParam(index ? PARAM_NONE : PARAM_OUT, "vec4", wxString::Format("r%d", index), index ? -1 : 0);
|
return m_parr.AddParam(index ? PARAM_NONE : PARAM_OUT, "vec4",
|
||||||
|
wxString::Format((fp16 ? "h%d" : "r%d"), index), (index || fp16) ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString FragmentDecompilerThread::AddConst()
|
wxString FragmentDecompilerThread::AddConst()
|
||||||
{
|
{
|
||||||
return m_parr.AddParam(PARAM_CONST, "vec4", wxString::Format("fc%d", m_const_index++));
|
mem32_t data(m_addr + m_size + m_offset);
|
||||||
|
|
||||||
|
m_offset += 4 * 4;
|
||||||
|
u32 x = GetData(data[0]);
|
||||||
|
u32 y = GetData(data[1]);
|
||||||
|
u32 z = GetData(data[2]);
|
||||||
|
u32 w = GetData(data[3]);
|
||||||
|
return m_parr.AddParam("vec4", wxString::Format("fc%d", m_const_index++),
|
||||||
|
wxString::Format("vec4(%f, %f, %f, %f)", (float&)x, (float&)y, (float&)z, (float&)w));
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString FragmentDecompilerThread::AddTex()
|
wxString FragmentDecompilerThread::AddTex()
|
||||||
{
|
{
|
||||||
return m_parr.AddParam(PARAM_CONST, "sampler2D", wxString::Format("tex_%d", dst.tex_num));
|
return m_parr.AddParam(PARAM_UNIFORM, "sampler2D", wxString::Format("tex%d", dst.tex_num));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> wxString FragmentDecompilerThread::GetSRC(T src)
|
template<typename T> wxString FragmentDecompilerThread::GetSRC(T src)
|
||||||
@ -69,7 +106,7 @@ template<typename T> wxString FragmentDecompilerThread::GetSRC(T src)
|
|||||||
switch(src.reg_type)
|
switch(src.reg_type)
|
||||||
{
|
{
|
||||||
case 0: //tmp
|
case 0: //tmp
|
||||||
ret += AddReg(src.tmp_reg_index);
|
ret += AddReg(src.tmp_reg_index, src.fp16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: //input
|
case 1: //input
|
||||||
@ -102,7 +139,6 @@ template<typename T> wxString FragmentDecompilerThread::GetSRC(T src)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: //const
|
case 2: //const
|
||||||
ConLog.Write("reg index = %d", src.tmp_reg_index);
|
|
||||||
ret += AddConst();
|
ret += AddConst();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -157,6 +193,8 @@ void FragmentDecompilerThread::Task()
|
|||||||
src1.HEX = GetData(data[2]);
|
src1.HEX = GetData(data[2]);
|
||||||
src2.HEX = GetData(data[3]);
|
src2.HEX = GetData(data[3]);
|
||||||
|
|
||||||
|
m_offset = 4 * 4;
|
||||||
|
|
||||||
switch(dst.opcode)
|
switch(dst.opcode)
|
||||||
{
|
{
|
||||||
case 0x00: break; //NOP
|
case 0x00: break; //NOP
|
||||||
@ -166,24 +204,24 @@ void FragmentDecompilerThread::Task()
|
|||||||
case 0x04: AddCode("(" + GetSRC(src0) + " * " + GetSRC(src1) + " + " + GetSRC(src2) + ")"); break; //MAD
|
case 0x04: AddCode("(" + GetSRC(src0) + " * " + GetSRC(src1) + " + " + GetSRC(src2) + ")"); break; //MAD
|
||||||
case 0x05: AddCode("dot(" + GetSRC(src0) + ".xyz, " + GetSRC(src1) + ".xyz)"); break; // DP3
|
case 0x05: AddCode("dot(" + GetSRC(src0) + ".xyz, " + GetSRC(src1) + ".xyz)"); break; // DP3
|
||||||
case 0x06: AddCode("dot(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // DP4
|
case 0x06: AddCode("dot(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // DP4
|
||||||
//case 0x07: break; // DST
|
case 0x07: AddCode("distance(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // DST
|
||||||
case 0x08: AddCode("min(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // MIN
|
case 0x08: AddCode("min(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // MIN
|
||||||
case 0x09: AddCode("max(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // MAX
|
case 0x09: AddCode("max(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // MAX
|
||||||
//case 0x0a: break; // SLT
|
case 0x0a: AddCode("vec4(lessThan(" + GetSRC(src0) + ", " + GetSRC(src1) + "))"); break; // SLT
|
||||||
//case 0x0b: break; // SGE
|
case 0x0b: AddCode("vec4(greaterThanEqual(" + GetSRC(src0) + ", " + GetSRC(src1) + "))"); break; // SGE
|
||||||
//case 0x0c: break; // SLE
|
case 0x0c: AddCode("vec4(lessThanEqual(" + GetSRC(src0) + ", " + GetSRC(src1) + "))"); break; // SLE
|
||||||
//case 0x0d: break; // SGT
|
case 0x0d: AddCode("vec4(greaterThan(" + GetSRC(src0) + ", " + GetSRC(src1) + "))"); break; // SGT
|
||||||
//case 0x0e: break; // SNE
|
case 0x0e: AddCode("vec4(notEqual(" + GetSRC(src0) + ", " + GetSRC(src1) + "))"); break; // SNE
|
||||||
//case 0x0f: break; // SEQ
|
case 0x0f: AddCode("vec4(equal(" + GetSRC(src0) + ", " + GetSRC(src1) + "))"); break; // SEQ
|
||||||
|
|
||||||
//case 0x10: break; // FRC
|
case 0x10: AddCode("fract(" + GetSRC(src0) + ")"); break; // FRC
|
||||||
//case 0x11: break; // FLR
|
case 0x11: AddCode("floor(" + GetSRC(src0) + ")"); break; // FLR
|
||||||
//case 0x12: break; // KIL
|
//case 0x12: break; // KIL
|
||||||
//case 0x13: break; // PK4
|
//case 0x13: break; // PK4
|
||||||
//case 0x14: break; // UP4
|
//case 0x14: break; // UP4
|
||||||
case 0x15: AddCode("ddx(" + GetSRC(src0) + ")"); break; // DDX
|
case 0x15: AddCode("ddx(" + GetSRC(src0) + ")"); break; // DDX
|
||||||
case 0x16: AddCode("ddy(" + GetSRC(src0) + ")"); break; // DDY
|
case 0x16: AddCode("ddy(" + GetSRC(src0) + ")"); break; // DDY
|
||||||
case 0x17: AddCode("texture(" + AddTex() + ", (" + GetSRC(src0) + ").xy)"); break; //TEX
|
case 0x17: AddCode("texture(" + AddTex() + ", " + GetSRC(src0) + ".xy)"); break; //TEX
|
||||||
//case 0x18: break; // TXP
|
//case 0x18: break; // TXP
|
||||||
//case 0x19: break; // TXD
|
//case 0x19: break; // TXD
|
||||||
case 0x1a: AddCode("1 / (" + GetSRC(src0) + ")"); break; // RCP
|
case 0x1a: AddCode("1 / (" + GetSRC(src0) + ")"); break; // RCP
|
||||||
@ -199,7 +237,7 @@ void FragmentDecompilerThread::Task()
|
|||||||
case 0x23: AddCode("sin(" + GetSRC(src0) + ")"); break; // SIN
|
case 0x23: AddCode("sin(" + GetSRC(src0) + ")"); break; // SIN
|
||||||
//case 0x24: break; // PK2
|
//case 0x24: break; // PK2
|
||||||
//case 0x25: break; // UP2
|
//case 0x25: break; // UP2
|
||||||
//case 0x26: break; // POW
|
case 0x26: AddCode("pow(" + GetSRC(src0) + ", " + GetSRC(src1) +")"); break; // POW
|
||||||
//case 0x27: break; // PKB
|
//case 0x27: break; // PKB
|
||||||
//case 0x28: break; // UPB
|
//case 0x28: break; // UPB
|
||||||
//case 0x29: break; // PK16
|
//case 0x29: break; // PK16
|
||||||
@ -218,23 +256,23 @@ void FragmentDecompilerThread::Task()
|
|||||||
//case 0x37: break; // TIMESWTEX
|
//case 0x37: break; // TIMESWTEX
|
||||||
//case 0x38: break; // DP2
|
//case 0x38: break; // DP2
|
||||||
//case 0x39: break; // NRM
|
//case 0x39: break; // NRM
|
||||||
//case 0x3a: break; // DIV
|
case 0x3a: AddCode("(" + GetSRC(src0) + " / " + GetSRC(src1) + ")"); break; // DIV
|
||||||
//case 0x3b: break; // DIVSQ
|
case 0x3b: AddCode("(" + GetSRC(src0) + " / " + GetSRC(src1) + ")"); break; // DIVSQ
|
||||||
//case 0x3c: break; // LIF
|
//case 0x3c: break; // LIF
|
||||||
//case 0x3d: break; // FENCT
|
case 0x3d: break; // FENCT
|
||||||
//case 0x3e: break; // FENCB
|
case 0x3e: break; // FENCB
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ConLog.Error("Unknown opcode 0x%x", dst.opcode);
|
ConLog.Error("Unknown opcode 0x%x (inst %d)", dst.opcode, m_size / (4 * 4));
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_size += 4 * 4;
|
m_size += m_offset;
|
||||||
|
|
||||||
if(dst.end) break;
|
if(dst.end) break;
|
||||||
|
|
||||||
data.SetOffset(4 * 4);
|
data.SetOffset(m_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_shader = BuildCode();
|
m_shader = BuildCode();
|
||||||
|
@ -100,6 +100,7 @@ struct FragmentDecompilerThread : public ThreadBase
|
|||||||
u32 m_addr;
|
u32 m_addr;
|
||||||
u32& m_size;
|
u32& m_size;
|
||||||
u32 m_const_index;
|
u32 m_const_index;
|
||||||
|
u32 m_offset;
|
||||||
|
|
||||||
FragmentDecompilerThread(wxString& shader, ParamArray& parr, u32 addr, u32& size)
|
FragmentDecompilerThread(wxString& shader, ParamArray& parr, u32 addr, u32& size)
|
||||||
: ThreadBase(false, "Fragment Shader Decompiler Thread")
|
: ThreadBase(false, "Fragment Shader Decompiler Thread")
|
||||||
@ -115,7 +116,7 @@ struct FragmentDecompilerThread : public ThreadBase
|
|||||||
wxString GetMask();
|
wxString GetMask();
|
||||||
|
|
||||||
void AddCode(wxString code);
|
void AddCode(wxString code);
|
||||||
wxString AddReg(u32 index);
|
wxString AddReg(u32 index, int fp16);
|
||||||
wxString AddConst();
|
wxString AddConst();
|
||||||
wxString AddTex();
|
wxString AddTex();
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "GLGSRender.h"
|
#include "GLGSRender.h"
|
||||||
#include "Emu/Cell/PPCInstrTable.h"
|
#include "Emu/Cell/PPCInstrTable.h"
|
||||||
#define CMD_DEBUG 1
|
#define CMD_DEBUG 0
|
||||||
#define DUMP_VERTEX_DATA 1
|
#define DUMP_VERTEX_DATA 0
|
||||||
|
|
||||||
#if CMD_DEBUG
|
#if CMD_DEBUG
|
||||||
#define CMD_LOG ConLog.Write
|
#define CMD_LOG ConLog.Write
|
||||||
@ -75,8 +75,8 @@ void GLGSFrame::SetViewport(int x, int y, u32 w, u32 h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLGSRender::GLGSRender()
|
GLGSRender::GLGSRender()
|
||||||
: m_frame(NULL)
|
: m_frame(nullptr)
|
||||||
, m_rsx_thread(NULL)
|
, m_rsx_thread(nullptr)
|
||||||
, m_fp_buf_num(-1)
|
, m_fp_buf_num(-1)
|
||||||
, m_vp_buf_num(-1)
|
, m_vp_buf_num(-1)
|
||||||
{
|
{
|
||||||
@ -122,6 +122,12 @@ void GLRSXThread::Task()
|
|||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0);
|
glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0);
|
||||||
|
|
||||||
|
for(u32 i=0; i<p.m_textures_count; ++i)
|
||||||
|
{
|
||||||
|
GLTexture& tex = p.m_frame->GetTexture(i);
|
||||||
|
tex.Create();
|
||||||
|
}
|
||||||
|
|
||||||
bool draw = true;
|
bool draw = true;
|
||||||
u32 drawed = 0;
|
u32 drawed = 0;
|
||||||
u32 skipped = 0;
|
u32 skipped = 0;
|
||||||
@ -172,7 +178,7 @@ void GLRSXThread::Task()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConLog.Write("addr = 0x%x", p.m_ioAddress + get);
|
//ConLog.Write("addr = 0x%x", p.m_ioAddress + get);
|
||||||
const u32 cmd = Memory.Read32(p.m_ioAddress + get);
|
const u32 cmd = Memory.Read32(p.m_ioAddress + get);
|
||||||
const u32 count = (cmd >> 18) & 0x7ff;
|
const u32 count = (cmd >> 18) & 0x7ff;
|
||||||
//if(cmd == 0) continue;
|
//if(cmd == 0) continue;
|
||||||
@ -251,6 +257,10 @@ void GLGSRender::Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddre
|
|||||||
m_localAddress = localAddress;
|
m_localAddress = localAddress;
|
||||||
m_ctrl = (CellGcmControl*)Memory.GetMemFromAddr(m_ctrlAddress);
|
m_ctrl = (CellGcmControl*)Memory.GetMemFromAddr(m_ctrlAddress);
|
||||||
|
|
||||||
|
m_cur_vertex_prog = nullptr;
|
||||||
|
m_cur_shader_prog = nullptr;
|
||||||
|
m_cur_shader_prog_num = 0;
|
||||||
|
|
||||||
(m_rsx_thread = new GLRSXThread(this))->Start();
|
(m_rsx_thread = new GLRSXThread(this))->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +319,7 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
|
|||||||
wxFile dump("VertexDataArray.dump", wxFile::write);
|
wxFile dump("VertexDataArray.dump", wxFile::write);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(u32 i=0; i<16; ++i)
|
for(u32 i=0; i<m_vertex_count; ++i)
|
||||||
{
|
{
|
||||||
if(!m_vertex_data[i].IsEnabled()) continue;
|
if(!m_vertex_data[i].IsEnabled()) continue;
|
||||||
|
|
||||||
@ -409,7 +419,7 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
|
|||||||
void GLGSRender::DisableVertexData()
|
void GLGSRender::DisableVertexData()
|
||||||
{
|
{
|
||||||
m_vdata.Clear();
|
m_vdata.Clear();
|
||||||
for(u32 i=0; i<16; ++i)
|
for(u32 i=0; i<m_vertex_count; ++i)
|
||||||
{
|
{
|
||||||
if(!m_vertex_data[i].IsEnabled()) continue;
|
if(!m_vertex_data[i].IsEnabled()) continue;
|
||||||
m_vertex_data[i].data.Clear();
|
m_vertex_data[i].data.Clear();
|
||||||
@ -419,7 +429,7 @@ void GLGSRender::DisableVertexData()
|
|||||||
|
|
||||||
void GLGSRender::LoadVertexData(u32 first, u32 count)
|
void GLGSRender::LoadVertexData(u32 first, u32 count)
|
||||||
{
|
{
|
||||||
for(u32 i=0; i<16; ++i)
|
for(u32 i=0; i<m_vertex_count; ++i)
|
||||||
{
|
{
|
||||||
if(!m_vertex_data[i].IsEnabled()) continue;
|
if(!m_vertex_data[i].IsEnabled()) continue;
|
||||||
|
|
||||||
@ -429,11 +439,10 @@ void GLGSRender::LoadVertexData(u32 first, u32 count)
|
|||||||
|
|
||||||
void GLGSRender::InitVertexData()
|
void GLGSRender::InitVertexData()
|
||||||
{
|
{
|
||||||
for(u32 i=0; i<m_cur_vertex_prog->constants4.GetCount(); ++i)
|
for(u32 i=0; i<m_transform_constants.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
const VertexProgram::Constant4& c = m_cur_vertex_prog->constants4[i];
|
const TransformConstant& c = m_transform_constants[i];
|
||||||
const wxString& name = wxString::Format("vc%d", c.id);
|
const wxString& name = wxString::Format("vc%d", c.id);
|
||||||
//const int l = glGetUniformLocation(m_program.id, name);
|
|
||||||
const int l = m_program.GetLocation(name);
|
const int l = m_program.GetLocation(name);
|
||||||
checkForGlError("glGetUniformLocation " + name);
|
checkForGlError("glGetUniformLocation " + name);
|
||||||
|
|
||||||
@ -499,7 +508,9 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
|
|||||||
CMD_LOG("index = %d, offset=0x%x, location=0x%x, cubemap=0x%x, dimension=0x%x, format=0x%x, mipmap=0x%x",
|
CMD_LOG("index = %d, offset=0x%x, location=0x%x, cubemap=0x%x, dimension=0x%x, format=0x%x, mipmap=0x%x",
|
||||||
index, offset, location, cubemap, dimension, format, mipmap);
|
index, offset, location, cubemap, dimension, format, mipmap);
|
||||||
|
|
||||||
tex.SetOffset(GetAddress(offset, location));
|
u32 tex_addr = GetAddress(offset, location);
|
||||||
|
ConLog.Warning("texture addr = 0x%x", tex_addr);
|
||||||
|
tex.SetOffset(tex_addr);
|
||||||
tex.SetFormat(cubemap, dimension, format, mipmap);
|
tex.SetFormat(cubemap, dimension, format, mipmap);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -810,10 +821,11 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
|
|||||||
|
|
||||||
case NV4097_SET_COLOR_CLEAR_VALUE:
|
case NV4097_SET_COLOR_CLEAR_VALUE:
|
||||||
{
|
{
|
||||||
const u8 a = (args[0] >> 24) & 0xff;
|
const u32 color = args[0];
|
||||||
const u8 r = (args[0] >> 16) & 0xff;
|
const u8 a = (color >> 24) & 0xff;
|
||||||
const u8 g = (args[0] >> 8) & 0xff;
|
const u8 r = (color >> 16) & 0xff;
|
||||||
const u8 b = args[0] & 0xff;
|
const u8 g = (color >> 8) & 0xff;
|
||||||
|
const u8 b = color & 0xff;
|
||||||
CMD_LOG("a=%d, r=%d, g=%d, b=%d", a, r, g, b);
|
CMD_LOG("a=%d, r=%d, g=%d, b=%d", a, r, g, b);
|
||||||
glClearColor(
|
glClearColor(
|
||||||
(float)r / 255.0f,
|
(float)r / 255.0f,
|
||||||
@ -825,9 +837,9 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
|
|||||||
|
|
||||||
case NV4097_SET_SHADER_PROGRAM:
|
case NV4097_SET_SHADER_PROGRAM:
|
||||||
{
|
{
|
||||||
m_shader_prog.Delete();
|
m_cur_shader_prog = &m_shader_progs[m_cur_shader_prog_num++];
|
||||||
m_shader_prog.addr = GetAddress(args[0] & ~0x3, (args[0] & 0x3) - 1);
|
m_cur_shader_prog->Delete();
|
||||||
//m_program.Delete();
|
m_cur_shader_prog->addr = GetAddress(args[0] & ~0x3, (args[0] & 0x3) - 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -850,13 +862,14 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
|
|||||||
|
|
||||||
case NV4097_SET_TRANSFORM_PROGRAM_LOAD:
|
case NV4097_SET_TRANSFORM_PROGRAM_LOAD:
|
||||||
{
|
{
|
||||||
//m_program.Delete();
|
|
||||||
m_cur_vertex_prog = &m_vertex_progs[args[0]];
|
m_cur_vertex_prog = &m_vertex_progs[args[0]];
|
||||||
m_cur_vertex_prog->Delete();
|
m_cur_vertex_prog->Delete();
|
||||||
|
|
||||||
if(count == 2)
|
if(count == 2)
|
||||||
{
|
{
|
||||||
const u32 start = args[1];
|
const u32 start = args[1];
|
||||||
|
if(start)
|
||||||
|
ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM_LOAD: start = %d", start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -899,12 +912,6 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!m_cur_vertex_prog)
|
|
||||||
{
|
|
||||||
ConLog.Warning("NV4097_SET_TRANSFORM_CONSTANT_LOAD: m_cur_vertex_prog == NULL");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(u32 id = args[0], i = 1; i<count; ++id)
|
for(u32 id = args[0], i = 1; i<count; ++id)
|
||||||
{
|
{
|
||||||
const u32 x = args[i++];
|
const u32 x = args[i++];
|
||||||
@ -912,15 +919,10 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
|
|||||||
const u32 z = args[i++];
|
const u32 z = args[i++];
|
||||||
const u32 w = args[i++];
|
const u32 w = args[i++];
|
||||||
|
|
||||||
VertexProgram::Constant4 c;
|
TransformConstant c(id, (float&)x, (float&)y, (float&)z, (float&)w);
|
||||||
c.id = id;
|
|
||||||
c.x = (float&)x;
|
|
||||||
c.y = (float&)y;
|
|
||||||
c.z = (float&)z;
|
|
||||||
c.w = (float&)w;
|
|
||||||
|
|
||||||
CMD_LOG("SET_TRANSFORM_CONSTANT_LOAD[%d : %d] = (%f, %f, %f, %f)", i, id, c.x, c.y, c.z, c.w);
|
CMD_LOG("SET_TRANSFORM_CONSTANT_LOAD[%d : %d] = (%f, %f, %f, %f)", i, id, c.x, c.y, c.z, c.w);
|
||||||
m_cur_vertex_prog->constants4.AddCpy(c);
|
m_transform_constants.AddCpy(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1154,13 +1156,20 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
|
|||||||
|
|
||||||
bool GLGSRender::LoadProgram()
|
bool GLGSRender::LoadProgram()
|
||||||
{
|
{
|
||||||
m_fp_buf_num = m_prog_buffer.SearchFp(m_shader_prog);
|
if(!m_cur_shader_prog)
|
||||||
|
{
|
||||||
|
ConLog.Warning("LoadProgram: m_cur_shader_prog == NULL");
|
||||||
|
|
||||||
if(m_fp_buf_num == -1) m_shader_prog.Decompile();
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fp_buf_num = m_prog_buffer.SearchFp(*m_cur_shader_prog);
|
||||||
|
|
||||||
|
if(m_fp_buf_num == -1) m_cur_shader_prog->Decompile();
|
||||||
|
|
||||||
if(!m_cur_vertex_prog)
|
if(!m_cur_vertex_prog)
|
||||||
{
|
{
|
||||||
ConLog.Warning("NV4097_SET_BEGIN_END: m_cur_vertex_prog == NULL");
|
ConLog.Warning("LoadProgram: m_cur_vertex_prog == NULL");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1182,11 +1191,11 @@ bool GLGSRender::LoadProgram()
|
|||||||
if(m_fp_buf_num == -1)
|
if(m_fp_buf_num == -1)
|
||||||
{
|
{
|
||||||
ConLog.Warning("FP not found in buffer!");
|
ConLog.Warning("FP not found in buffer!");
|
||||||
m_shader_prog.Wait();
|
m_cur_shader_prog->Wait();
|
||||||
m_shader_prog.Compile();
|
m_cur_shader_prog->Compile();
|
||||||
|
|
||||||
wxFile f(wxGetCwd() + "/FragmentProgram.txt", wxFile::write);
|
wxFile f(wxGetCwd() + "/FragmentProgram.txt", wxFile::write);
|
||||||
f.Write(m_shader_prog.shader);
|
f.Write(m_cur_shader_prog->shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_vp_buf_num == -1)
|
if(m_vp_buf_num == -1)
|
||||||
@ -1203,10 +1212,14 @@ bool GLGSRender::LoadProgram()
|
|||||||
m_program.id = m_prog_buffer.GetProg(m_fp_buf_num, m_vp_buf_num);
|
m_program.id = m_prog_buffer.GetProg(m_fp_buf_num, m_vp_buf_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!m_program.id)
|
if(m_program.id)
|
||||||
{
|
{
|
||||||
m_program.Create(m_cur_vertex_prog->id, m_shader_prog.id);
|
m_program.Use();
|
||||||
m_prog_buffer.Add(m_program, m_shader_prog, *m_cur_vertex_prog);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_program.Create(m_cur_vertex_prog->id, m_cur_shader_prog->id);
|
||||||
|
m_prog_buffer.Add(m_program, *m_cur_shader_prog, *m_cur_vertex_prog);
|
||||||
|
|
||||||
m_program.Use();
|
m_program.Use();
|
||||||
|
|
||||||
@ -1270,7 +1283,12 @@ void GLGSRender::ExecCMD()
|
|||||||
glDepthRangef(m_clip_min, m_clip_max);
|
glDepthRangef(m_clip_min, m_clip_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(u32 i=0; i<16; ++i)
|
if(m_indexed_array.m_count && m_draw_array_count)
|
||||||
|
{
|
||||||
|
ConLog.Warning("m_indexed_array.m_count && draw_array_count");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(u32 i=0; i<m_textures_count; ++i)
|
||||||
{
|
{
|
||||||
GLTexture& tex = m_frame->GetTexture(i);
|
GLTexture& tex = m_frame->GetTexture(i);
|
||||||
if(!tex.IsEnabled()) continue;
|
if(!tex.IsEnabled()) continue;
|
||||||
@ -1280,17 +1298,11 @@ void GLGSRender::ExecCMD()
|
|||||||
tex.Bind();
|
tex.Bind();
|
||||||
checkForGlError("tex.Bind");
|
checkForGlError("tex.Bind");
|
||||||
m_program.SetTex(i);
|
m_program.SetTex(i);
|
||||||
checkForGlError("m_program.SetTex");
|
|
||||||
tex.Init();
|
tex.Init();
|
||||||
checkForGlError("tex.Init");
|
checkForGlError("tex.Init");
|
||||||
tex.Save();
|
tex.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_indexed_array.m_count && m_draw_array_count)
|
|
||||||
{
|
|
||||||
ConLog.Warning("m_indexed_array.m_count && draw_array_count");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_indexed_array.m_count)
|
if(m_indexed_array.m_count)
|
||||||
{
|
{
|
||||||
LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1);
|
LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1);
|
||||||
@ -1347,13 +1359,20 @@ void GLGSRender::ExecCMD()
|
|||||||
|
|
||||||
void GLGSRender::Reset()
|
void GLGSRender::Reset()
|
||||||
{
|
{
|
||||||
m_program.Delete();
|
m_program.UnUse();
|
||||||
//m_program.id = 0;
|
|
||||||
m_shader_prog.id = 0;
|
if(m_cur_shader_prog)
|
||||||
|
m_cur_shader_prog->id = 0;
|
||||||
|
|
||||||
if(m_cur_vertex_prog)
|
if(m_cur_vertex_prog)
|
||||||
m_cur_vertex_prog->id = 0;
|
m_cur_vertex_prog->id = 0;
|
||||||
|
|
||||||
memset(m_vertex_data, 0, sizeof(VertexData) * 16);
|
m_cur_shader_prog_num = 0;
|
||||||
|
m_transform_constants.Clear();
|
||||||
|
for(uint i=0; i<m_vertex_count; ++i)
|
||||||
|
{
|
||||||
|
m_vertex_data[i].Reset();
|
||||||
|
}
|
||||||
|
|
||||||
if(m_vbo.IsCreated())
|
if(m_vbo.IsCreated())
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,20 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Create()
|
||||||
|
{
|
||||||
|
if(!m_id)
|
||||||
|
{
|
||||||
|
glGenTextures(1, &m_id);
|
||||||
|
checkForGlError("GLTexture::Init() -> glGenTextures");
|
||||||
|
Bind();
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SetRect(const u32 width, const u32 height)
|
void SetRect(const u32 width, const u32 height)
|
||||||
{
|
{
|
||||||
m_width = width;
|
m_width = width;
|
||||||
@ -68,21 +82,8 @@ public:
|
|||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
if(!m_id)
|
Bind();
|
||||||
{
|
ConLog.Warning("texture addr = 0x%x, width = %d, height = %d", m_offset, m_width, m_height);
|
||||||
glGenTextures(1, &m_id);
|
|
||||||
checkForGlError("GLTexture::Init() -> glGenTextures");
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_id);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: safe init
|
//TODO: safe init
|
||||||
checkForGlError("GLTexture::Init() -> glBindTexture");
|
checkForGlError("GLTexture::Init() -> glBindTexture");
|
||||||
|
|
||||||
@ -106,18 +107,17 @@ public:
|
|||||||
default: ConLog.Error("Init tex error: Bad tex format (0x%x)", m_format); break;
|
default: ConLog.Error("Init tex error: Bad tex format (0x%x)", m_format); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//glBindTexture(GL_TEXTURE_2D, 0);
|
//Unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Save(const wxString& name)
|
void Save(const wxString& name)
|
||||||
{
|
{
|
||||||
if(!m_id || !m_offset) return;
|
if(!m_id || !m_offset) return;
|
||||||
|
|
||||||
ConLog.Write("start");
|
|
||||||
u32* alldata = new u32[m_width * m_height];
|
u32* alldata = new u32[m_width * m_height];
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_id);
|
Bind();
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, alldata);
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, alldata);
|
||||||
|
|
||||||
u8* data = new u8[m_width * m_height * 3];
|
u8* data = new u8[m_width * m_height * 3];
|
||||||
u8* alpha = new u8[m_width * m_height];
|
u8* alpha = new u8[m_width * m_height];
|
||||||
@ -133,7 +133,6 @@ public:
|
|||||||
*dst_a++ = *src++;
|
*dst_a++ = *src++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConLog.Write("end");
|
|
||||||
wxImage out;
|
wxImage out;
|
||||||
out.Create(m_width, m_height, data, alpha);
|
out.Create(m_width, m_height, data, alpha);
|
||||||
out.SaveFile(name, wxBITMAP_TYPE_PNG);
|
out.SaveFile(name, wxBITMAP_TYPE_PNG);
|
||||||
@ -160,10 +159,34 @@ public:
|
|||||||
glBindTexture(GL_TEXTURE_2D, m_id);
|
glBindTexture(GL_TEXTURE_2D, m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Unbind()
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void Enable(bool enable) { m_enabled = enable; }
|
void Enable(bool enable) { m_enabled = enable; }
|
||||||
bool IsEnabled() const { return m_enabled; }
|
bool IsEnabled() const { return m_enabled; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TransformConstant
|
||||||
|
{
|
||||||
|
u32 id;
|
||||||
|
float x, y, z, w;
|
||||||
|
|
||||||
|
TransformConstant()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TransformConstant(u32 id, float x, float y, float z, float w)
|
||||||
|
: id(id)
|
||||||
|
, x(x)
|
||||||
|
, y(y)
|
||||||
|
, z(z)
|
||||||
|
, w(w)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct IndexArrayData
|
struct IndexArrayData
|
||||||
{
|
{
|
||||||
Array<u8> m_data;
|
Array<u8> m_data;
|
||||||
@ -228,16 +251,25 @@ class GLGSRender
|
|||||||
, public GSRender
|
, public GSRender
|
||||||
, public ExecRSXCMDdata
|
, public ExecRSXCMDdata
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
static const uint m_vertex_count = 16;
|
||||||
|
static const uint m_fragment_count = 16;
|
||||||
|
static const uint m_textures_count = 16;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLRSXThread* m_rsx_thread;
|
GLRSXThread* m_rsx_thread;
|
||||||
|
|
||||||
IndexArrayData m_indexed_array;
|
IndexArrayData m_indexed_array;
|
||||||
|
|
||||||
ShaderProgram m_shader_prog;
|
ShaderProgram m_shader_progs[m_fragment_count];
|
||||||
VertexData m_vertex_data[16];
|
ShaderProgram* m_cur_shader_prog;
|
||||||
|
int m_cur_shader_prog_num;
|
||||||
|
VertexData m_vertex_data[m_vertex_count];
|
||||||
Array<u8> m_vdata;
|
Array<u8> m_vdata;
|
||||||
VertexProgram m_vertex_progs[16];
|
VertexProgram m_vertex_progs[m_vertex_count];
|
||||||
VertexProgram* m_cur_vertex_prog;
|
VertexProgram* m_cur_vertex_prog;
|
||||||
|
Array<TransformConstant> m_transform_constants;
|
||||||
|
|
||||||
Program m_program;
|
Program m_program;
|
||||||
int m_fp_buf_num;
|
int m_fp_buf_num;
|
||||||
int m_vp_buf_num;
|
int m_vp_buf_num;
|
||||||
|
@ -19,7 +19,9 @@ int Program::GetLocation(const wxString& name)
|
|||||||
u32 pos = m_locations.Move(new Location());
|
u32 pos = m_locations.Move(new Location());
|
||||||
m_locations[pos].name = name;
|
m_locations[pos].name = name;
|
||||||
|
|
||||||
return m_locations[pos].loc = glGetUniformLocation(id, name);
|
m_locations[pos].loc = glGetUniformLocation(id, name);
|
||||||
|
checkForGlError(wxString::Format("glGetUniformLocation(0x%x, %s)", id, name));
|
||||||
|
return m_locations[pos].loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Program::IsCreated() const
|
bool Program::IsCreated() const
|
||||||
@ -72,6 +74,11 @@ void Program::Create(const u32 vp, const u32 fp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Program::UnUse()
|
||||||
|
{
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Program::Use()
|
void Program::Use()
|
||||||
{
|
{
|
||||||
glUseProgram(id);
|
glUseProgram(id);
|
||||||
@ -80,8 +87,10 @@ void Program::Use()
|
|||||||
|
|
||||||
void Program::SetTex(u32 index)
|
void Program::SetTex(u32 index)
|
||||||
{
|
{
|
||||||
glUniform1i(GetLocation(wxString::Format("tex_%d", index)), index);
|
int loc = GetLocation(wxString::Format("tex%d", index));
|
||||||
checkForGlError(wxString::Format("SetTex(%d)", index));
|
checkForGlError(wxString::Format("GetLocation(tex%d)", index));
|
||||||
|
glUniform1i(loc, index);
|
||||||
|
checkForGlError(wxString::Format("SetTex(%d - %d)", index, loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Program::Delete()
|
void Program::Delete()
|
||||||
|
@ -22,6 +22,7 @@ public:
|
|||||||
bool IsCreated() const;
|
bool IsCreated() const;
|
||||||
void Create(const u32 vp, const u32 fp);
|
void Create(const u32 vp, const u32 fp);
|
||||||
void Use();
|
void Use();
|
||||||
|
void UnUse();
|
||||||
void SetTex(u32 index);
|
void SetTex(u32 index);
|
||||||
void Delete();
|
void Delete();
|
||||||
};
|
};
|
@ -8,7 +8,7 @@ int ProgramBuffer::SearchFp(ShaderProgram& fp)
|
|||||||
if(memcmp(&m_buf[i].fp_data[0], &Memory[fp.addr], m_buf[i].fp_data.GetCount()) != 0) continue;
|
if(memcmp(&m_buf[i].fp_data[0], &Memory[fp.addr], m_buf[i].fp_data.GetCount()) != 0) continue;
|
||||||
|
|
||||||
fp.id = m_buf[i].fp_id;
|
fp.id = m_buf[i].fp_id;
|
||||||
fp.shader = m_buf[i].fp_shader;
|
fp.shader = m_buf[i].fp_shader.GetPtr();
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -21,10 +21,10 @@ int ProgramBuffer::SearchVp(VertexProgram& vp)
|
|||||||
for(u32 i=0; i<m_buf.GetCount(); ++i)
|
for(u32 i=0; i<m_buf.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
if(m_buf[i].vp_data.GetCount() != vp.data.GetCount()) continue;
|
if(m_buf[i].vp_data.GetCount() != vp.data.GetCount()) continue;
|
||||||
if(memcmp(&m_buf[i].vp_data[0], &vp.data[0], vp.data.GetCount() * 4) != 0) continue;
|
if(memcmp(m_buf[i].vp_data.GetPtr(), vp.data.GetPtr(), vp.data.GetCount() * 4) != 0) continue;
|
||||||
|
|
||||||
vp.id = m_buf[i].vp_id;
|
vp.id = m_buf[i].vp_id;
|
||||||
vp.shader = m_buf[i].vp_shader;
|
vp.shader = m_buf[i].vp_shader.GetPtr();
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -35,18 +35,30 @@ int ProgramBuffer::SearchVp(VertexProgram& vp)
|
|||||||
bool ProgramBuffer::CmpVP(const u32 a, const u32 b) const
|
bool ProgramBuffer::CmpVP(const u32 a, const u32 b) const
|
||||||
{
|
{
|
||||||
if(m_buf[a].vp_data.GetCount() != m_buf[b].vp_data.GetCount()) return false;
|
if(m_buf[a].vp_data.GetCount() != m_buf[b].vp_data.GetCount()) return false;
|
||||||
return memcmp(&m_buf[a].vp_data[0], &m_buf[b].vp_data[0], m_buf[a].vp_data.GetCount() * 4) == 0;
|
return memcmp(m_buf[a].vp_data.GetPtr(), m_buf[b].vp_data.GetPtr(), m_buf[a].vp_data.GetCount() * 4) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProgramBuffer::CmpFP(const u32 a, const u32 b) const
|
bool ProgramBuffer::CmpFP(const u32 a, const u32 b) const
|
||||||
{
|
{
|
||||||
if(m_buf[a].fp_data.GetCount() != m_buf[b].fp_data.GetCount()) return false;
|
if(m_buf[a].fp_data.GetCount() != m_buf[b].fp_data.GetCount()) return false;
|
||||||
return memcmp(&m_buf[a].fp_data[0], &m_buf[b].fp_data[0], m_buf[a].fp_data.GetCount()) == 0;
|
return memcmp(m_buf[a].fp_data.GetPtr(), m_buf[b].fp_data.GetPtr(), m_buf[a].fp_data.GetCount()) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ProgramBuffer::GetProg(u32 fp, u32 vp) const
|
u32 ProgramBuffer::GetProg(u32 fp, u32 vp) const
|
||||||
{
|
{
|
||||||
if(fp == vp) return m_buf[fp].prog_id;
|
if(fp == vp)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
ConLog.Write("Get program (%d):", fp);
|
||||||
|
ConLog.Write("*** prog id = %d", m_buf[fp].prog_id);
|
||||||
|
ConLog.Write("*** vp id = %d", m_buf[fp].vp_id);
|
||||||
|
ConLog.Write("*** fp id = %d", m_buf[fp].fp_id);
|
||||||
|
|
||||||
|
ConLog.Write("*** vp shader = \n%s", m_buf[fp].vp_shader);
|
||||||
|
ConLog.Write("*** fp shader = \n%s", m_buf[fp].fp_shader);
|
||||||
|
*/
|
||||||
|
return m_buf[fp].prog_id;
|
||||||
|
}
|
||||||
|
|
||||||
for(u32 i=0; i<m_buf.GetCount(); ++i)
|
for(u32 i=0; i<m_buf.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
@ -54,13 +66,15 @@ u32 ProgramBuffer::GetProg(u32 fp, u32 vp) const
|
|||||||
|
|
||||||
if(CmpVP(vp, i) && CmpFP(fp, i))
|
if(CmpVP(vp, i) && CmpFP(fp, i))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
ConLog.Write("Get program (%d):", i);
|
ConLog.Write("Get program (%d):", i);
|
||||||
ConLog.Write("*** prog id = %d", m_buf[i].prog_id);
|
ConLog.Write("*** prog id = %d", m_buf[i].prog_id);
|
||||||
ConLog.Write("*** vp id = %d", m_buf[i].vp_id);
|
ConLog.Write("*** vp id = %d", m_buf[i].vp_id);
|
||||||
ConLog.Write("*** fp id = %d", m_buf[i].fp_id);
|
ConLog.Write("*** fp id = %d", m_buf[i].fp_id);
|
||||||
|
|
||||||
ConLog.Write("*** vp shader = %s\n", m_buf[i].vp_shader);
|
ConLog.Write("*** vp shader = \n%s", m_buf[i].vp_shader);
|
||||||
ConLog.Write("*** fp shader = %s\n", m_buf[i].fp_shader);
|
ConLog.Write("*** fp shader = \n%s", m_buf[i].fp_shader);
|
||||||
|
*/
|
||||||
return m_buf[i].prog_id;
|
return m_buf[i].prog_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,8 +93,8 @@ void ProgramBuffer::Add(Program& prog, ShaderProgram& fp, VertexProgram& vp)
|
|||||||
ConLog.Write("*** vp data size = %d", vp.data.GetCount() * 4);
|
ConLog.Write("*** vp data size = %d", vp.data.GetCount() * 4);
|
||||||
ConLog.Write("*** fp data size = %d", fp.size);
|
ConLog.Write("*** fp data size = %d", fp.size);
|
||||||
|
|
||||||
ConLog.Write("*** vp shader = %s\n", vp.shader);
|
ConLog.Write("*** vp shader = \n%s", vp.shader);
|
||||||
ConLog.Write("*** fp shader = %s\n", fp.shader);
|
ConLog.Write("*** fp shader = \n%s", fp.shader);
|
||||||
|
|
||||||
new_buf.prog_id = prog.id;
|
new_buf.prog_id = prog.id;
|
||||||
new_buf.vp_id = vp.id;
|
new_buf.vp_id = vp.id;
|
||||||
|
@ -8,8 +8,8 @@ struct BufferInfo
|
|||||||
u32 vp_id;
|
u32 vp_id;
|
||||||
Array<u8> fp_data;
|
Array<u8> fp_data;
|
||||||
Array<u32> vp_data;
|
Array<u32> vp_data;
|
||||||
wxString fp_shader;
|
ArrayString fp_shader;
|
||||||
wxString vp_shader;
|
ArrayString vp_shader;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProgramBuffer
|
struct ProgramBuffer
|
||||||
|
@ -5,18 +5,21 @@ enum ParamFlag
|
|||||||
{
|
{
|
||||||
PARAM_IN,
|
PARAM_IN,
|
||||||
PARAM_OUT,
|
PARAM_OUT,
|
||||||
|
PARAM_UNIFORM,
|
||||||
PARAM_CONST,
|
PARAM_CONST,
|
||||||
PARAM_NONE,
|
PARAM_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParamItem
|
struct ParamItem
|
||||||
{
|
{
|
||||||
wxString name;
|
ArrayString name;
|
||||||
wxString location;
|
ArrayString location;
|
||||||
|
ArrayString value;
|
||||||
|
|
||||||
ParamItem(const wxString& _name, int _location)
|
ParamItem(const wxString& _name, int _location, const wxString& _value = wxEmptyString)
|
||||||
: name(_name)
|
: name(_name)
|
||||||
, location(_location > -1 ? wxString::Format("layout (location = %d) ", _location) : "")
|
, location(_location > -1 ? wxString::Format("layout (location = %d) ", _location) : "")
|
||||||
|
, value(_value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -24,7 +27,7 @@ struct ParamItem
|
|||||||
struct ParamType
|
struct ParamType
|
||||||
{
|
{
|
||||||
const ParamFlag flag;
|
const ParamFlag flag;
|
||||||
wxString type;
|
ArrayString type;
|
||||||
Array<ParamItem> items;
|
Array<ParamItem> items;
|
||||||
|
|
||||||
ParamType(const ParamFlag _flag, const wxString& _type)
|
ParamType(const ParamFlag _flag, const wxString& _type)
|
||||||
@ -37,7 +40,7 @@ struct ParamType
|
|||||||
{
|
{
|
||||||
for(u32 i=0; i<items.GetCount(); ++i)
|
for(u32 i=0; i<items.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
if(items[i].name.Cmp(name) == 0) return true;
|
if(name.Cmp(items[i].name.GetPtr()) == 0) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -49,10 +52,15 @@ struct ParamType
|
|||||||
|
|
||||||
for(u32 n=0; n<items.GetCount(); ++n)
|
for(u32 n=0; n<items.GetCount(); ++n)
|
||||||
{
|
{
|
||||||
ret += items[n].location;
|
ret += items[n].location.GetPtr();
|
||||||
ret += type;
|
ret += type.GetPtr();
|
||||||
ret += " ";
|
ret += " ";
|
||||||
ret += items[n].name;
|
ret += items[n].name.GetPtr();
|
||||||
|
if(items[n].value.GetCount())
|
||||||
|
{
|
||||||
|
ret += " = ";
|
||||||
|
ret += items[n].value.GetPtr();
|
||||||
|
}
|
||||||
ret += ";\n";
|
ret += ";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,10 +76,10 @@ struct ParamArray
|
|||||||
{
|
{
|
||||||
for(u32 i=0; i<params.GetCount(); ++i)
|
for(u32 i=0; i<params.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
if(params[i].type.Cmp(type) == 0) return ¶ms[i];
|
if(type.Cmp(params[i].type.GetPtr()) == 0) return ¶ms[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString GetParamFlag(const ParamFlag flag)
|
wxString GetParamFlag(const ParamFlag flag)
|
||||||
@ -80,12 +88,32 @@ struct ParamArray
|
|||||||
{
|
{
|
||||||
case PARAM_OUT: return "out ";
|
case PARAM_OUT: return "out ";
|
||||||
case PARAM_IN: return "in ";
|
case PARAM_IN: return "in ";
|
||||||
case PARAM_CONST: return "uniform ";
|
case PARAM_UNIFORM: return "uniform ";
|
||||||
|
case PARAM_CONST: return "const ";
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxEmptyString;
|
return wxEmptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString AddParam(wxString type, const wxString& name, const wxString& value)
|
||||||
|
{
|
||||||
|
type = GetParamFlag(PARAM_CONST) + type;
|
||||||
|
ParamType* t = SearchParam(type);
|
||||||
|
|
||||||
|
if(t)
|
||||||
|
{
|
||||||
|
if(!t->SearchName(name)) t->items.Move(new ParamItem(name, -1, value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const u32 num = params.GetCount();
|
||||||
|
params.Move(new ParamType(PARAM_CONST, type));
|
||||||
|
params[num].items.Move(new ParamItem(name, -1, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
wxString AddParam(const ParamFlag flag, wxString type, const wxString& name, int location = -1)
|
wxString AddParam(const ParamFlag flag, wxString type, const wxString& name, int location = -1)
|
||||||
{
|
{
|
||||||
type = GetParamFlag(flag) + type;
|
type = GetParamFlag(flag) + type;
|
||||||
|
@ -1,28 +1,36 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "VertexProgram.h"
|
#include "VertexProgram.h"
|
||||||
|
|
||||||
wxString VertexDecompilerThread::GetVecMask()
|
wxString VertexDecompilerThread::GetMask(bool is_sca)
|
||||||
{
|
{
|
||||||
wxString ret = wxEmptyString;
|
wxString ret = wxEmptyString;
|
||||||
|
|
||||||
if(d3.vec_writemask_x) ret += "x";
|
if(is_sca)
|
||||||
if(d3.vec_writemask_y) ret += "y";
|
{
|
||||||
if(d3.vec_writemask_z) ret += "z";
|
if(d3.sca_writemask_x) ret += "x";
|
||||||
if(d3.vec_writemask_w) ret += "w";
|
if(d3.sca_writemask_y) ret += "y";
|
||||||
|
if(d3.sca_writemask_z) ret += "z";
|
||||||
|
if(d3.sca_writemask_w) ret += "w";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(d3.vec_writemask_x) ret += "x";
|
||||||
|
if(d3.vec_writemask_y) ret += "y";
|
||||||
|
if(d3.vec_writemask_z) ret += "z";
|
||||||
|
if(d3.vec_writemask_w) ret += "w";
|
||||||
|
}
|
||||||
|
|
||||||
return ret.IsEmpty() || ret == "xyzw" ? wxEmptyString : ("." + ret);
|
return ret.IsEmpty() || ret == "xyzw" ? wxEmptyString : ("." + ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString VertexDecompilerThread::GetVecMask()
|
||||||
|
{
|
||||||
|
return GetMask(false);
|
||||||
|
}
|
||||||
|
|
||||||
wxString VertexDecompilerThread::GetScaMask()
|
wxString VertexDecompilerThread::GetScaMask()
|
||||||
{
|
{
|
||||||
wxString ret = wxEmptyString;
|
return GetMask(true);
|
||||||
|
|
||||||
if(d3.sca_writemask_x) ret += "x";
|
|
||||||
if(d3.sca_writemask_y) ret += "y";
|
|
||||||
if(d3.sca_writemask_z) ret += "z";
|
|
||||||
if(d3.sca_writemask_w) ret += "w";
|
|
||||||
|
|
||||||
return ret.IsEmpty() || ret == "xyzw" ? wxEmptyString : ("." + ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString VertexDecompilerThread::GetDST(bool isSca)
|
wxString VertexDecompilerThread::GetDST(bool isSca)
|
||||||
@ -38,26 +46,25 @@ wxString VertexDecompilerThread::GetDST(bool isSca)
|
|||||||
};
|
};
|
||||||
|
|
||||||
wxString ret = wxEmptyString;
|
wxString ret = wxEmptyString;
|
||||||
u32 dst = isSca ? d3.sca_dst : d3.dst;
|
|
||||||
|
|
||||||
switch(dst)
|
switch(isSca ? 0x1f : d3.dst)
|
||||||
{
|
{
|
||||||
case 0x0: case 0x6:
|
case 0x0: case 0x6:
|
||||||
ret += reg_table[dst];
|
ret += reg_table[d3.dst];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1f:
|
case 0x1f:
|
||||||
ret += m_parr.AddParam(PARAM_NONE, "vec4", wxString::Format("tmp%d", d0.dst_tmp));
|
ret += m_parr.AddParam(PARAM_NONE, "vec4", wxString::Format("tmp%d", isSca ? d3.sca_dst_tmp : d0.dst_tmp));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if(dst < WXSIZEOF(reg_table))
|
if(d3.dst < WXSIZEOF(reg_table))
|
||||||
{
|
{
|
||||||
ret += m_parr.AddParam(PARAM_OUT, "vec4", reg_table[dst]);
|
ret += m_parr.AddParam(PARAM_OUT, "vec4", reg_table[d3.dst]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ConLog.Error("Bad dst reg num: %d", dst);
|
ConLog.Error("Bad dst reg num: %d", d3.dst);
|
||||||
ret += m_parr.AddParam(PARAM_OUT, "vec4", "unk");
|
ret += m_parr.AddParam(PARAM_OUT, "vec4", "unk");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -97,7 +104,7 @@ wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: //const
|
case 3: //const
|
||||||
ret += m_parr.AddParam(PARAM_CONST, "vec4", wxString::Format("vc%d", d1.const_src));
|
ret += m_parr.AddParam(PARAM_UNIFORM, "vec4", wxString::Format("vc%d", d1.const_src));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -106,8 +113,7 @@ wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char f[4] = {'x', 'z', 'w', 'y'};
|
static const char f[4] = {'x', 'y', 'z', 'w'};
|
||||||
static const char fSca[4] = {'x', 'z', 'y', 'w'};
|
|
||||||
|
|
||||||
wxString swizzle = wxEmptyString;
|
wxString swizzle = wxEmptyString;
|
||||||
|
|
||||||
@ -117,7 +123,7 @@ wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca)
|
|||||||
assert(src[n].swz_z == src[n].swz_w);
|
assert(src[n].swz_z == src[n].swz_w);
|
||||||
assert(src[n].swz_x == src[n].swz_z);
|
assert(src[n].swz_x == src[n].swz_z);
|
||||||
|
|
||||||
ret += "." + fSca[src[n].swz_x];
|
ret += "." + f[src[n].swz_x];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -144,34 +150,50 @@ wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexDecompilerThread::AddVecCode(wxString code, bool src_mask)
|
void VertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask)
|
||||||
{
|
{
|
||||||
if(d0.cond == 0) return;
|
if(d0.cond == 0) return;
|
||||||
if(d0.cond != 7)
|
enum
|
||||||
{
|
{
|
||||||
ConLog.Error("Bad cond! %d", d0.cond);
|
lt = 0x1,
|
||||||
Emu.Pause();
|
eq = 0x2,
|
||||||
return;
|
gt = 0x4,
|
||||||
|
};
|
||||||
|
|
||||||
|
wxString cond;
|
||||||
|
|
||||||
|
if(d0.cond != (lt | gt | eq))
|
||||||
|
{
|
||||||
|
if(d0.cond & (lt | gt))
|
||||||
|
{
|
||||||
|
cond = "!=";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(d0.cond & lt) cond = "<";
|
||||||
|
else if(d0.cond & gt) cond = ">";
|
||||||
|
else if(d0.cond & eq) cond = "=";
|
||||||
|
|
||||||
|
if(d0.cond & eq) cond += "=";
|
||||||
|
}
|
||||||
|
|
||||||
|
ConLog.Error("cond! %d (%d %s %d %d)", d0.cond, d0.dst_tmp, cond, d1.input_src, d1.const_src);
|
||||||
|
cond = wxString::Format("if(tmp%d.x %s 0) ", d0.dst_tmp, cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
code = GetDST() + GetVecMask() + " = " + (src_mask ? code + GetVecMask() : code);
|
code = cond + GetDST(is_sca) + GetMask(is_sca) + " = " + (src_mask ? code + GetMask(is_sca) : code);
|
||||||
|
|
||||||
main += "\t" + code + ";\n";
|
main += "\t" + code + ";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexDecompilerThread::AddScaCode(wxString code, bool src_mask)
|
void VertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask)
|
||||||
{
|
{
|
||||||
if(d0.cond == 0) return;
|
AddCode(false, code, src_mask);
|
||||||
if(d0.cond != 7)
|
}
|
||||||
{
|
|
||||||
ConLog.Error("Bad cond! %d", d0.cond);
|
|
||||||
Emu.Pause();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
code = GetDST(true) + GetScaMask() + " = " + (src_mask ? code + GetScaMask() : code);
|
void VertexDecompilerThread::AddScaCode(const wxString& code, bool src_mask)
|
||||||
|
{
|
||||||
main += "\t" + code + ";\n";
|
AddCode(true, code, src_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString VertexDecompilerThread::BuildCode()
|
wxString VertexDecompilerThread::BuildCode()
|
||||||
@ -201,16 +223,18 @@ void VertexDecompilerThread::Task()
|
|||||||
d2.HEX = m_data[i++];
|
d2.HEX = m_data[i++];
|
||||||
d3.HEX = m_data[i++];
|
d3.HEX = m_data[i++];
|
||||||
|
|
||||||
src[0].HEX = d2.src0l | (d1.src0h << 9);
|
src[0].src0l = d2.src0l;
|
||||||
src[1].HEX = d2.src1;
|
src[0].src0h = d1.src0h;
|
||||||
src[2].HEX = d3.src2l | (d2.src2h << 11);
|
src[1].src1 = d2.src1;
|
||||||
|
src[2].src2l = d3.src2l;
|
||||||
|
src[2].src2h = d2.src2h;
|
||||||
|
|
||||||
switch(d1.sca_opcode)
|
switch(d1.sca_opcode)
|
||||||
{
|
{
|
||||||
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 / (" + 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 / (" + 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
|
||||||
@ -229,7 +253,6 @@ void VertexDecompilerThread::Task()
|
|||||||
//case 0x13: break; // PSH : works differently (PSH o[1].x A0;)
|
//case 0x13: break; // PSH : works differently (PSH o[1].x A0;)
|
||||||
//case 0x14: break; // POP : works differently (POP o[1].x;)
|
//case 0x14: break; // POP : works differently (POP o[1].x;)
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ConLog.Error("Unknown vp sca_opcode 0x%x", d1.sca_opcode);
|
ConLog.Error("Unknown vp sca_opcode 0x%x", d1.sca_opcode);
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
@ -241,7 +264,7 @@ void VertexDecompilerThread::Task()
|
|||||||
case 0x00: break; //NOP
|
case 0x00: break; //NOP
|
||||||
case 0x01: AddVecCode(GetSRC(0)); break; //MOV
|
case 0x01: AddVecCode(GetSRC(0)); break; //MOV
|
||||||
case 0x02: AddVecCode("(" + GetSRC(0) + " * " + GetSRC(1) + ")"); break; //MUL
|
case 0x02: AddVecCode("(" + GetSRC(0) + " * " + GetSRC(1) + ")"); break; //MUL
|
||||||
case 0x03: AddVecCode("(" + GetSRC(0) + " + " + GetSRC(1) + ")"); break; //ADD
|
case 0x03: AddVecCode("(" + GetSRC(0) + " + " + GetSRC(2) + ")"); break; //ADD
|
||||||
case 0x04: AddVecCode("(" + GetSRC(0) + " * " + GetSRC(1) + " + " + GetSRC(2) + ")"); break; //MAD
|
case 0x04: AddVecCode("(" + GetSRC(0) + " * " + GetSRC(1) + " + " + GetSRC(2) + ")"); break; //MAD
|
||||||
case 0x05: AddVecCode("dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz)", false); break; //DP3
|
case 0x05: AddVecCode("dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz)", false); break; //DP3
|
||||||
case 0x06: AddVecCode("(dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz) + " + GetSRC(1) + ".w)", false); break; //DPH
|
case 0x06: AddVecCode("(dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz) + " + GetSRC(1) + ".w)", false); break; //DPH
|
||||||
@ -249,18 +272,17 @@ void VertexDecompilerThread::Task()
|
|||||||
case 0x08: AddVecCode("distance(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //DST
|
case 0x08: AddVecCode("distance(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //DST
|
||||||
case 0x09: AddVecCode("min(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MIN
|
case 0x09: AddVecCode("min(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MIN
|
||||||
case 0x0a: AddVecCode("max(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MAX
|
case 0x0a: AddVecCode("max(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MAX
|
||||||
case 0x0b: AddVecCode("lessThan(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SLT
|
case 0x0b: AddVecCode("vec4(lessThan(" + GetSRC(0) + ", " + GetSRC(1) + "))"); break; //SLT
|
||||||
case 0x0c: AddVecCode("greaterThanEqual(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SGE
|
case 0x0c: AddVecCode("vec4(greaterThanEqual(" + GetSRC(0) + ", " + GetSRC(1) + "))"); break; //SGE
|
||||||
case 0x0e: AddVecCode("fract(" + GetSRC(0) + ")"); break; //FRC
|
case 0x0e: AddVecCode("fract(" + GetSRC(0) + ")"); break; //FRC
|
||||||
case 0x0f: AddVecCode("floor(" + GetSRC(0) + ")"); break; //FLR
|
case 0x0f: AddVecCode("floor(" + GetSRC(0) + ")"); break; //FLR
|
||||||
case 0x10: AddVecCode("equal(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SEQ
|
case 0x10: AddVecCode("vec4(equal(" + GetSRC(0) + ", " + GetSRC(1) + "))"); break; //SEQ
|
||||||
case 0x11: AddVecCode("vec4(0.0f, 0.0f, 0.0f, 0.0f)"); break; //SFL
|
//case 0x11: AddVecCode("vec4(0.0f, 0.0f, 0.0f, 0.0f)"); break; //SFL
|
||||||
case 0x12: AddVecCode("greaterThan(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SGT
|
case 0x12: AddVecCode("vec4(greaterThan(" + GetSRC(0) + ", " + GetSRC(1) + "))"); break; //SGT
|
||||||
case 0x13: AddVecCode("lessThanEqual(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SLE
|
case 0x13: AddVecCode("vec4(lessThanEqual(" + GetSRC(0) + ", " + GetSRC(1) + "))"); break; //SLE
|
||||||
case 0x14: AddVecCode("notEqual(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SNE
|
case 0x14: AddVecCode("vec4(notEqual(" + GetSRC(0) + ", " + GetSRC(1) + "))"); break; //SNE
|
||||||
case 0x15: AddVecCode("vec4(1.0f, 1.0f, 1.0f, 1.0f)"); break; //STR
|
//case 0x15: AddVecCode("vec4(1.0f, 1.0f, 1.0f, 1.0f)"); break; //STR
|
||||||
case 0x16: AddVecCode("sign(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SSG
|
case 0x16: AddVecCode("sign(" + GetSRC(0) + ")"); break; //SSG
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ConLog.Error("Unknown vp opcode 0x%x", d1.vec_opcode);
|
ConLog.Error("Unknown vp opcode 0x%x", d1.vec_opcode);
|
||||||
@ -276,7 +298,7 @@ void VertexDecompilerThread::Task()
|
|||||||
}
|
}
|
||||||
|
|
||||||
VertexProgram::VertexProgram()
|
VertexProgram::VertexProgram()
|
||||||
: m_decompiler_thread(NULL)
|
: m_decompiler_thread(nullptr)
|
||||||
, id(0)
|
, id(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -358,13 +380,7 @@ void VertexProgram::Compile()
|
|||||||
void VertexProgram::Delete()
|
void VertexProgram::Delete()
|
||||||
{
|
{
|
||||||
data.Clear();
|
data.Clear();
|
||||||
for(u32 i=0; i<parr.params.GetCount(); ++i)
|
|
||||||
{
|
|
||||||
parr.params[i].items.Clear();
|
|
||||||
parr.params[i].type.Clear();
|
|
||||||
}
|
|
||||||
parr.params.Clear();
|
parr.params.Clear();
|
||||||
constants4.Clear();
|
|
||||||
shader.Clear();
|
shader.Clear();
|
||||||
|
|
||||||
if(id)
|
if(id)
|
||||||
@ -374,6 +390,28 @@ void VertexProgram::Delete()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VertexData::VertexData()
|
||||||
|
: index(0)
|
||||||
|
, frequency(0)
|
||||||
|
, stride(0)
|
||||||
|
, size(0)
|
||||||
|
, type(0)
|
||||||
|
, addr(0)
|
||||||
|
, data()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void VertexData::Reset()
|
||||||
|
{
|
||||||
|
index = 0;
|
||||||
|
frequency = 0;
|
||||||
|
stride = 0;
|
||||||
|
size = 0;
|
||||||
|
type = 0;
|
||||||
|
addr = 0;
|
||||||
|
data.ClearF();
|
||||||
|
}
|
||||||
|
|
||||||
void VertexData::Load(u32 start, u32 count)
|
void VertexData::Load(u32 start, u32 count)
|
||||||
{
|
{
|
||||||
const u32 tsize = GetTypeSize();
|
const u32 tsize = GetTypeSize();
|
||||||
|
@ -72,8 +72,7 @@ struct VertexDecompilerThread : public ThreadBase
|
|||||||
u32 end : 1;
|
u32 end : 1;
|
||||||
u32 index_const : 1;
|
u32 index_const : 1;
|
||||||
u32 dst : 5;
|
u32 dst : 5;
|
||||||
u32 sca_dst : 5;
|
u32 sca_dst_tmp : 6;
|
||||||
u32 sca_result : 1;
|
|
||||||
u32 vec_writemask_w : 1;
|
u32 vec_writemask_w : 1;
|
||||||
u32 vec_writemask_z : 1;
|
u32 vec_writemask_z : 1;
|
||||||
u32 vec_writemask_y : 1;
|
u32 vec_writemask_y : 1;
|
||||||
@ -93,17 +92,37 @@ struct VertexDecompilerThread : public ThreadBase
|
|||||||
|
|
||||||
union SRC
|
union SRC
|
||||||
{
|
{
|
||||||
u16 HEX;
|
union
|
||||||
|
{
|
||||||
|
u32 HEX;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u32 src0l : 9;
|
||||||
|
u32 src0h : 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u32 src1 : 17;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u32 src2l : 11;
|
||||||
|
u32 src2h : 6;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u16 reg_type : 2;
|
u32 reg_type : 2;
|
||||||
u16 tmp_src : 5;
|
u32 tmp_src : 6;
|
||||||
u16 swz_w : 2;
|
u32 swz_w : 2;
|
||||||
u16 swz_z : 2;
|
u32 swz_z : 2;
|
||||||
u16 swz_y : 2;
|
u32 swz_y : 2;
|
||||||
u16 swz_x : 2;
|
u32 swz_x : 2;
|
||||||
u16 neg : 1;
|
u32 neg : 1;
|
||||||
};
|
};
|
||||||
} src[3];
|
} src[3];
|
||||||
|
|
||||||
@ -120,12 +139,14 @@ struct VertexDecompilerThread : public ThreadBase
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString GetMask(bool is_sca);
|
||||||
wxString GetVecMask();
|
wxString GetVecMask();
|
||||||
wxString GetScaMask();
|
wxString GetScaMask();
|
||||||
wxString GetDST(bool isSca = false);
|
wxString GetDST(bool is_sca = false);
|
||||||
wxString GetSRC(const u32 n, bool isSca = false);
|
wxString GetSRC(const u32 n, bool is_sca = false);
|
||||||
void AddVecCode(wxString code, bool src_mask = true);
|
void AddCode(bool is_sca, wxString code, bool src_mask = true);
|
||||||
void AddScaCode(wxString code, bool src_mask = true);
|
void AddVecCode(const wxString& code, bool src_mask = true);
|
||||||
|
void AddScaCode(const wxString& code, bool src_mask = true);
|
||||||
wxString BuildCode();
|
wxString BuildCode();
|
||||||
|
|
||||||
virtual void Task();
|
virtual void Task();
|
||||||
@ -140,14 +161,6 @@ struct VertexProgram
|
|||||||
VertexProgram();
|
VertexProgram();
|
||||||
~VertexProgram();
|
~VertexProgram();
|
||||||
|
|
||||||
struct Constant4
|
|
||||||
{
|
|
||||||
u32 id;
|
|
||||||
float x, y, z, w;
|
|
||||||
};
|
|
||||||
|
|
||||||
Array<Constant4> constants4;
|
|
||||||
|
|
||||||
Array<u32> data;
|
Array<u32> data;
|
||||||
ParamArray parr;
|
ParamArray parr;
|
||||||
|
|
||||||
@ -174,11 +187,10 @@ struct VertexData
|
|||||||
|
|
||||||
Array<u8> data;
|
Array<u8> data;
|
||||||
|
|
||||||
VertexData() { memset(this, 0, sizeof(*this)); }
|
VertexData();
|
||||||
~VertexData() { data.Clear(); }
|
|
||||||
|
|
||||||
|
void Reset();
|
||||||
bool IsEnabled() { return size > 0; }
|
bool IsEnabled() { return size > 0; }
|
||||||
|
|
||||||
void Load(u32 start, u32 count);
|
void Load(u32 start, u32 count);
|
||||||
|
|
||||||
u32 GetTypeSize();
|
u32 GetTypeSize();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "SysCalls.h"
|
#include "SysCalls.h"
|
||||||
|
|
||||||
#define FUNC_LOG_ERROR(x) ConLog.Error(x); return SC_ARGS_1
|
#define FUNC_LOG_ERROR(x) ConLog.Error(x); return 0
|
||||||
s64 SysCalls::DoFunc(const u32 id)
|
s64 SysCalls::DoFunc(const u32 id)
|
||||||
{
|
{
|
||||||
switch(id)
|
switch(id)
|
||||||
|
Loading…
Reference in New Issue
Block a user