mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00:00
Implemented binary vertex program disassembler
This commit is contained in:
parent
deebe3ca1f
commit
99ea666bf2
10 changed files with 520 additions and 12 deletions
|
@ -1,13 +1,13 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#include "Utilities/Log.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Utilities/Log.h"
|
||||
#include "CgBinaryProgram.h"
|
||||
#include "Emu/RSX/RSXFragmentProgram.h"
|
||||
|
||||
void CgBinaryDisasm::AddCodeAsm(const std::string& code)
|
||||
{
|
||||
assert(m_opcode < 70);
|
||||
std::string op_name = "";
|
||||
|
||||
if (dst.dest_reg == 63)
|
||||
|
@ -33,7 +33,10 @@ void CgBinaryDisasm::AddCodeAsm(const std::string& code)
|
|||
case RSX_FP_OPCODE_LOOP:
|
||||
case RSX_FP_OPCODE_NOP:
|
||||
case RSX_FP_OPCODE_REP:
|
||||
case RSX_FP_OPCODE_RET: m_dst_reg_name = ""; break;
|
||||
case RSX_FP_OPCODE_RET:
|
||||
m_dst_reg_name = "";
|
||||
op_name = rsx_fp_op_names[m_opcode] + std::string(dst.fp16 ? "H" : "R");
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
@ -212,6 +215,7 @@ template<typename T> std::string CgBinaryDisasm::GetSrcDisAsm(T src)
|
|||
if (strncmp(swizzle.c_str(), f, 4) != 0) ret += "." + swizzle;
|
||||
|
||||
if (src.neg) ret = "-" + ret;
|
||||
if (src.abs) ret = "|" + ret + "|";
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -130,12 +130,13 @@ private:
|
|||
std::vector<u32> m_loop_end_offsets;
|
||||
|
||||
// VP members
|
||||
u32 m_sca_opcode;
|
||||
u32 m_vec_opcode;
|
||||
static const size_t m_max_instr_count = 512;
|
||||
size_t m_instr_count;
|
||||
std::vector<u32> m_data;
|
||||
|
||||
public:
|
||||
|
||||
std::string GetArbShader() const { return m_arb_shader; }
|
||||
std::string GetGlslShader() const { return m_glsl_shader; }
|
||||
|
||||
|
@ -149,6 +150,27 @@ public:
|
|||
std::string GetCondDisAsm();
|
||||
template<typename T> std::string GetSrcDisAsm(T src);
|
||||
|
||||
// VP functions
|
||||
std::string GetMaskDisasm(bool is_sca);
|
||||
std::string GetVecMaskDisasm();
|
||||
std::string GetScaMaskDisasm();
|
||||
std::string GetDSTDisasm(bool is_sca = false);
|
||||
std::string GetSRCDisasm(const u32 n);
|
||||
std::string GetTexDisasm();
|
||||
std::string GetCondDisasm();
|
||||
std::string AddAddrMaskDisasm();
|
||||
std::string AddAddrRegDisasm();
|
||||
u32 GetAddrDisasm();
|
||||
std::string FormatDisasm(const std::string& code);
|
||||
void AddScaCodeDisasm(const std::string& code = "");
|
||||
void AddVecCodeDisasm(const std::string& code = "");
|
||||
void AddCodeCondDisasm(const std::string& dst, const std::string& src);
|
||||
void AddCodeDisasm(const std::string& code);
|
||||
void SetDSTDisasm(bool is_sca, std::string value);
|
||||
void SetDSTVecDisasm(const std::string& code);
|
||||
void SetDSTScaDisasm(const std::string& code);
|
||||
|
||||
|
||||
CgBinaryDisasm(const std::string& path)
|
||||
: m_path(path)
|
||||
, m_buffer(nullptr)
|
||||
|
@ -187,6 +209,7 @@ public:
|
|||
case 1064: return "float4x4";
|
||||
case 1066: return "sampler2D";
|
||||
case 1069: return "samplerCUBE";
|
||||
case 1091: return "float1";
|
||||
|
||||
default: return fmt::format("!UnkCgType(%d)", type);
|
||||
}
|
||||
|
@ -356,12 +379,12 @@ public:
|
|||
m_data.push_back(vdata[i]);
|
||||
}
|
||||
|
||||
//TaskVP();
|
||||
TaskVP();
|
||||
GLVertexDecompilerThread(m_data, m_glsl_shader, param_array).Task();
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetData(const u32 d) const { return d << 16 | d >> 16; }
|
||||
void TaskFP();
|
||||
//void TaskVP(); // TODO
|
||||
void TaskVP();
|
||||
};
|
450
rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp
Normal file
450
rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp
Normal file
|
@ -0,0 +1,450 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#include "Emu/System.h"
|
||||
#include "Utilities/Log.h"
|
||||
#include "CgBinaryProgram.h"
|
||||
#include "Emu/RSX/RSXVertexProgram.h"
|
||||
|
||||
void CgBinaryDisasm::AddScaCodeDisasm(const std::string& code)
|
||||
{
|
||||
assert(m_sca_opcode < 21);
|
||||
m_arb_shader += rsx_vp_sca_op_names[m_sca_opcode] + code + " ";
|
||||
}
|
||||
|
||||
void CgBinaryDisasm::AddVecCodeDisasm(const std::string& code)
|
||||
{
|
||||
assert(m_vec_opcode < 26);
|
||||
m_arb_shader += rsx_vp_vec_op_names[m_vec_opcode] + code + " ";
|
||||
}
|
||||
|
||||
std::string CgBinaryDisasm::GetMaskDisasm(bool is_sca)
|
||||
{
|
||||
std::string ret;
|
||||
|
||||
if (is_sca)
|
||||
{
|
||||
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";
|
||||
}
|
||||
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.empty() || ret == "xyzw" ? "" : ("." + ret);
|
||||
}
|
||||
|
||||
std::string CgBinaryDisasm::GetVecMaskDisasm()
|
||||
{
|
||||
return GetMaskDisasm(false);
|
||||
}
|
||||
|
||||
std::string CgBinaryDisasm::GetScaMaskDisasm()
|
||||
{
|
||||
return GetMaskDisasm(true);
|
||||
}
|
||||
|
||||
std::string CgBinaryDisasm::GetDSTDisasm(bool isSca)
|
||||
{
|
||||
std::string ret;
|
||||
|
||||
switch (isSca ? 0x1f : d3.dst)
|
||||
{
|
||||
case 0x1f:
|
||||
ret += isSca ? fmt::format("R%d", d3.sca_dst_tmp) + GetScaMaskDisasm() : fmt::format("R%d", d0.dst_tmp) + GetVecMaskDisasm();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (d3.dst > 15)
|
||||
LOG_ERROR(RSX, fmt::Format("dst index out of range: %u", d3.dst));
|
||||
|
||||
ret += fmt::format("o[%d]", d3.dst) + GetVecMaskDisasm();
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string CgBinaryDisasm::GetSRCDisasm(const u32 n)
|
||||
{
|
||||
std::string ret;
|
||||
|
||||
switch (src[n].reg_type)
|
||||
{
|
||||
case 1: //temp
|
||||
ret += "R" + std::to_string(src[n].tmp_src);
|
||||
break;
|
||||
case 2: //input
|
||||
if (d1.input_src < 16)
|
||||
{
|
||||
ret += fmt::format("v[%d]", d1.input_src);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR(RSX, "Bad input src num: %d", fmt::by_value(d1.input_src));
|
||||
ret += fmt::format("v[%d] # bad src", d1.input_src);
|
||||
}
|
||||
break;
|
||||
case 3: //const
|
||||
ret += std::string("c[" + (d3.index_const ? AddAddrRegDisasm() + " + " : "") + std::to_string(d1.const_src) + "]");
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_ERROR(RSX, fmt::Format("Bad src%u reg type: %d", n, fmt::by_value(src[n].reg_type)));
|
||||
Emu.Pause();
|
||||
break;
|
||||
}
|
||||
|
||||
static const std::string f = "xyzw";
|
||||
|
||||
std::string swizzle;
|
||||
|
||||
swizzle += f[src[n].swz_x];
|
||||
swizzle += f[src[n].swz_y];
|
||||
swizzle += f[src[n].swz_z];
|
||||
swizzle += f[src[n].swz_w];
|
||||
|
||||
if (swizzle == "xxxx") swizzle = "x";
|
||||
if (swizzle == "yyyy") swizzle = "y";
|
||||
if (swizzle == "zzzz") swizzle = "z";
|
||||
if (swizzle == "wwww") swizzle = "w";
|
||||
|
||||
if (swizzle != f) ret += '.' + swizzle;
|
||||
|
||||
bool abs;
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case 0: abs = d0.src0_abs; break;
|
||||
case 1: abs = d0.src1_abs; break;
|
||||
case 2: abs = d0.src2_abs; break;
|
||||
}
|
||||
|
||||
if (abs) ret = "|" + ret + "|";
|
||||
if (src[n].neg) ret = "-" + ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CgBinaryDisasm::SetDSTDisasm(bool is_sca, std::string value)
|
||||
{
|
||||
is_sca ? AddScaCodeDisasm() : AddVecCodeDisasm();
|
||||
|
||||
if (d0.cond == 0) return;
|
||||
|
||||
enum
|
||||
{
|
||||
lt = 0x1,
|
||||
eq = 0x2,
|
||||
gt = 0x4
|
||||
};
|
||||
|
||||
if (d0.staturate)
|
||||
{
|
||||
m_arb_shader.pop_back();
|
||||
m_arb_shader += "_sat ";
|
||||
}
|
||||
|
||||
std::string dest;
|
||||
if (d0.cond_update_enable_0 && d0.cond_update_enable_1)
|
||||
{
|
||||
m_arb_shader.pop_back();
|
||||
m_arb_shader += "C ";
|
||||
dest = fmt::format("RC%s", GetMaskDisasm(is_sca).c_str());
|
||||
}
|
||||
else if (d3.dst != 0x1f || (is_sca ? d3.sca_dst_tmp != 0x3f : d0.dst_tmp != 0x3f))
|
||||
{
|
||||
dest = GetDSTDisasm(is_sca);
|
||||
}
|
||||
|
||||
AddCodeCondDisasm(FormatDisasm(dest), value);
|
||||
}
|
||||
|
||||
std::string CgBinaryDisasm::GetTexDisasm()
|
||||
{
|
||||
return fmt::format("TEX%d", 0);
|
||||
}
|
||||
|
||||
std::string CgBinaryDisasm::FormatDisasm(const std::string& code)
|
||||
{
|
||||
const std::pair<std::string, std::function<std::string()>> repl_list[] =
|
||||
{
|
||||
{ "$$", []() -> std::string { return "$"; } },
|
||||
{ "$0", std::bind(std::mem_fn(&CgBinaryDisasm::GetSRCDisasm), this, 0) },
|
||||
{ "$1", std::bind(std::mem_fn(&CgBinaryDisasm::GetSRCDisasm), this, 1) },
|
||||
{ "$2", std::bind(std::mem_fn(&CgBinaryDisasm::GetSRCDisasm), this, 2) },
|
||||
{ "$s", std::bind(std::mem_fn(&CgBinaryDisasm::GetSRCDisasm), this, 2) },
|
||||
{ "$am", std::bind(std::mem_fn(&CgBinaryDisasm::AddAddrMaskDisasm), this) },
|
||||
{ "$a", std::bind(std::mem_fn(&CgBinaryDisasm::AddAddrRegDisasm), this) },
|
||||
{ "$t", std::bind(std::mem_fn(&CgBinaryDisasm::GetTexDisasm), this) },
|
||||
{ "$fa", [this]()->std::string { return std::to_string(GetAddrDisasm()); } },
|
||||
{ "$ifcond ", [this]() -> std::string
|
||||
{
|
||||
const std::string& cond = GetCondDisasm();
|
||||
if (cond == "true") return "";
|
||||
return cond;
|
||||
}
|
||||
},
|
||||
{ "$cond", std::bind(std::mem_fn(&CgBinaryDisasm::GetCondDisasm), this) }
|
||||
};
|
||||
|
||||
return fmt::replace_all(code, repl_list);
|
||||
}
|
||||
|
||||
std::string CgBinaryDisasm::GetCondDisasm()
|
||||
{
|
||||
enum
|
||||
{
|
||||
lt = 0x1,
|
||||
eq = 0x2,
|
||||
gt = 0x4
|
||||
};
|
||||
|
||||
if (d0.cond == 0) return "false";
|
||||
if (d0.cond == (lt | gt | eq)) return "true";
|
||||
|
||||
static const char* cond_string_table[(lt | gt | eq) + 1] =
|
||||
{
|
||||
"ERROR",
|
||||
"LT", "EQ", "LE",
|
||||
"GT", "NE", "GE",
|
||||
"ERROR"
|
||||
};
|
||||
|
||||
static const char f[4] = { 'x', 'y', 'z', 'w' };
|
||||
|
||||
std::string swizzle;
|
||||
swizzle += f[d0.mask_x];
|
||||
swizzle += f[d0.mask_y];
|
||||
swizzle += f[d0.mask_z];
|
||||
swizzle += f[d0.mask_w];
|
||||
|
||||
if (swizzle == "xxxx") swizzle = "x";
|
||||
if (swizzle == "yyyy") swizzle = "y";
|
||||
if (swizzle == "zzzz") swizzle = "z";
|
||||
if (swizzle == "wwww") swizzle = "w";
|
||||
|
||||
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
|
||||
|
||||
return fmt::Format("(%s%s)", cond_string_table[d0.cond], swizzle.c_str());
|
||||
}
|
||||
|
||||
void CgBinaryDisasm::AddCodeCondDisasm(const std::string& dst, const std::string& src)
|
||||
{
|
||||
enum
|
||||
{
|
||||
lt = 0x1,
|
||||
eq = 0x2,
|
||||
gt = 0x4
|
||||
};
|
||||
|
||||
if (!d0.cond_test_enable || d0.cond == (lt | gt | eq))
|
||||
{
|
||||
AddCodeDisasm(dst + ", " + src + ";");
|
||||
return;
|
||||
}
|
||||
|
||||
if (d0.cond == 0)
|
||||
{
|
||||
AddCodeDisasm("# " + dst + ", " + src + ";");
|
||||
return;
|
||||
}
|
||||
|
||||
static const char* cond_string_table[(lt | gt | eq) + 1] =
|
||||
{
|
||||
"ERROR",
|
||||
"LT", "EQ", "LE",
|
||||
"GT", "NE", "GE",
|
||||
"ERROR"
|
||||
};
|
||||
|
||||
static const char f[4] = { 'x', 'y', 'z', 'w' };
|
||||
|
||||
std::string swizzle;
|
||||
swizzle += f[d0.mask_x];
|
||||
swizzle += f[d0.mask_y];
|
||||
swizzle += f[d0.mask_z];
|
||||
swizzle += f[d0.mask_w];
|
||||
|
||||
if (swizzle == "xxxx") swizzle = "x";
|
||||
if (swizzle == "yyyy") swizzle = "y";
|
||||
if (swizzle == "zzzz") swizzle = "z";
|
||||
if (swizzle == "wwww") swizzle = "w";
|
||||
|
||||
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
|
||||
|
||||
std::string cond = fmt::Format("%s%s", cond_string_table[d0.cond], swizzle.c_str());
|
||||
AddCodeDisasm(dst + "(" + cond + ") " + ", " + src + ";");
|
||||
}
|
||||
|
||||
|
||||
std::string CgBinaryDisasm::AddAddrMaskDisasm()
|
||||
{
|
||||
static const char f[] = { 'x', 'y', 'z', 'w' };
|
||||
return std::string(".") + f[d0.addr_swz];
|
||||
}
|
||||
|
||||
std::string CgBinaryDisasm::AddAddrRegDisasm()
|
||||
{
|
||||
static const char f[] = { 'x', 'y', 'z', 'w' };
|
||||
return fmt::format("A%d", d0.addr_reg_sel_1) + AddAddrMaskDisasm();
|
||||
}
|
||||
|
||||
u32 CgBinaryDisasm::GetAddrDisasm()
|
||||
{
|
||||
return (d2.iaddrh << 3) | d3.iaddrl;
|
||||
}
|
||||
|
||||
void CgBinaryDisasm::AddCodeDisasm(const std::string& code)
|
||||
{
|
||||
m_arb_shader += FormatDisasm(code) + "\n";
|
||||
}
|
||||
|
||||
void CgBinaryDisasm::SetDSTVecDisasm(const std::string& code)
|
||||
{
|
||||
SetDSTDisasm(false, code);
|
||||
}
|
||||
|
||||
void CgBinaryDisasm::SetDSTScaDisasm(const std::string& code)
|
||||
{
|
||||
SetDSTDisasm(true, code);
|
||||
}
|
||||
|
||||
void CgBinaryDisasm::TaskVP()
|
||||
{
|
||||
m_instr_count = 0;
|
||||
bool is_has_BRA = false;
|
||||
|
||||
for (u32 i = 1; m_instr_count < m_max_instr_count; m_instr_count++)
|
||||
{
|
||||
if (is_has_BRA)
|
||||
{
|
||||
d3.HEX = m_data[i];
|
||||
i += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
d1.HEX = m_data[i++];
|
||||
|
||||
|
||||
m_sca_opcode = d1.sca_opcode;
|
||||
switch (d1.sca_opcode)
|
||||
{
|
||||
case 0x08: //BRA
|
||||
is_has_BRA = true;
|
||||
d3.HEX = m_data[++i];
|
||||
i += 4;
|
||||
AddScaCodeDisasm("# WARNING");
|
||||
break;
|
||||
|
||||
case 0x09: //BRI
|
||||
d2.HEX = m_data[i++];
|
||||
d3.HEX = m_data[i];
|
||||
i += 2;
|
||||
AddScaCodeDisasm("$ifcond # WARNING");
|
||||
break;
|
||||
|
||||
default:
|
||||
d3.HEX = m_data[++i];
|
||||
i += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (d3.end)
|
||||
{
|
||||
m_instr_count++;
|
||||
|
||||
if (i < m_data.size())
|
||||
{
|
||||
LOG_ERROR(RSX, "Program end before buffer end.");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < m_instr_count; ++i)
|
||||
{
|
||||
d0.HEX = m_data[i * 4 + 0];
|
||||
d1.HEX = m_data[i * 4 + 1];
|
||||
d2.HEX = m_data[i * 4 + 2];
|
||||
d3.HEX = m_data[i * 4 + 3];
|
||||
|
||||
src[0].src0l = d2.src0l;
|
||||
src[0].src0h = d1.src0h;
|
||||
src[1].src1 = d2.src1;
|
||||
src[2].src2l = d3.src2l;
|
||||
src[2].src2h = d2.src2h;
|
||||
|
||||
m_sca_opcode = d1.sca_opcode;
|
||||
switch (d1.sca_opcode)
|
||||
{
|
||||
case RSX_SCA_OPCODE_NOP: break;
|
||||
case RSX_SCA_OPCODE_MOV: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_RCP: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_RCC: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_RSQ: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_EXP: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_LOG: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_LIT: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_BRA: AddScaCodeDisasm("BRA # WARNING"); break;
|
||||
case RSX_SCA_OPCODE_BRI: AddCodeDisasm("$ifcond # WARNING"); break;
|
||||
case RSX_SCA_OPCODE_CAL: AddCodeDisasm("$ifcond $f# WARNING"); break;
|
||||
case RSX_SCA_OPCODE_CLI: AddCodeDisasm("$ifcond $f # WARNING"); break;
|
||||
case RSX_SCA_OPCODE_RET: AddCodeDisasm("$ifcond # WARNING"); break;
|
||||
case RSX_SCA_OPCODE_LG2: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_EX2: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_SIN: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_COS: SetDSTScaDisasm("$s"); break;
|
||||
case RSX_SCA_OPCODE_BRB: SetDSTScaDisasm("# WARNING Boolean constant"); break;
|
||||
case RSX_SCA_OPCODE_CLB: SetDSTScaDisasm("# WARNING Boolean constant"); break;
|
||||
case RSX_SCA_OPCODE_PSH: SetDSTScaDisasm(""); break;
|
||||
case RSX_SCA_OPCODE_POP: SetDSTScaDisasm(""); break;
|
||||
|
||||
default:
|
||||
LOG_ERROR(RSX, "Unknown vp sca_opcode 0x%x", fmt::by_value(d1.sca_opcode));
|
||||
break;
|
||||
}
|
||||
|
||||
m_vec_opcode = d1.vec_opcode;
|
||||
switch (d1.vec_opcode)
|
||||
{
|
||||
case RSX_VEC_OPCODE_NOP: break;
|
||||
case RSX_VEC_OPCODE_MOV: SetDSTVecDisasm("$0"); break;
|
||||
case RSX_VEC_OPCODE_MUL: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_ADD: SetDSTVecDisasm("$0, $2"); break;
|
||||
case RSX_VEC_OPCODE_MAD: SetDSTVecDisasm("$0, $1, $2"); break;
|
||||
case RSX_VEC_OPCODE_DP3: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_DPH: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_DP4: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_DST: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_MIN: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_MAX: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_SLT: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_SGE: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_ARL: AddCodeDisasm("ARL, $a, $0"); break;
|
||||
case RSX_VEC_OPCODE_FRC: SetDSTVecDisasm("$0"); break;
|
||||
case RSX_VEC_OPCODE_FLR: SetDSTVecDisasm("$0"); break;
|
||||
case RSX_VEC_OPCODE_SEQ: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_SFL: SetDSTVecDisasm("$0"); break;
|
||||
case RSX_VEC_OPCODE_SGT: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_SLE: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_SNE: SetDSTVecDisasm("$0, $1"); break;
|
||||
case RSX_VEC_OPCODE_STR: SetDSTVecDisasm("$0"); break;
|
||||
case RSX_VEC_OPCODE_SSG: SetDSTVecDisasm("$0"); break;
|
||||
case RSX_VEC_OPCODE_TXL: SetDSTVecDisasm("$t, $0"); break;
|
||||
|
||||
default:
|
||||
LOG_ERROR(RSX, "Unknown vp opcode 0x%x", fmt::by_value(d1.vec_opcode));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_arb_shader += "END\n";
|
||||
}
|
|
@ -735,7 +735,7 @@ void GLVertexDecompilerThread::Task()
|
|||
case RSX_VEC_OPCODE_SNE: SetDSTVec("vec4(notEqual($0, $1))"); break;
|
||||
case RSX_VEC_OPCODE_STR: SetDSTVec("vec4(equal($0, vec4(1.0)))"); break;
|
||||
case RSX_VEC_OPCODE_SSG: SetDSTVec("sign($0)"); break;
|
||||
case RSX_VEC_OPCODE_TEX: SetDSTVec("texture($t, $0.xy)"); break;
|
||||
case RSX_VEC_OPCODE_TXL: SetDSTVec("texture($t, $0.xy)"); break;
|
||||
|
||||
default:
|
||||
AddCode(fmt::Format("//Unknown vp opcode 0x%x", fmt::by_value(d1.vec_opcode)));
|
||||
|
|
|
@ -68,7 +68,7 @@ enum
|
|||
RSX_FP_OPCODE_IFE = 0x42, // If
|
||||
RSX_FP_OPCODE_LOOP = 0x43, // Loop
|
||||
RSX_FP_OPCODE_REP = 0x44, // Repeat
|
||||
RSX_FP_OPCODE_RET = 0x45, // Return
|
||||
RSX_FP_OPCODE_RET = 0x45 // Return
|
||||
};
|
||||
|
||||
static union OPDEST
|
||||
|
|
|
@ -50,7 +50,7 @@ enum vec_opcode
|
|||
RSX_VEC_OPCODE_SNE = 0x14,
|
||||
RSX_VEC_OPCODE_STR = 0x15,
|
||||
RSX_VEC_OPCODE_SSG = 0x16,
|
||||
RSX_VEC_OPCODE_TEX = 0x19
|
||||
RSX_VEC_OPCODE_TXL = 0x19
|
||||
};
|
||||
|
||||
static union D0
|
||||
|
@ -187,7 +187,7 @@ static const std::string rsx_vp_vec_op_names[] =
|
|||
{
|
||||
"NOP", "MOV", "MUL", "ADD", "MAD", "DP3", "DPH", "DP4",
|
||||
"DST", "MIN", "MAX", "SLT", "SGE", "ARL", "FRC", "FLR",
|
||||
"SEQ", "SFL", "SGT", "SLE", "SNE", "STR", "SSG", "TEX"
|
||||
"SEQ", "SFL", "SGT", "SLE", "SNE", "STR", "SSG", "NULL", "NULL", "TXL"
|
||||
};
|
||||
|
||||
struct RSXVertexProgram
|
||||
|
|
|
@ -29,7 +29,11 @@ CgDisasm::CgDisasm(wxWindow* parent)
|
|||
|
||||
SetMenuBar(menubar);
|
||||
|
||||
m_disasm_text->Bind(wxEVT_RIGHT_DOWN, &CgDisasm::OnRightClick, this);
|
||||
m_glsl_text->Bind(wxEVT_RIGHT_DOWN, &CgDisasm::OnRightClick, this);
|
||||
|
||||
Bind(wxEVT_MENU, &CgDisasm::OpenCg, this, id_open_file);
|
||||
Bind(wxEVT_MENU, &CgDisasm::OnContextMenu, this, id_clear);
|
||||
}
|
||||
|
||||
void CgDisasm::OpenCg(wxCommandEvent& event)
|
||||
|
@ -56,3 +60,23 @@ void CgDisasm::OnSize(wxSizeEvent& event)
|
|||
m_glsl_text->SetSize(GetSize().x - 20, GetSize().y - 85);
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void CgDisasm::OnRightClick(wxMouseEvent& event)
|
||||
{
|
||||
wxMenu* menu = new wxMenu();
|
||||
menu->Append(id_clear, "&Clear");
|
||||
PopupMenu(menu);
|
||||
}
|
||||
|
||||
void CgDisasm::OnContextMenu(wxCommandEvent& event)
|
||||
{
|
||||
switch (event.GetId())
|
||||
{
|
||||
case id_clear:
|
||||
m_disasm_text->Clear();
|
||||
m_glsl_text->Clear();
|
||||
break;
|
||||
default:
|
||||
event.Skip();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
enum CgDisasmIds
|
||||
{
|
||||
id_open_file
|
||||
id_open_file,
|
||||
id_clear
|
||||
};
|
||||
|
||||
class CgDisasm : public wxFrame
|
||||
|
@ -19,4 +20,6 @@ public:
|
|||
|
||||
void OpenCg(wxCommandEvent& event);
|
||||
virtual void OnSize(wxSizeEvent& event);
|
||||
void OnRightClick(wxMouseEvent& event);
|
||||
void OnContextMenu(wxCommandEvent& event);
|
||||
};
|
|
@ -38,6 +38,7 @@
|
|||
<ClCompile Include="..\Utilities\StrFmt.cpp" />
|
||||
<ClCompile Include="..\Utilities\Thread.cpp" />
|
||||
<ClCompile Include="Emu\RSX\CgBinaryFragmentProgram.cpp" />
|
||||
<ClCompile Include="Emu\RSX\CgBinaryVertexProgram.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSpursSpu.cpp" />
|
||||
<ClCompile Include="Crypto\aes.cpp" />
|
||||
<ClCompile Include="Crypto\ec.cpp" />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
|
@ -857,6 +857,9 @@
|
|||
<ClCompile Include="Emu\ARMv7\Modules\psv_cond.cpp">
|
||||
<Filter>Emu\CPU\ARMv7\Objects</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\CgBinaryVertexProgram.cpp">
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Crypto\aes.h">
|
||||
|
|
Loading…
Add table
Reference in a new issue