OpenGL renderer:

- Improved Vertex & Fragment Shader Decompilers.
- Implemented fp uniform loader.
- Implemented DXT1 & DXT2 textures decompression.
- Implemented draft cellResc module.
- Updated glext.

PPU Interpreter:
- Fixed VSPLTW, VNMSUBFP, VMRGLW, VMRGLH, VMRGLB, VMRGHW, VMRGHH, VMRGHB instructions.

cellFs:
- Fixed cellFsStat syscall.
This commit is contained in:
DH 2013-08-26 17:18:59 +03:00
parent 234e174b7d
commit f83aa9d5ae
42 changed files with 4015 additions and 845 deletions

2014
GL/glext.h

File diff suppressed because it is too large Load Diff

View File

@ -88,11 +88,14 @@ public:
return m_count - 1;
}
inline bool AddCpy(const u32 pos, const T* data, u64 count = 1)
inline bool AddCpy(const u32 pos, const T* data, u32 count = 1)
{
if(!InsertRoom(pos, count)) return false;
memcpy(m_array + pos, data, sizeof(T) * count);
for(u32 i=0; i<count; ++i)
{
new (m_array + pos + i) T(data[i]);
}
return true;
}
@ -102,11 +105,14 @@ public:
return AddCpy(pos, &data);
}
inline u32 AddCpy(const T* data, u64 count = 1)
inline u32 AddCpy(const T* data, u32 count = 1)
{
_InsertRoomEnd(count);
memcpy(m_array + m_count - count, data, sizeof(T)*count);
for(u32 i=0; i<count; ++i)
{
new (m_array + m_count - count + i) T(data[i]);
}
return m_count - count;
}

View File

@ -236,7 +236,7 @@ struct MFC
break;
default:
ConLog.Error("Unknown MFC cmd.");
ConLog.Error("Unknown MFC cmd. (opcode=0x%x, cmd=0x%x)", op, cmd);
break;
}
}

View File

@ -426,9 +426,9 @@ private:
{
DisAsm_V3("vmulouh", vd, va, vb);
}
void VNMSUBFP(u32 vd, u32 va, u32 vb, u32 vc)
void VNMSUBFP(u32 vd, u32 va, u32 vc, u32 vb)
{
DisAsm_V4("vnmsubfp", vd, va, vb, vc);
DisAsm_V4("vnmsubfp", vd, va, vc, vb);
}
void VNOR(u32 vd, u32 va, u32 vb)
{

View File

@ -273,7 +273,7 @@ namespace PPU_instr
bind_instr(g04_list, VMSUMUBM, VD, VA, VB, VC);
bind_instr(g04_list, VMSUMUHM, VD, VA, VB, VC);
bind_instr(g04_list, VMSUMUHS, VD, VA, VB, VC);
bind_instr(g04_list, VNMSUBFP, VD, VA, VB, VC);
bind_instr(g04_list, VNMSUBFP, VD, VA, VC, VB);
bind_instr(g04_list, VPERM, VD, VA, VB, VC);
bind_instr(g04_list, VSEL, VD, VA, VB, VC);
bind_instr(g04_list, VSLDOI, VD, VA, VB, VSH);

View File

@ -949,50 +949,56 @@ private:
}
void VMRGHB(u32 vd, u32 va, u32 vb)
{
VPR_reg VA = CPU.VPR[va];
VPR_reg VB = CPU.VPR[vb];
for (uint h = 0; h < 8; h++)
{
CPU.VPR[vd]._u8[h*2] = CPU.VPR[va]._u8[h];
CPU.VPR[vd]._u8[h*2 + 1] = CPU.VPR[vb]._u8[h];
CPU.VPR[vd]._u8[15 - h*2] = VA._u8[15 - h];
CPU.VPR[vd]._u8[15 - h*2 - 1] = VB._u8[15 - h];
}
}
void VMRGHH(u32 vd, u32 va, u32 vb)
{
VPR_reg VA = CPU.VPR[va];
VPR_reg VB = CPU.VPR[vb];
for (uint w = 0; w < 4; w++)
{
CPU.VPR[vd]._u16[w*2] = CPU.VPR[va]._u16[w];
CPU.VPR[vd]._u16[w*2 + 1] = CPU.VPR[vb]._u16[w];
CPU.VPR[vd]._u16[7 - w*2] = VA._u16[7 - w];
CPU.VPR[vd]._u16[7 - w*2 - 1] = VB._u16[7 - w];
}
}
void VMRGHW(u32 vd, u32 va, u32 vb)
{
VPR_reg VA = CPU.VPR[va];
VPR_reg VB = CPU.VPR[vb];
for (uint d = 0; d < 2; d++)
{
CPU.VPR[vd]._u32[d*2] = CPU.VPR[va]._u32[d];
CPU.VPR[vd]._u32[d*2 + 1] = CPU.VPR[vb]._u32[d];
CPU.VPR[vd]._u32[3 - d*2] = VA._u32[3 - d];
CPU.VPR[vd]._u32[3 - d*2 - 1] = VB._u32[3 - d];
}
}
void VMRGLB(u32 vd, u32 va, u32 vb)
{
for (uint h = 0; h < 8; h++)
{
CPU.VPR[vd]._u8[h*2] = CPU.VPR[va]._u8[h + 8];
CPU.VPR[vd]._u8[h*2 + 1] = CPU.VPR[vb]._u8[h + 8];
CPU.VPR[vd]._u8[15 - h*2] = CPU.VPR[va]._u8[7 - h];
CPU.VPR[vd]._u8[15 - h*2 - 1] = CPU.VPR[vb]._u8[7 - h];
}
}
void VMRGLH(u32 vd, u32 va, u32 vb)
{
for (uint w = 0; w < 4; w++)
{
CPU.VPR[vd]._u16[w*2] = CPU.VPR[va]._u16[w + 4];
CPU.VPR[vd]._u16[w*2 + 1] = CPU.VPR[vb]._u16[w + 4];
CPU.VPR[vd]._u16[7 - w*2] = CPU.VPR[va]._u16[3 - w];
CPU.VPR[vd]._u16[7 - w*2 - 1] = CPU.VPR[vb]._u16[3 - w];
}
}
void VMRGLW(u32 vd, u32 va, u32 vb)
{
for (uint d = 0; d < 2; d++)
{
CPU.VPR[vd]._u32[d*2] = CPU.VPR[va]._u32[d + 2];
CPU.VPR[vd]._u32[d*2 + 1] = CPU.VPR[vb]._u32[d + 2];
CPU.VPR[vd]._u32[3 - d*2] = CPU.VPR[va]._u32[1 - d];
CPU.VPR[vd]._u32[3 - d*2 - 1] = CPU.VPR[vb]._u32[1 - d];
}
}
void VMSUMMBM(u32 vd, u32 va, u32 vb, u32 vc)
@ -1166,11 +1172,11 @@ private:
CPU.VPR[vd]._u32[w] = (u32)CPU.VPR[va]._u16[w*2] * (u32)CPU.VPR[vb]._u16[w*2];
}
}
void VNMSUBFP(u32 vd, u32 va, u32 vb, u32 vc)
void VNMSUBFP(u32 vd, u32 va, u32 vc, u32 vb)
{
for (uint w = 0; w < 4; w++)
{
CPU.VPR[vd]._f[w] = (double)CPU.VPR[vb]._f[w] - (double)CPU.VPR[va]._f[w] * (double)CPU.VPR[vc]._f[w];
CPU.VPR[vd]._f[w] = -(CPU.VPR[va]._f[w] * CPU.VPR[vc]._f[w] - CPU.VPR[vb]._f[w]);
}
}
void VNOR(u32 vd, u32 va, u32 vb)
@ -1611,7 +1617,7 @@ private:
{
assert(uimm5 < 4);
u32 word = CPU.VPR[vb]._u32[uimm5];
u32 word = CPU.VPR[vb]._u32[3 - uimm5];
for (uint w = 0; w < 4; w++)
{

View File

@ -535,7 +535,7 @@ public:
virtual void VMULOSH(u32 vd, u32 va, u32 vb) = 0;
virtual void VMULOUB(u32 vd, u32 va, u32 vb) = 0;
virtual void VMULOUH(u32 vd, u32 va, u32 vb) = 0;
virtual void VNMSUBFP(u32 vd, u32 va, u32 vb, u32 vc) = 0;
virtual void VNMSUBFP(u32 vd, u32 va, u32 vc, u32 vb) = 0;
virtual void VNOR(u32 vd, u32 va, u32 vb) = 0;
virtual void VOR(u32 vd, u32 va, u32 vb) = 0;
virtual void VPERM(u32 vd, u32 va, u32 vb, u32 vc) = 0;

View File

@ -1,50 +1,49 @@
#include "stdafx.h"
#include "FragmentProgram.h"
void FragmentDecompilerThread::AddCode(wxString code)
void FragmentDecompilerThread::AddCode(wxString code, bool append_mask)
{
if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return;
const wxString mask = GetMask();
wxString cond = wxEmptyString;
if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq)
{
if(src0.exec_if_gr)
{
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.Len())
{
static const char f[4] = {'x', 'y', 'z', 'w'};
wxString swizzle = wxEmptyString;
swizzle += f[src0.cond_swizzle_x];
swizzle += f[src0.cond_swizzle_y];
swizzle += f[src0.cond_swizzle_z];
swizzle += f[src0.cond_swizzle_w];
cond = wxString::Format("if(rc.%s %s 0.0) ", swizzle, cond);
if(src0.exec_if_gr && src0.exec_if_eq)
{
cond = "greaterThanEqual";
}
else if(src0.exec_if_lt && src0.exec_if_eq)
{
cond = "lessThanEqual";
}
else if(src0.exec_if_gr && src0.exec_if_lt)
{
cond = "notEqual";
}
else if(src0.exec_if_gr)
{
cond = "greaterThan";
}
else if(src0.exec_if_lt)
{
cond = "lessThan";
}
else //if(src0.exec_if_eq)
{
cond = "equal";
}
cond = wxString::Format("if(all(%s(%s.%s, vec4(0, 0, 0, 0)))) ", cond, AddCond(dst.no_dest), swizzle);
//ConLog.Error("cond! [eq: %d gr: %d lt: %d] (%s)", src0.exec_if_eq, src0.exec_if_gr, src0.exec_if_lt, cond);
//Emu.Pause();
//return;
@ -73,7 +72,8 @@ void FragmentDecompilerThread::AddCode(wxString code)
code = "clamp(" + code + ", 0.0, 1.0)";
}
code = cond + (dst.set_cond ? AddCond(dst.fp16) : AddReg(dst.dest_reg, dst.fp16)) + GetMask() + " = " + code + GetMask();
code = cond + (dst.set_cond ? AddCond(dst.fp16) : AddReg(dst.dest_reg, dst.fp16)) + mask
+ " = " + code + (append_mask ? mask : wxEmptyString);
main += "\t" + code + ";\n";
}
@ -82,25 +82,30 @@ wxString FragmentDecompilerThread::GetMask()
{
wxString ret = wxEmptyString;
static const char dst_mask[2][4] =
static const char dst_mask[4] =
{
{'x', 'y', 'z', 'w'},
{'r', 'g', 'b', 'a'}
'x', 'y', 'z', 'w',
};
if(dst.mask_x) ret += dst_mask[dst.dest_reg == 0][0];
if(dst.mask_y) ret += dst_mask[dst.dest_reg == 0][1];
if(dst.mask_z) ret += dst_mask[dst.dest_reg == 0][2];
if(dst.mask_w) ret += dst_mask[dst.dest_reg == 0][3];
if(dst.mask_x) ret += dst_mask[0];
if(dst.mask_y) ret += dst_mask[1];
if(dst.mask_z) ret += dst_mask[2];
if(dst.mask_w) ret += dst_mask[3];
return ret.IsEmpty() || strncmp(ret, dst_mask[dst.dest_reg == 0], 4) == 0 ? wxEmptyString : ("." + ret);
return ret.IsEmpty() || strncmp(ret, dst_mask, 4) == 0 ? wxEmptyString : ("." + ret);
}
wxString FragmentDecompilerThread::AddReg(u32 index, int fp16)
{
//if(!index) return "gl_FragColor";
//if(!index && !fp16) return "gl_FragColor";
return m_parr.AddParam((index || fp16) ? PARAM_NONE : PARAM_OUT, "vec4",
wxString::Format((fp16 ? "h%d" : "r%d"), index), (index || fp16) ? -1 : 0);
wxString::Format((fp16 ? "h%u" : "r%u"), index), (index || fp16) ? -1 : 0);
}
bool FragmentDecompilerThread::HasReg(u32 index, int fp16)
{
return m_parr.HasParam((index || fp16) ? PARAM_NONE : PARAM_OUT, "vec4",
wxString::Format((fp16 ? "h%u" : "r%u"), index));
}
wxString FragmentDecompilerThread::AddCond(int fp16)
@ -117,7 +122,7 @@ wxString FragmentDecompilerThread::AddConst()
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++),
return m_parr.AddParam(PARAM_UNIFORM, "vec4", wxString::Format("fc%u", m_size + 4 * 4),
wxString::Format("vec4(%f, %f, %f, %f)", (float&)x, (float&)y, (float&)z, (float&)w));
}
@ -130,8 +135,6 @@ template<typename T> wxString FragmentDecompilerThread::GetSRC(T src)
{
wxString ret = wxEmptyString;
bool is_color = src.reg_type == 0 || (src.reg_type == 1 && dst.src_attr_reg_num >= 1 && dst.src_attr_reg_num <= 3);
switch(src.reg_type)
{
case 0: //tmp
@ -177,9 +180,7 @@ template<typename T> wxString FragmentDecompilerThread::GetSRC(T src)
break;
}
static const char f_pos[4] = {'x', 'y', 'z', 'w'};
static const char f_col[4] = {'r', 'g', 'b', 'a'};
const char *f = is_color ? f_col : f_pos;
static const char f[4] = {'x', 'y', 'z', 'w'};
wxString swizzle = wxEmptyString;
swizzle += f[src.swizzle_x];
@ -199,6 +200,11 @@ wxString FragmentDecompilerThread::BuildCode()
{
wxString p = wxEmptyString;
if(!m_parr.HasParam(PARAM_OUT, "vec4", "r0") && m_parr.HasParam(PARAM_NONE, "vec4", "h0"))
{
main += "\t" + m_parr.AddParam(PARAM_OUT, "vec4", "r0", 0) + " = " + "h0;\n";
}
for(u32 i=0; i<m_parr.params.GetCount(); ++i)
{
p += m_parr.params[i].Format();
@ -227,16 +233,16 @@ void FragmentDecompilerThread::Task()
m_offset = 4 * 4;
switch(dst.opcode)
switch(dst.opcode | (src1.opcode_is_branch << 6))
{
case 0x00: break; //NOP
case 0x01: AddCode(GetSRC(src0)); break; //MOV
case 0x02: AddCode("(" + GetSRC(src0) + " * " + GetSRC(src1) + ")"); break; //MUL
case 0x03: AddCode("(" + GetSRC(src0) + " + " + GetSRC(src1) + ")"); break; //ADD
case 0x04: AddCode("(" + GetSRC(src0) + " * " + GetSRC(src1) + " + " + GetSRC(src2) + ")"); break; //MAD
case 0x05: AddCode("dot(" + GetSRC(src0) + ".xyz, " + GetSRC(src1) + ".xyz)"); break; // DP3
case 0x06: AddCode("dot(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // DP4
case 0x07: AddCode("distance(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // DST
case 0x05: AddCode("vec4(dot(" + GetSRC(src0) + ".xyz, " + GetSRC(src1) + ".xyz)).xxxx"); break; // DP3
case 0x06: AddCode("vec4(dot(" + GetSRC(src0) + ", " + GetSRC(src1) + ")).xxxx"); break; // DP4
case 0x07: AddCode("vec4(distance(" + GetSRC(src0) + ", " + GetSRC(src1) + ")).xxxx"); break; // DST
case 0x08: AddCode("min(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // MIN
case 0x09: AddCode("max(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // MAX
case 0x0a: AddCode("vec4(lessThan(" + GetSRC(src0) + ", " + GetSRC(src1) + "))"); break; // SLT
@ -286,10 +292,10 @@ void FragmentDecompilerThread::Task()
//case 0x35: break; // BEMLUM
//case 0x36: break; // REFL
//case 0x37: break; // TIMESWTEX
//case 0x38: break; // DP2
//case 0x39: break; // NRM
case 0x38: AddCode("vec4(dot(" + GetSRC(src0) + ".xy, " + GetSRC(src1) + ".xy)).xxxx"); break; // DP2
case 0x39: AddCode("normalize(" + GetSRC(src0) + ".xyz)"); break; // NRM
case 0x3a: AddCode("(" + GetSRC(src0) + " / " + GetSRC(src1) + ")"); break; // DIV
case 0x3b: AddCode("(" + GetSRC(src0) + " / " + GetSRC(src1) + ")"); break; // DIVSQ
case 0x3b: AddCode("(" + GetSRC(src0) + " / sqrt(" + GetSRC(src1) + "))"); break; // DIVSQ
//case 0x3c: break; // LIF
case 0x3d: break; // FENCT
case 0x3e: break; // FENCB

View File

@ -33,22 +33,24 @@ struct FragmentDecompilerThread : public ThreadBase
struct
{
u32 reg_type : 2;
u32 tmp_reg_index : 6;
u32 fp16 : 1;
u32 swizzle_x : 2;
u32 swizzle_y : 2;
u32 swizzle_z : 2;
u32 swizzle_w : 2;
u32 neg : 1;
u32 exec_if_lt : 1;
u32 exec_if_eq : 1;
u32 exec_if_gr : 1;
u32 cond_swizzle_x : 2;
u32 cond_swizzle_y : 2;
u32 cond_swizzle_z : 2;
u32 cond_swizzle_w : 2;
u32 abs : 1;
u32 reg_type : 2;
u32 tmp_reg_index : 6;
u32 fp16 : 1;
u32 swizzle_x : 2;
u32 swizzle_y : 2;
u32 swizzle_z : 2;
u32 swizzle_w : 2;
u32 neg : 1;
u32 exec_if_lt : 1;
u32 exec_if_eq : 1;
u32 exec_if_gr : 1;
u32 cond_swizzle_x : 2;
u32 cond_swizzle_y : 2;
u32 cond_swizzle_z : 2;
u32 cond_swizzle_w : 2;
u32 abs : 1;
u32 cond_mod_reg_index : 1;
u32 cond_reg_index : 1;
};
} src0;
@ -67,8 +69,8 @@ struct FragmentDecompilerThread : public ThreadBase
u32 swizzle_w : 2;
u32 neg : 1;
u32 abs : 1;
u32 input_prec : 2;
u32 : 7;
u32 input_mod_src0 : 3;
u32 : 6;
u32 scale : 3;
u32 opcode_is_branch : 1;
};
@ -91,6 +93,7 @@ struct FragmentDecompilerThread : public ThreadBase
u32 abs : 1;
u32 addr_reg : 11;
u32 use_index_reg : 1;
u32 perspective_corr: 1;
};
} src2;
@ -115,8 +118,9 @@ struct FragmentDecompilerThread : public ThreadBase
wxString GetMask();
void AddCode(wxString code);
void AddCode(wxString code, bool append_mask = true);
wxString AddReg(u32 index, int fp16);
bool HasReg(u32 index, int fp16);
wxString AddCond(int fp16);
wxString AddConst();
wxString AddTex();
@ -140,6 +144,7 @@ struct ShaderProgram
u32 size;
u32 addr;
u32 offset;
wxString shader;
u32 id;

View File

@ -121,6 +121,132 @@ void GLvao::Delete()
}
bool GLvao::IsCreated() const
{
return m_id != 0;
}
GLrbo::GLrbo()
{
}
GLrbo::~GLrbo()
{
}
void GLrbo::Create(u32 count)
{
if(m_id.GetCount())
{
return;
}
m_id.SetCount(count);
glGenRenderbuffers(count, m_id.GetPtr());
}
void GLrbo::Bind(u32 num) const
{
assert(num < m_id.GetCount());
glBindRenderbuffer(GL_RENDERBUFFER, m_id[num]);
}
void GLrbo::Storage(u32 format, u32 width, u32 height)
{
glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
}
void GLrbo::Unbind()
{
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
void GLrbo::Delete()
{
glDeleteRenderbuffers(m_id.GetCount(), m_id.GetPtr());
m_id.Clear();
}
bool GLrbo::IsCreated() const
{
return m_id.GetCount();
}
u32 GLrbo::GetId(u32 num) const
{
assert(num < m_id.GetCount());
return m_id[num];
}
GLfbo::GLfbo()
{
}
GLfbo::~GLfbo()
{
}
void GLfbo::Create()
{
if(m_id)
{
return;
}
glGenFramebuffers(1, &m_id);
}
void GLfbo::Bind(u32 type, int id)
{
if(id != -1)
assert(m_id);
m_type = type;
glBindFramebuffer(m_type, id == -1 ? m_id : id);
}
void GLfbo::Texture1D(u32 attachment, u32 texture, int level)
{
glFramebufferTexture1D(m_type, attachment, GL_TEXTURE_1D, texture, level);
}
void GLfbo::Texture2D(u32 attachment, u32 texture, int level)
{
glFramebufferTexture2D(m_type, attachment, GL_TEXTURE_2D, texture, level);
}
void GLfbo::Texture3D(u32 attachment, u32 texture, int zoffset, int level)
{
glFramebufferTexture3D(m_type, attachment, GL_TEXTURE_3D, texture, level, zoffset);
}
void GLfbo::Renderbuffer(u32 attachment, u32 renderbuffer)
{
glFramebufferRenderbuffer(m_type, attachment, GL_RENDERBUFFER, renderbuffer);
}
void GLfbo::Blit(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, u32 mask, u32 filter)
{
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
void GLfbo::Unbind()
{
Unbind(m_type);
}
void GLfbo::Unbind(u32 type)
{
glBindFramebuffer(type, 0);
}
void GLfbo::Delete()
{
glDeleteFramebuffers(1, &m_id);
m_id = 0;
}
bool GLfbo::IsCreated() const
{
return m_id != 0;
}

View File

@ -46,4 +46,45 @@ public:
static void Unbind();
void Delete();
bool IsCreated() const;
};
class GLrbo
{
protected:
Array<GLuint> m_id;
public:
GLrbo();
~GLrbo();
void Create(u32 count = 1);
void Bind(u32 num = 0) const;
void Storage(u32 format, u32 width, u32 height);
static void Unbind();
void Delete();
bool IsCreated() const;
u32 GetId(u32 num) const;
};
class GLfbo
{
protected:
GLuint m_id;
GLuint m_type;
public:
GLfbo();
~GLfbo();
void Create();
void Bind(u32 type = GL_FRAMEBUFFER, int id = -1);
void Texture1D(u32 attachment, u32 texture, int level = 0);
void Texture2D(u32 attachment, u32 texture, int level = 0);
void Texture3D(u32 attachment, u32 texture, int zoffset = 0, int level = 0);
void Renderbuffer(u32 attachment, u32 renderbuffer);
void Blit(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, u32 mask, u32 filter);
void Unbind();
static void Unbind(u32 type);
void Delete();
bool IsCreated() const;
};

File diff suppressed because it is too large Load Diff

View File

@ -24,18 +24,39 @@ class GLTexture
u8 m_dimension;
u32 m_format;
u16 m_mipmap;
u32 m_pitch;
u16 m_depth;
u16 m_minlod;
u16 m_maxlod;
u8 m_maxaniso;
u8 m_wraps;
u8 m_wrapt;
u8 m_wrapr;
u8 m_unsigned_remap;
u8 m_zfunc;
u8 m_gamma;
u8 m_aniso_bias;
u8 m_signed_remap;
u32 m_remap;
public:
GLTexture()
: m_width(0), m_height(0),
m_id(0),
m_offset(0),
m_enabled(false),
: m_width(0), m_height(0)
, m_id(0)
, m_offset(0)
, m_enabled(false)
m_cubemap(false),
m_dimension(0),
m_format(0),
m_mipmap(0)
, m_cubemap(false)
, m_dimension(0)
, m_format(0)
, m_mipmap(0)
, m_minlod(0)
, m_maxlod(1000)
, m_maxaniso(0)
{
}
@ -51,10 +72,11 @@ public:
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);
//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);
}
}
@ -74,6 +96,37 @@ public:
m_mipmap = mipmap;
}
void SetAddress(u8 wraps, u8 wrapt, u8 wrapr, u8 unsigned_remap, u8 zfunc, u8 gamma, u8 aniso_bias, u8 signed_remap)
{
m_wraps = wraps;
m_wrapt = wrapt;
m_wrapr = wrapr;
m_unsigned_remap = unsigned_remap;
m_zfunc = zfunc;
m_gamma = gamma;
m_aniso_bias = aniso_bias;
m_signed_remap = signed_remap;
}
void SetControl0(const bool enable, const u16 minlod, const u16 maxlod, const u8 maxaniso)
{
m_enabled = enable;
m_minlod = minlod;
m_maxlod = maxlod;
m_maxaniso = maxaniso;
}
void SetControl1(u32 remap)
{
m_remap = remap;
}
void SetControl3(u16 depth, u32 pitch)
{
m_depth = depth;
m_pitch = pitch;
}
u32 GetFormat() const { return m_format; }
void SetOffset(const u32 offset)
@ -86,44 +139,163 @@ public:
return wxSize(m_width, m_height);
}
int GetGlWrap(int wrap)
{
switch(wrap)
{
case 1: return GL_REPEAT;
case 2: return GL_MIRRORED_REPEAT;
case 3: return GL_CLAMP_TO_EDGE;
case 4: return GL_TEXTURE_BORDER;
case 5: return GL_CLAMP_TO_EDGE;//GL_CLAMP;
//case 6: return GL_MIRROR_CLAMP_TO_EDGE_EXT;
}
ConLog.Error("Texture wrap error: bad wrap (%d).", wrap);
return GL_REPEAT;
}
void Init()
{
Bind();
//ConLog.Warning("texture addr = 0x%x, width = %d, height = %d", m_offset, m_width, m_height);
if(!Memory.IsGoodAddr(m_offset))
{
ConLog.Error("Bad texture address=0x%x", m_offset);
return;
}
//ConLog.Warning("texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x",
// m_offset, m_width, m_height, m_maxaniso, m_mipmap, m_remap, m_zfunc, m_wraps, m_wrapt, m_wrapr, m_minlod, m_maxlod);
//TODO: safe init
checkForGlError("GLTexture::Init() -> glBindTexture");
switch(m_format & ~(0x20 | 0x40))
glPixelStorei(GL_PACK_ROW_LENGTH, m_pitch);
int format = m_format & ~(0x20 | 0x40);
bool is_swizzled = (m_format & 0x20) == 0;
char* pixels = (char*)Memory.GetMemFromAddr(m_offset);
switch(format)
{
case 0x81:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BLUE, GL_UNSIGNED_BYTE, Memory.GetMemFromAddr(m_offset));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels);
checkForGlError("GLTexture::Init() -> glTexImage2D");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_BLUE);
checkForGlError("GLTexture::Init() -> glTexParameteri");
break;
case 0x85:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, Memory.GetMemFromAddr(m_offset));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels);
checkForGlError("GLTexture::Init() -> glTexImage2D");
break;
case 0x94://FIXME
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, m_width, m_height, 0, GL_RED, GL_SHORT, Memory.GetMemFromAddr(m_offset));
case 0x86:
{
u32 size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 8;
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, m_width, m_height, 0, size, pixels);
checkForGlError("GLTexture::Init() -> glCompressedTexImage2D");
}
break;
case 0x87:
{
u32 size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 16;
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, m_width, m_height, 0, size, pixels);
checkForGlError("GLTexture::Init() -> glCompressedTexImage2D");
}
break;
case 0x88:
{
u32 size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 16;
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, m_width, m_height, 0, size, pixels);
checkForGlError("GLTexture::Init() -> glCompressedTexImage2D");
}
break;
case 0x94:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RED, GL_SHORT, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
checkForGlError("GLTexture::Init() -> glTexImage2D");
break;
default: ConLog.Error("Init tex error: Bad tex format (0x%x)", m_format); break;
case 0x9a:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_HALF_FLOAT, pixels);
checkForGlError("GLTexture::Init() -> glTexImage2D");
break;
case 0x9e:
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels);
checkForGlError("GLTexture::Init() -> glTexImage2D");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
}
break;
default: ConLog.Error("Init tex error: Bad tex format (0x%x | 0x%x | 0x%x)", format, m_format & 0x20, m_format & 0x40); break;
}
if(m_mipmap > 1)
{
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if(format != 0x81 && format != 0x94)
{
u8 remap_a = m_remap & 0x3;
u8 remap_r = (m_remap >> 2) & 0x3;
u8 remap_g = (m_remap >> 4) & 0x3;
u8 remap_b = (m_remap >> 6) & 0x3;
static const int gl_remap[] =
{
GL_ALPHA,
GL_RED,
GL_GREEN,
GL_BLUE,
};
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, gl_remap[remap_a]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, gl_remap[remap_r]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, gl_remap[remap_g]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, gl_remap[remap_b]);
}
static const int gl_tex_zfunc[] =
{
GL_NEVER,
GL_LESS,
GL_EQUAL,
GL_LEQUAL,
GL_GREATER,
GL_NOTEQUAL,
GL_GEQUAL,
GL_ALWAYS,
};
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(m_wraps));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(m_wrapt));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(m_wrapr));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[m_zfunc]);
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, m_aniso_bias);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, m_minlod);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, m_maxlod);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, m_maxaniso);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//Unbind();
}
@ -207,7 +379,7 @@ public:
m_id = 0;
}
}
void Enable(bool enable) { m_enabled = enable; }
bool IsEnabled() const { return m_enabled; }
};
@ -217,6 +389,10 @@ struct TransformConstant
float x, y, z, w;
TransformConstant()
: x(0.0f)
, y(0.0f)
, z(0.0f)
, w(0.0f)
{
}
@ -310,6 +486,7 @@ private:
VertexProgram m_vertex_progs[m_vertex_count];
VertexProgram* m_cur_vertex_prog;
Array<TransformConstant> m_transform_constants;
Array<TransformConstant> m_fragment_constants;
Program m_program;
int m_fp_buf_num;
@ -318,8 +495,13 @@ private:
int m_draw_mode;
ProgramBuffer m_prog_buffer;
u32 m_width;
u32 m_height;
GLvao m_vao;
GLvbo m_vbo;
GLrbo m_rbo;
GLfbo m_fbo;
public:
GLGSFrame* m_frame;
@ -334,6 +516,7 @@ private:
void DisableVertexData();
void LoadVertexData(u32 first, u32 count);
void InitVertexData();
void InitFragmentData();
void Enable(bool enable, const u32 cap);
virtual void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress);

View File

@ -30,6 +30,17 @@ OPENGL_PROC(PFNGLBINDATTRIBLOCATIONPROC, BindAttribLocation);
OPENGL_PROC(PFNGLGETUNIFORMLOCATIONPROC, GetUniformLocation);
OPENGL_PROC(PFNGLGETPROGRAMIVPROC, GetProgramiv);
OPENGL_PROC(PFNGLGETPROGRAMINFOLOGPROC, GetProgramInfoLog);
OPENGL_PROC(PFNGLVERTEXATTRIB4BVPROC, VertexAttrib4bv);
OPENGL_PROC(PFNGLVERTEXATTRIB4UBVPROC, VertexAttrib4ubv);
OPENGL_PROC(PFNGLVERTEXATTRIB1SPROC, VertexAttrib1s);
OPENGL_PROC(PFNGLVERTEXATTRIB2SVPROC, VertexAttrib2sv);
OPENGL_PROC(PFNGLVERTEXATTRIB3SVPROC, VertexAttrib3sv);
OPENGL_PROC(PFNGLVERTEXATTRIB4SVPROC, VertexAttrib4sv);
OPENGL_PROC(PFNGLVERTEXATTRIB4IVPROC, VertexAttrib4iv);
OPENGL_PROC(PFNGLVERTEXATTRIB1FPROC, VertexAttrib1f);
OPENGL_PROC(PFNGLVERTEXATTRIB2FVPROC, VertexAttrib2fv);
OPENGL_PROC(PFNGLVERTEXATTRIB3FVPROC, VertexAttrib3fv);
OPENGL_PROC(PFNGLVERTEXATTRIB4FVPROC, VertexAttrib4fv);
OPENGL_PROC(PFNGLVERTEXATTRIBPOINTERPROC, VertexAttribPointer);
OPENGL_PROC(PFNGLENABLEVERTEXATTRIBARRAYPROC, EnableVertexAttribArray);
OPENGL_PROC(PFNGLDISABLEVERTEXATTRIBARRAYPROC, DisableVertexAttribArray);
@ -39,11 +50,49 @@ OPENGL_PROC(PFNGLDELETEVERTEXARRAYSPROC, DeleteVertexArrays);
OPENGL_PROC(PFNGLDEPTHRANGEFPROC, DepthRangef);
OPENGL_PROC(PFNGLUNIFORM1IPROC, Uniform1i);
OPENGL_PROC(PFNGLUNIFORM1FPROC, Uniform1f);
OPENGL_PROC(PFNGLUNIFORM1UIPROC, Uniform1ui);
OPENGL_PROC(PFNGLUNIFORM1IVPROC, Uniform1iv);
OPENGL_PROC(PFNGLUNIFORM1FVPROC, Uniform1fv);
OPENGL_PROC(PFNGLUNIFORM1UIVPROC, Uniform1uiv);
OPENGL_PROC(PFNGLUNIFORM2IPROC, Uniform2i);
OPENGL_PROC(PFNGLUNIFORM2FPROC, Uniform2f);
OPENGL_PROC(PFNGLUNIFORM2UIPROC, Uniform2ui);
OPENGL_PROC(PFNGLUNIFORM2IVPROC, Uniform2iv);
OPENGL_PROC(PFNGLUNIFORM2FVPROC, Uniform2fv);
OPENGL_PROC(PFNGLUNIFORM2UIVPROC, Uniform2uiv);
OPENGL_PROC(PFNGLUNIFORM3IPROC, Uniform3i);
OPENGL_PROC(PFNGLUNIFORM3FPROC, Uniform3f);
OPENGL_PROC(PFNGLUNIFORM3UIPROC, Uniform3ui);
OPENGL_PROC(PFNGLUNIFORM3IVPROC, Uniform3iv);
OPENGL_PROC(PFNGLUNIFORM3FVPROC, Uniform3fv);
OPENGL_PROC(PFNGLUNIFORM3UIVPROC, Uniform3uiv);
OPENGL_PROC(PFNGLUNIFORM4FPROC, Uniform4i);
OPENGL_PROC(PFNGLUNIFORM4FPROC, Uniform4f);
OPENGL_PROC(PFNGLUNIFORM4UIPROC, Uniform4ui);
OPENGL_PROC(PFNGLUNIFORM4IVPROC, Uniform4iv);
OPENGL_PROC(PFNGLUNIFORM4FVPROC, Uniform4fv);
OPENGL_PROC(PFNGLUNIFORM4UIVPROC, Uniform4uiv);
OPENGL_PROC(PFNGLPROGRAMUNIFORM1IPROC, ProgramUniform1i);
OPENGL_PROC(PFNGLPROGRAMUNIFORM1FPROC, ProgramUniform1f);
OPENGL_PROC(PFNGLPROGRAMUNIFORM4FPROC, ProgramUniform4f);
OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv);
OPENGL_PROC(PFNGLUSEPROGRAMPROC, UseProgram);
OPENGL_PROC2(PFNWGLSWAPINTERVALEXTPROC, SwapInterval, wglSwapIntervalEXT);
OPENGL_PROC2(PFNGLDEPTHBOUNDSEXTPROC, DepthBounds, glDepthBoundsEXT);
OPENGL_PROC2(PFNGLDEPTHBOUNDSEXTPROC, DepthBounds, glDepthBoundsEXT);
OPENGL_PROC(PFNGLSTENCILOPSEPARATEPROC, StencilOpSeparate);
OPENGL_PROC(PFNGLSTENCILFUNCSEPARATEPROC, StencilFuncSeparate);
OPENGL_PROC(PFNGLSTENCILMASKSEPARATEPROC, StencilMaskSeparate);
OPENGL_PROC(PFNGLCOMPRESSEDTEXIMAGE2DPROC, CompressedTexImage2D);
OPENGL_PROC(PFNGLGENERATEMIPMAPPROC, GenerateMipmap);
OPENGL_PROC(PFNGLBINDRENDERBUFFERPROC, BindRenderbuffer);
OPENGL_PROC(PFNGLDELETERENDERBUFFERSPROC, DeleteRenderbuffers);
OPENGL_PROC(PFNGLGENRENDERBUFFERSPROC, GenRenderbuffers);
OPENGL_PROC(PFNGLRENDERBUFFERSTORAGEPROC, RenderbufferStorage);
OPENGL_PROC(PFNGLBINDFRAMEBUFFERPROC, BindFramebuffer);
OPENGL_PROC(PFNGLDELETEFRAMEBUFFERSPROC, DeleteFramebuffers);
OPENGL_PROC(PFNGLGENFRAMEBUFFERSPROC, GenFramebuffers);
OPENGL_PROC(PFNGLFRAMEBUFFERTEXTURE1DPROC, FramebufferTexture1D);
OPENGL_PROC(PFNGLFRAMEBUFFERTEXTURE2DPROC, FramebufferTexture2D);
OPENGL_PROC(PFNGLFRAMEBUFFERTEXTURE3DPROC, FramebufferTexture3D);
OPENGL_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, FramebufferRenderbuffer);
OPENGL_PROC(PFNGLBLITFRAMEBUFFERPROC, BlitFramebuffer);

View File

@ -77,6 +77,7 @@ void Program::Create(const u32 vp, const u32 fp)
void Program::UnUse()
{
id = 0;
m_locations.Clear();
}
void Program::Use()
@ -87,14 +88,10 @@ void Program::Use()
void Program::SetTex(u32 index)
{
int loc = GetLocation(wxString::Format("tex%d", index));
checkForGlError(wxString::Format("GetLocation(tex%d)", index));
int loc = GetLocation(wxString::Format("tex%u", index));
checkForGlError(wxString::Format("GetLocation(tex%u)", index));
glProgramUniform1i(id, loc, index);
GLenum err = glGetError();
if(err != 0x502)
{
printGlError(err, wxString::Format("SetTex(%d - %d - %d)", id, index, loc));
}
checkForGlError(wxString::Format("SetTex(%u - %d - %d)", id, index, loc));
}
void Program::Delete()
@ -102,4 +99,5 @@ void Program::Delete()
if(!IsCreated()) return;
glDeleteProgram(id);
id = 0;
m_locations.Clear();
}

View File

@ -95,9 +95,16 @@ struct ParamArray
return wxEmptyString;
}
wxString AddParam(wxString type, const wxString& name, const wxString& value)
bool HasParam(const ParamFlag flag, wxString type, const wxString& name)
{
type = GetParamFlag(PARAM_CONST) + type;
type = GetParamFlag(flag) + type;
ParamType* t = SearchParam(type);
return t && t->SearchName(name);
}
wxString AddParam(const ParamFlag flag, wxString type, const wxString& name, const wxString& value)
{
type = GetParamFlag(flag) + type;
ParamType* t = SearchParam(type);
if(t)
@ -107,7 +114,7 @@ struct ParamArray
else
{
const u32 num = params.GetCount();
params.Move(new ParamType(PARAM_CONST, type));
params.Move(new ParamType(flag, type));
params[num].items.Move(new ParamItem(name, -1, value));
}

View File

@ -40,8 +40,8 @@ wxString VertexDecompilerThread::GetDST(bool isSca)
"gl_Position",
"col0", "col1",
"bfc0", "bfc1",
"fogc",
"gl_Pointsize",
"gl_ClipDistance[%d]",
"gl_ClipDistance[%d]",
"tc0", "tc1", "tc2", "tc3", "tc4", "tc5", "tc6", "tc7"
};
@ -49,12 +49,12 @@ wxString VertexDecompilerThread::GetDST(bool isSca)
switch(isSca ? 0x1f : d3.dst)
{
case 0x0: case 0x6:
case 0x0: case 0x5: case 0x6:
ret += reg_table[d3.dst];
break;
case 0x1f:
ret += m_parr.AddParam(PARAM_NONE, "vec4", wxString::Format("tmp%d", isSca ? d3.sca_dst_tmp : d0.dst_tmp));
ret += m_parr.AddParam(PARAM_NONE, "vec4", wxString::Format("tmp%u", isSca ? d3.sca_dst_tmp : d0.dst_tmp));
break;
default:
@ -90,7 +90,7 @@ wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca)
switch(src[n].reg_type)
{
case 1: //temp
ret += m_parr.AddParam(PARAM_NONE, "vec4", wxString::Format("tmp%d", src[n].tmp_src));
ret += m_parr.AddParam(PARAM_NONE, "vec4", wxString::Format("tmp%u", src[n].tmp_src));
break;
case 2: //input
if(d1.input_src < WXSIZEOF(reg_table))
@ -104,18 +104,16 @@ wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca)
}
break;
case 3: //const
ret += m_parr.AddParam(PARAM_UNIFORM, "vec4", wxString::Format("vc%d", d1.const_src));
ret += m_parr.AddParam(PARAM_UNIFORM, "vec4", wxString::Format("vc%u", d1.const_src));
break;
default:
ConLog.Error("Bad src%d reg type: %d", n, src[n].reg_type);
ConLog.Error("Bad src%u reg type: %d", n, src[n].reg_type);
Emu.Pause();
break;
}
static const char f[4] = {'x', 'y', 'z', 'w'};
wxString swizzle = wxEmptyString;
static const wxString f = "xyzw";
if (isSca)
{
@ -123,16 +121,19 @@ wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca)
assert(src[n].swz_z == src[n].swz_w);
assert(src[n].swz_x == src[n].swz_z);
ret += "." + f[src[n].swz_x];
ret += '.';
ret += f[src[n].swz_x];
}
else
{
wxString swizzle = wxEmptyString;
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 != "xyzw") ret += "." + swizzle;
if(swizzle != f) ret += '.' + swizzle;
}
bool abs;
@ -164,7 +165,7 @@ void VertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask)
if(d0.cond != (lt | gt | eq))
{
if(d0.cond & (lt | gt))
if((d0.cond & (lt | gt)) == (lt | gt))
{
cond = "!=";
}
@ -177,7 +178,7 @@ void VertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask)
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);
//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);
}
@ -188,7 +189,28 @@ void VertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask)
value = "clamp(" + value + ", 0.0, 1.0)";
}
code = cond + GetDST(is_sca) + GetMask(is_sca) + " = " + value;
wxString dest;
if(d3.dst == 5 || d3.dst == 6)
{
int num = d3.dst == 5 ? 0 : 3;
if(d3.vec_writemask_x)
{
ConLog.Error("Bad clip mask.");
}
//if(d3.vec_writemask_y) num += 0;
if(d3.vec_writemask_z) num += 1;
else if(d3.vec_writemask_w) num += 2;
dest = wxString::Format(GetDST(is_sca), num);
}
else
{
dest = GetDST(is_sca) + GetMask(is_sca);
}
code = cond + dest + " = " + value;
main += "\t" + code + ";\n";
}
@ -198,9 +220,9 @@ void VertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask)
AddCode(false, code, src_mask);
}
void VertexDecompilerThread::AddScaCode(const wxString& code, bool src_mask)
void VertexDecompilerThread::AddScaCode(const wxString& code)
{
AddCode(true, code, src_mask);
AddCode(true, code, false);
}
wxString VertexDecompilerThread::BuildCode()
@ -273,10 +295,10 @@ void VertexDecompilerThread::Task()
case 0x02: AddVecCode("(" + GetSRC(0) + " * " + GetSRC(1) + ")"); break; //MUL
case 0x03: AddVecCode("(" + GetSRC(0) + " + " + GetSRC(2) + ")"); break; //ADD
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 0x06: AddVecCode("(dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz) + " + GetSRC(1) + ".w)", false); break; //DPH
case 0x07: AddVecCode("dot(" + GetSRC(0) + ", " + GetSRC(1) + ")", false); break; //DP4
case 0x08: AddVecCode("distance(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //DST
case 0x05: AddVecCode("vec4(dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz)).xxxx"); break; //DP3
case 0x06: AddVecCode("vec4(dot(vec4(" + GetSRC(0) + ".xyz, 1), " + GetSRC(1) + ")).xxxx"); break; //DPH
case 0x07: AddVecCode("vec4(dot(" + GetSRC(0) + ", " + GetSRC(1) + ")).xxxx"); break; //DP4
case 0x08: AddVecCode("vec4(distance(" + GetSRC(0) + ", " + GetSRC(1) + ")).xxxx"); break; //DST
case 0x09: AddVecCode("min(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MIN
case 0x0a: AddVecCode("max(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MAX
case 0x0b: AddVecCode("vec4(lessThan(" + GetSRC(0) + ", " + GetSRC(1) + "))"); break; //SLT
@ -399,8 +421,7 @@ void VertexProgram::Delete()
}
VertexData::VertexData()
: index(0)
, frequency(0)
: frequency(0)
, stride(0)
, size(0)
, type(0)
@ -411,7 +432,6 @@ VertexData::VertexData()
void VertexData::Reset()
{
index = 0;
frequency = 0;
stride = 0;
size = 0;
@ -422,7 +442,10 @@ void VertexData::Reset()
void VertexData::Load(u32 start, u32 count)
{
if(!addr) return;
const u32 tsize = GetTypeSize();
data.SetCount((start + count) * tsize * size);
for(u32 i=start; i<start + count; ++i)

View File

@ -146,7 +146,7 @@ struct VertexDecompilerThread : public ThreadBase
wxString GetSRC(const u32 n, bool is_sca = false);
void AddCode(bool is_sca, wxString code, bool src_mask = true);
void AddVecCode(const wxString& code, bool src_mask = true);
void AddScaCode(const wxString& code, bool src_mask = true);
void AddScaCode(const wxString& code);
wxString BuildCode();
virtual void Task();
@ -178,12 +178,12 @@ struct VertexProgram
struct VertexData
{
u32 index;
u32 frequency;
u32 stride;
u32 size;
u32 type;
u32 addr;
u32 constant_count;
Array<u8> data;

View File

@ -8,7 +8,7 @@ BEGIN_EVENT_TABLE(GSFrame, wxFrame)
EVT_SIZE(GSFrame::OnSize)
END_EVENT_TABLE()
GSManager::GSManager() : m_render(NULL)
GSManager::GSManager() : m_render(nullptr)
{
}

View File

@ -78,9 +78,10 @@ void GSFrame::SetSize(int width, int height)
GSRender::GSRender()
: m_ctrl(NULL)
: m_ctrl(nullptr)
, m_flip_status(0)
, m_flip_mode(CELL_GCM_DISPLAY_VSYNC)
, m_main_mem_addr(0)
{
}
@ -88,9 +89,11 @@ u32 GSRender::GetAddress(u32 offset, u8 location)
{
switch(location)
{
case CELL_GCM_LOCATION_LOCAL: return Memory.RSXFBMem.GetStartAddr() + offset;
case CELL_GCM_LOCATION_MAIN: return offset;
case CELL_GCM_LOCATION_LOCAL: return m_local_mem_addr + offset;
case CELL_GCM_LOCATION_MAIN: return m_main_mem_addr + offset;
}
ConLog.Error("GetAddress(offset=0x%x, location=0x%x", location);
return 0;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "Emu/GS/GCM.h"
#include "Emu/SysCalls/Callback.h"
#include "rpcs3.h"
enum Method
{
@ -39,9 +40,109 @@ private:
DECLARE_EVENT_TABLE();
};
struct CellGcmSurface
{
u8 type;
u8 antialias;
u8 color_format;
u8 color_target;
u8 color_location[4];
u32 color_offset[4];
u32 color_pitch[4];
u8 depth_format;
u8 depth_location;
u16 pad;
u32 depth_offset;
u32 depth_pitch;
u16 width;
u16 height;
u16 x;
u16 y;
};
struct CellGcmReportData
{
u64 timer;
u32 value;
u32 pad;
};
struct CellGcmZcullInfo
{
u32 region;
u32 size;
u32 start;
u32 offset;
u32 status0;
u32 status1;
};
struct CellGcmTileInfo
{
u32 tile;
u32 limit;
u32 pitch;
u32 format;
};
struct GcmZcullInfo
{
u32 m_offset;
u32 m_width;
u32 m_height;
u32 m_cullStart;
u32 m_zFormat;
u32 m_aaFormat;
u32 m_zCullDir;
u32 m_zCullFormat;
u32 m_sFunc;
u32 m_sRef;
u32 m_sMask;
bool m_binded;
GcmZcullInfo()
{
memset(this, 0, sizeof(*this));
}
};
struct GcmTileInfo
{
u8 m_location;
u32 m_offset;
u32 m_size;
u32 m_pitch;
u8 m_comp;
u16 m_base;
u8 m_bank;
bool m_binded;
GcmTileInfo()
{
memset(this, 0, sizeof(*this));
}
CellGcmTileInfo Pack()
{
CellGcmTileInfo ret;
re(ret.tile, (m_location + 1) | (m_bank << 4) | ((m_offset / 0x10000) << 16) | (m_location << 31));
re(ret.limit, ((m_offset + m_size - 1) / 0x10000) << 16 | (m_location << 31));
re(ret.pitch, (m_pitch / 0x100) << 8);
re(ret.format, m_base | ((m_base + ((m_size - 1) / 0x10000)) << 13) | (m_comp << 26) | (1 << 30));
return ret;
}
};
static const int g_tiles_count = 15;
struct GSRender
{
u32 m_ioAddress, m_ioSize, m_ctrlAddress, m_localAddress;
u32 m_ioAddress, m_ioSize, m_ctrlAddress;
CellGcmControl* m_ctrl;
wxCriticalSection m_cs_main;
wxSemaphore m_sem_flush;
@ -51,9 +152,18 @@ struct GSRender
volatile bool m_draw;
Callback m_flip_handler;
GcmTileInfo m_tiles[g_tiles_count];
u32 m_tiles_addr;
u32 m_zculls_addr;
u32 m_gcm_buffers_addr;
u32 m_gcm_buffers_count;
u32 m_gcm_current_buffer;
u32 m_ctxt_addr;
u32 m_report_main_addr;
u32 m_local_mem_addr, m_main_mem_addr;
Array<MemInfo> m_main_mem_info;
GSRender();

View File

@ -71,7 +71,7 @@ private:
m_ioAddress = ioAddress;
m_ctrlAddress = ctrlAddress;
m_ioSize = ioSize;
m_localAddress = localAddress;
m_local_mem_addr = localAddress;
m_ctrl = (CellGcmControl*)Memory.GetMemFromAddr(m_ctrlAddress);
(m_rsx_thread = new NullRSXThread(this))->Start();

View File

@ -3,7 +3,7 @@
class ExecRSXCMDdata
{
protected:
public:
bool m_set_color_mask;
bool m_color_mask_r;
bool m_color_mask_g;
@ -21,6 +21,12 @@ protected:
bool m_set_blend;
bool m_set_depth_bounds_test;
bool m_depth_test_enable;
bool m_set_logic_op;
bool m_set_cull_face;
bool m_set_dither;
bool m_set_stencil_test;
bool m_set_line_smooth;
bool m_set_poly_smooth;
bool m_set_viewport_horizontal;
bool m_set_viewport_vertical;
@ -50,11 +56,6 @@ protected:
u16 m_blend_dfactor_rgb;
u16 m_blend_dfactor_alpha;
bool m_set_logic_op;
bool m_set_cull_face;
bool m_set_dither;
bool m_set_stencil_test;
bool m_set_stencil_mask;
u32 m_stencil_mask;
@ -76,6 +77,29 @@ protected:
bool m_set_stencil_zpass;
u32 m_stencil_zpass;
bool m_set_two_sided_stencil_test_enable;
bool m_set_back_stencil_mask;
u32 m_back_stencil_mask;
bool m_set_back_stencil_func;
u32 m_back_stencil_func;
bool m_set_back_stencil_func_ref;
u32 m_back_stencil_func_ref;
bool m_set_back_stencil_func_mask;
u32 m_back_stencil_func_mask;
bool m_set_back_stencil_fail;
u32 m_back_stencil_fail;
bool m_set_back_stencil_zfail;
u32 m_back_stencil_zfail;
bool m_set_back_stencil_zpass;
u32 m_back_stencil_zpass;
bool m_set_blend_equation;
u16 m_blend_equation_rgb;
u16 m_blend_equation_alpha;
@ -83,8 +107,6 @@ protected:
bool m_set_depth_mask;
u32 m_depth_mask;
bool m_set_line_smooth;
bool m_set_line_width;
u32 m_line_width;
@ -97,6 +119,85 @@ protected:
u8 m_blend_color_b;
u8 m_blend_color_a;
bool m_set_clear_color;
u8 m_clear_color_r;
u8 m_clear_color_g;
u8 m_clear_color_b;
u8 m_clear_color_a;
u32 m_context_dma_img_src;
u32 m_context_dma_img_dst;
u32 m_dst_offset;
u32 m_color_format;
u16 m_color_format_src_pitch;
u16 m_color_format_dst_pitch;
u32 m_color_conv;
u32 m_color_conv_fmt;
u32 m_color_conv_op;
u16 m_color_conv_in_x;
u16 m_color_conv_in_y;
u16 m_color_conv_in_w;
u16 m_color_conv_in_h;
u16 m_color_conv_out_x;
u16 m_color_conv_out_y;
u16 m_color_conv_out_w;
u16 m_color_conv_out_h;
u32 m_color_conv_dsdx;
u32 m_color_conv_dtdy;
bool m_set_semaphore_offset;
u32 m_semaphore_offset;
bool m_set_fog_mode;
u32 m_fog_mode;
bool m_set_fog_params;
float m_fog_param0;
float m_fog_param1;
bool m_set_clip_plane;
u32 m_clip_plane_0;
u32 m_clip_plane_1;
u32 m_clip_plane_2;
u32 m_clip_plane_3;
u32 m_clip_plane_4;
u32 m_clip_plane_5;
bool m_set_surface_format;
u8 m_surface_color_format;
u8 m_surface_depth_format;
u8 m_surface_type;
u8 m_surface_antialias;
u8 m_surface_width;
u8 m_surface_height;
u32 m_surface_pitch_a;
u32 m_surface_offset_a;
u32 m_surface_offset_z;
u32 m_surface_offset_b;
u32 m_surface_pitch_b;
bool m_set_context_dma_color_a;
u32 m_context_dma_color_a;
bool m_set_context_dma_color_b;
u32 m_context_dma_color_b;
bool m_set_context_dma_color_c;
u32 m_context_dma_color_c;
bool m_set_context_dma_z;
u32 m_context_dma_z;
bool m_set_surface_clip_horizontal;
u16 m_surface_clip_x;
u16 m_surface_clip_w;
bool m_set_surface_clip_vertical;
u16 m_surface_clip_y;
u16 m_surface_clip_h;
u8 m_begin_end;
public:
ExecRSXCMDdata()
{
@ -131,12 +232,34 @@ public:
m_set_stencil_fail = false;
m_set_stencil_zfail = false;
m_set_stencil_zpass = false;
m_set_two_sided_stencil_test_enable = false;
m_set_back_stencil_mask = false;
m_set_back_stencil_func = false;
m_set_back_stencil_func_ref = false;
m_set_back_stencil_func_mask = false;
m_set_back_stencil_fail = false;
m_set_back_stencil_zfail = false;
m_set_back_stencil_zpass = false;
m_set_blend_equation = false;
m_set_depth_mask = false;
m_set_line_smooth = false;
m_set_poly_smooth = false;
m_set_line_width = false;
m_set_shade_mode = false;
m_set_blend_color = false;
m_set_clear_color = false;
m_set_semaphore_offset = false;
m_set_fog_mode = false;
m_set_fog_params = false;
m_set_clip_plane = false;
m_set_surface_format = false;
m_set_context_dma_color_a = false;
m_set_context_dma_color_b = false;
m_set_context_dma_color_c = false;
m_set_context_dma_z = false;
m_set_surface_clip_horizontal = false;
m_set_surface_clip_vertical = false;
m_begin_end = 0;
}
virtual void ExecCMD()=0;

View File

@ -4,7 +4,7 @@
#include "Windows/WindowsPadHandler.h"
PadManager::PadManager()
: m_pad_handler(NULL)
: m_pad_handler(nullptr)
, m_inited(false)
{
}
@ -32,7 +32,7 @@ void PadManager::Init(const u32 max_connect)
void PadManager::Close()
{
if(m_pad_handler) m_pad_handler->Close();
m_pad_handler = NULL;
m_pad_handler = nullptr;
m_inited = false;
}

View File

@ -90,9 +90,11 @@ struct Button
u32 m_keyCode;
u32 m_outKeyCode;
bool m_pressed;
bool m_flush;
Button(u32 offset, u32 keyCode, u32 outKeyCode)
: m_pressed(false)
, m_flush(false)
, m_offset(offset)
, m_keyCode(keyCode)
, m_outKeyCode(outKeyCode)
@ -169,8 +171,8 @@ struct Pad
struct PadInfo
{
u32 max_connect;
u32 now_connect;
u32 system_info;
u32 now_connect;
u32 system_info;
};
class PadHandlerBase
@ -191,7 +193,14 @@ public:
{
Button& button = GetButtons(p).Get(b);
if(button.m_keyCode != code) continue;
button.m_pressed = pressed;
if(button.m_pressed && !pressed)
{
button.m_flush = true;
}
else
{
button.m_pressed = pressed;
}
}
}
}

View File

@ -1,14 +1,27 @@
#pragma once
struct MemBlockInfo
struct MemInfo
{
u64 addr;
u32 size;
MemInfo(u64 _addr, u32 _size)
: addr(_addr)
, size(_size)
{
}
MemInfo()
{
}
};
struct MemBlockInfo : public MemInfo
{
void* mem;
MemBlockInfo(u64 _addr, u32 _size)
: addr(_addr)
, size(_size)
: MemInfo(_addr, _size)
, mem(malloc(_size))
{
if(!mem)

View File

@ -286,19 +286,19 @@ s64 SysCalls::DoFunc(const u32 id)
case 0x72cc6cf7: FUNC_LOG_ERROR("TODO: cellGameGetHomeDataImportPath");
case 0x94e9f81d: FUNC_LOG_ERROR("TODO: cellGameGetHomeLaunchOptionPath");
case 0xf6acd0bc: FUNC_LOG_ERROR("TODO: cellGameGetBootGameInfo");
case 0x055bd74d: return cellGcmGetTiledPitchSize(SC_ARGS_1); //FUNC_LOG_ERROR("TODO: cellGcmGetTiledPitchSize");
case 0x055bd74d: FUNC_LOG_ERROR("TODO: cellGcmGetTiledPitchSize");
case 0x06edea9e: FUNC_LOG_ERROR("TODO: cellGcmSetUserHandler");
case 0x0a862772: FUNC_LOG_ERROR("TODO: cellGcmSetQueueHandler");
case 0x0b4b62d5: FUNC_LOG_ERROR("TODO: cellGcmSetPrepareFlip");
case 0x0e6b0dae: FUNC_LOG_ERROR("TODO: cellGcmGetDisplayInfo");
case 0x107bf3a1: FUNC_LOG_ERROR("TODO: cellGcmInitCursor");
case 0x15bae46b: return cellGcmInit(SC_ARGS_4);//FUNC_LOG_ERROR("TODO: _cellGcmInitBody");
case 0x15bae46b: FUNC_LOG_ERROR("TODO: _cellGcmInitBody");
case 0x172c3197: FUNC_LOG_ERROR("TODO: cellGcmSetDefaultCommandBufferAndSegmentWordSize");
case 0x1a0de550: FUNC_LOG_ERROR("TODO: cellGcmSetCursorPosition");
case 0x1bd633f8: FUNC_LOG_ERROR("TODO: _cellGcmFunc3");
case 0x1f61b3ff: FUNC_LOG_ERROR("TODO: cellGcmDumpGraphicsError");
case 0x21397818: return cellGcmFlush(SC_ARGS_2); //FUNC_LOG_ERROR("TODO: _cellGcmSetFlipCommand");
case 0x21ac3697: return cellGcmAddressToOffset(SC_ARGS_2); //FUNC_LOG_ERROR("TODO: cellGcmAddressToOffset");
case 0x21397818: FUNC_LOG_ERROR("TODO: _cellGcmSetFlipCommand");
case 0x21ac3697: FUNC_LOG_ERROR("TODO: cellGcmAddressToOffset");
case 0x21cee035: FUNC_LOG_ERROR("TODO: cellGcmGetNotifyDataAddress");
case 0x23ae55a3: FUNC_LOG_ERROR("TODO: cellGcmGetLastSecondVTime");
case 0x25b40ab4: FUNC_LOG_ERROR("TODO: cellGcmSortRemapEaIoAddress");
@ -309,7 +309,7 @@ s64 SysCalls::DoFunc(const u32 id)
case 0x3a33c1fd: FUNC_LOG_ERROR("TODO: _cellGcmFunc15");
case 0x3b9bd5bd: FUNC_LOG_ERROR("TODO: cellGcmUnreserveIoMapSize");
case 0x4524cccd: FUNC_LOG_ERROR("TODO: cellGcmBindTile");
case 0x4ae8d215: return cellGcmSetFlipMode(SC_ARGS_1); //FUNC_LOG_ERROR("TODO: cellGcmSetFlipMode");
case 0x4ae8d215: FUNC_LOG_ERROR("TODO: cellGcmSetFlipMode");
case 0x4d7ce993: FUNC_LOG_ERROR("TODO: cellGcmSetSecondVFrequency");
case 0x51c9d62b: FUNC_LOG_ERROR("TODO: cellGcmSetDebugOutputLevel");
case 0x527c6439: FUNC_LOG_ERROR("TODO: cellGcmTerminate");
@ -318,13 +318,13 @@ s64 SysCalls::DoFunc(const u32 id)
case 0x5f909b17: FUNC_LOG_ERROR("TODO: _cellGcmFunc1");
case 0x626e8518: FUNC_LOG_ERROR("TODO: cellGcmMapEaIoAddressWithFlags");
case 0x63387071: FUNC_LOG_ERROR("TODO: cellGcmGetLastFlipTime");
case 0x63441cb4: return cellGcmMapEaIoAddress(SC_ARGS_3); //FUNC_LOG_ERROR("TODO: cellGcmMapEaIoAddress");
case 0x63441cb4: FUNC_LOG_ERROR("TODO: cellGcmMapEaIoAddress");
case 0x657571f7: FUNC_LOG_ERROR("TODO: cellGcmGetTileInfo");
case 0x661fe266: FUNC_LOG_ERROR("TODO: _cellGcmFunc12");
case 0x688b8ac9: FUNC_LOG_ERROR("TODO: _cellGcmFunc38");
case 0x69c6cc82: FUNC_LOG_ERROR("TODO: cellGcmSetCursorDisable");
case 0x723bbc7e: FUNC_LOG_ERROR("TODO: cellGcmGetVBlankCount");
case 0x72a577ce: return cellGcmGetFlipStatus(); //FUNC_LOG_ERROR("TODO: cellGcmGetFlipStatus");
case 0x72a577ce: FUNC_LOG_ERROR("TODO: cellGcmGetFlipStatus");
case 0x7fc034bc: FUNC_LOG_ERROR("TODO: _cellGcmFunc4");
case 0x8572bce2: FUNC_LOG_ERROR("TODO: cellGcmGetReportDataAddressLocation");
case 0x8bde5ebf: FUNC_LOG_ERROR("TODO: cellGcmSetUserCommand");
@ -336,17 +336,17 @@ s64 SysCalls::DoFunc(const u32 id)
case 0x9a0159af: FUNC_LOG_ERROR("TODO: cellGcmGetReportDataAddress");
case 0x9ba451e4: FUNC_LOG_ERROR("TODO: cellGcmSetDefaultFifoSize");
case 0x9dc04436: FUNC_LOG_ERROR("TODO: cellGcmBindZcull");
case 0xa114ec67: return cellGcmMapMainMemory(SC_ARGS_3); //FUNC_LOG_ERROR("TODO: cellGcmMapMainMemory");
case 0xa114ec67: FUNC_LOG_ERROR("TODO: cellGcmMapMainMemory");
case 0xa41ef7e8: FUNC_LOG_ERROR("TODO: cellGcmSetFlipHandler");
case 0xa47c09ff: FUNC_LOG_ERROR("TODO: cellGcmSetFlipStatus");
case 0xa53d12ae: return cellGcmSetDisplayBuffer(SC_ARGS_5); //FUNC_LOG_ERROR("TODO: cellGcmSetDisplayBuffer");
case 0xa547adde: return cellGcmGetControlRegister();//FUNC_LOG_ERROR("TODO: cellGcmGetControlRegister");
case 0xa53d12ae: FUNC_LOG_ERROR("TODO: cellGcmSetDisplayBuffer");
case 0xa547adde: FUNC_LOG_ERROR("TODO: cellGcmGetControlRegister");
case 0xa6b180ac: FUNC_LOG_ERROR("TODO: cellGcmGetReportDataLocation");
case 0xa75640e8: FUNC_LOG_ERROR("TODO: cellGcmUnbindZcull");
case 0xa7ede268: FUNC_LOG_ERROR("TODO: cellGcmReserveIoMapSize");
case 0xa91b0402: FUNC_LOG_ERROR("TODO: cellGcmSetVBlankHandler");
case 0xacee8542: FUNC_LOG_ERROR("TODO: cellGcmSetFlipImmediate");
case 0xb2e761d4: return cellGcmResetFlipStatus(); //FUNC_LOG_ERROR("TODO: cellGcmResetFlipStatus");
case 0xb2e761d4: FUNC_LOG_ERROR("TODO: cellGcmResetFlipStatus");
case 0xbb42a9dd: FUNC_LOG_ERROR("TODO: _cellGcmFunc13");
case 0xbc982946: FUNC_LOG_ERROR("TODO: cellGcmSetDefaultCommandBuffer");
case 0xbd100dbc: FUNC_LOG_ERROR("TODO: cellGcmSetTileInfo");
@ -356,7 +356,7 @@ s64 SysCalls::DoFunc(const u32 id)
case 0xc8f3bd09: FUNC_LOG_ERROR("TODO: cellGcmGetCurrentField");
case 0xcaabd992: FUNC_LOG_ERROR("TODO: cellGcmInitDefaultFifoMode");
case 0xd01b570d: FUNC_LOG_ERROR("TODO: cellGcmSetGraphicsHandler");
case 0xd0b1d189: cellGcmSetTile(SC_ARGS_8); return SC_ARGS_1;//FUNC_LOG_ERROR("TODO: cellGcmSetTile");
case 0xd0b1d189: ConLog.Error("TODO: cellGcmSetTile"); return SC_ARGS_1;
case 0xd34a420d: ConLog.Error("TODO: cellGcmSetZcull"); return SC_ARGS_1;
case 0xd8f88e1a: FUNC_LOG_ERROR("TODO: _cellGcmSetFlipCommandWithWaitLabel");
case 0xd9a0a879: FUNC_LOG_ERROR("TODO: cellGcmGetZcullInfo");
@ -366,10 +366,10 @@ s64 SysCalls::DoFunc(const u32 id)
case 0xdc09357e: FUNC_LOG_ERROR("TODO: cellGcmSetFlip");
case 0xdc494430: FUNC_LOG_ERROR("TODO: cellGcmSetSecondVHandler");
case 0xdf6476bd: FUNC_LOG_ERROR("TODO: cellGcmSetWaitFlipUnsafe");
case 0xe315a0b2: return cellGcmGetConfiguration(SC_ARGS_1); //FUNC_LOG_ERROR("TODO: cellGcmGetConfiguration");
case 0xe315a0b2: FUNC_LOG_ERROR("TODO: cellGcmGetConfiguration");
case 0xe44874f3: FUNC_LOG_ERROR("TODO: cellGcmSysGetLastVBlankTime");
case 0xefd00f54: FUNC_LOG_ERROR("TODO: cellGcmUnmapEaIoAddress");
case 0xf80196c1: return cellGcmGetLabelAddress(SC_ARGS_1); //FUNC_LOG_ERROR("TODO: cellGcmGetLabelAddress");
case 0xf80196c1: FUNC_LOG_ERROR("TODO: cellGcmGetLabelAddress");
case 0xf9bfdc72: FUNC_LOG_ERROR("TODO: cellGcmSetCursorImageOffset");
case 0xfb81c03e: FUNC_LOG_ERROR("TODO: cellGcmGetMaxIoMapSize");
case 0xfce9e764: FUNC_LOG_ERROR("TODO: cellGcmInitSystemMode");

View File

@ -6,16 +6,351 @@
void cellGcmSys_init();
Module cellGcmSys(0x0010, cellGcmSys_init);
enum
{
CELL_GCM_ERROR_FAILURE = 0x802100ff,
CELL_GCM_ERROR_INVALID_ENUM = 0x80210002,
CELL_GCM_ERROR_INVALID_VALUE = 0x80210003,
CELL_GCM_ERROR_INVALID_ALIGNMENT = 0x80210004,
};
CellGcmConfig current_config;
CellGcmContextData current_context;
gcmInfo gcm_info;
struct gcm_offset
{
u16 ea;
u16 offset;
};
u32 map_offset_addr = 0;
u32 map_offset_pos = 0;
int cellGcmMapMainMemory(u32 address, u32 size, u32 offset_addr)
{
cellGcmSys.Warning("cellGcmMapMainMemory(address=0x%x,size=0x%x,offset_addr=0x%x)", address, size, offset_addr);
if(!Memory.IsGoodAddr(offset_addr, sizeof(u32))) return CELL_EFAULT;
Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress;
u32 offset = address - Emu.GetGSManager().GetRender().m_main_mem_addr;
Emu.GetGSManager().GetRender().m_main_mem_info.AddCpy(MemInfo(address, size));
Memory.Write32(offset_addr, offset);
return CELL_OK;
}
int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
{
cellGcmSys.Log("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress);
const u32 local_size = 0xf900000; //TODO
const u32 local_addr = Memory.RSXFBMem.GetStartAddr();
map_offset_addr = 0;
map_offset_pos = 0;
current_config.ioSize = re32(ioSize);
current_config.ioAddress = re32(ioAddress);
current_config.localSize = re32(local_size);
current_config.localAddress = re32(local_addr);
current_config.memoryFrequency = re32(650000000);
current_config.coreFrequency = re32(500000000);
Memory.RSXFBMem.Alloc(local_size);
Memory.RSXCMDMem.Alloc(cmdSize);
u32 ctx_begin = ioAddress/* + 0x1000*/;
u32 ctx_size = 0x6ffc;
current_context.begin = re(ctx_begin);
current_context.end = re(ctx_begin + ctx_size);
current_context.current = current_context.begin;
current_context.callback = re32(Emu.GetRSXCallback() - 4);
gcm_info.context_addr = Memory.MainMem.Alloc(0x1000);
gcm_info.control_addr = gcm_info.context_addr + 0x40;
Memory.WriteData(gcm_info.context_addr, current_context);
Memory.Write32(context_addr, gcm_info.context_addr);
CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr];
ctrl.put = 0;
ctrl.get = 0;
ctrl.ref = -1;
auto& render = Emu.GetGSManager().GetRender();
render.m_ctxt_addr = context_addr;
render.m_gcm_buffers_addr = Memory.Alloc(sizeof(gcmBuffer) * 8, sizeof(gcmBuffer));
render.m_zculls_addr = Memory.Alloc(sizeof(CellGcmZcullInfo) * 8, sizeof(CellGcmZcullInfo));
render.m_tiles_addr = Memory.Alloc(sizeof(CellGcmTileInfo) * 15, sizeof(CellGcmTileInfo));
render.m_gcm_buffers_count = 0;
render.m_gcm_current_buffer = 0;
render.m_main_mem_info.Clear();
render.m_main_mem_addr = 0;
render.Init(ctx_begin, ctx_size, gcm_info.control_addr, local_addr);
return CELL_OK;
}
int cellGcmGetConfiguration(u32 config_addr)
{
cellGcmSys.Log("cellGcmGetConfiguration(config_addr=0x%x)", config_addr);
if(!Memory.IsGoodAddr(config_addr, sizeof(CellGcmConfig))) return CELL_EFAULT;
Memory.WriteData(config_addr, current_config);
return CELL_OK;
}
int cellGcmAddressToOffset(u32 address, u32 offset_addr)
{
cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset_addr);
if(!Memory.IsGoodAddr(offset_addr, sizeof(u32))) return CELL_EFAULT;
if(!map_offset_addr)
{
map_offset_addr = Memory.Alloc(4*50, 4);
}
u32 sa;
bool is_main_mem = false;
const auto& main_mem_info = Emu.GetGSManager().GetRender().m_main_mem_info;
for(u32 i=0; i<Emu.GetGSManager().GetRender().m_main_mem_info.GetCount(); ++i)
{
//main memory
if(address >= main_mem_info[i].addr && address < main_mem_info[i].addr + main_mem_info[i].size)
{
is_main_mem = true;
break;
}
}
if(is_main_mem)
{
//main
sa = Emu.GetGSManager().GetRender().m_main_mem_addr;
//ConLog.Warning("cellGcmAddressToOffset: main memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
}
else if(Memory.RSXFBMem.IsMyAddress(address))
{
//local
sa = Emu.GetGSManager().GetRender().m_local_mem_addr;
//ConLog.Warning("cellGcmAddressToOffset: local memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
}
else
{
//io
sa = Emu.GetGSManager().GetRender().m_ioAddress;
//ConLog.Warning("cellGcmAddressToOffset: io memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
}
u32 offset = address - sa;
//Memory.Write16(map_offset_addr + map_offset_pos + 0, ea);
//Memory.Write16(map_offset_addr + map_offset_pos + 2, offset);
//map_offset_pos += 4;
Memory.Write32(offset_addr, offset);
return CELL_OK;
}
int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height)
{
cellGcmSys.Warning("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)",
id, offset, width ? pitch/width : pitch, width, height);
if(id > 7) return CELL_EINVAL;
gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(Emu.GetGSManager().GetRender().m_gcm_buffers_addr);
buffers[id].offset = re(offset);
buffers[id].pitch = re(pitch);
buffers[id].width = re(width);
buffers[id].height = re(height);
if(id + 1 > Emu.GetGSManager().GetRender().m_gcm_buffers_count)
{
Emu.GetGSManager().GetRender().m_gcm_buffers_count = id + 1;
}
return CELL_OK;
}
u32 cellGcmGetLabelAddress(u8 index)
{
cellGcmSys.Log("cellGcmGetLabelAddress(index=%d)", index);
return Memory.RSXCMDMem.GetStartAddr() + 0x10 * index;
}
u32 cellGcmGetControlRegister()
{
cellGcmSys.Log("cellGcmGetControlRegister()");
return gcm_info.control_addr;
}
int cellGcmSetPrepareFlip(u32 ctx, u32 id)
{
cellGcmSys.Log("cellGcmSetPrepareFlip(ctx=0x%x, id=0x%x)", ctx, id);
if(id >= 8)
{
return CELL_GCM_ERROR_FAILURE;
}
GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH);
CellGcmContextData& ctxt = (CellGcmContextData&)Memory[ctx];
u32 current = re(ctxt.current);
u32 end = re(ctxt.end);
if(current + 8 >= end)
{
ConLog.Warning("bad flip!");
cellGcmCallback(ctx, current + 8 - end);
}
current = re(ctxt.current);
Memory.Write32(current, 0x3fead | (1 << 18));
Memory.Write32(current + 4, id);
re(ctxt.current, current + 8);
if(ctx == gcm_info.context_addr)
{
CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr];
re(ctrl.put, re(ctrl.put) + 8);
}
return id;
}
int cellGcmSetFlipCommand(u32 ctx, u32 id)
{
return cellGcmSetPrepareFlip(ctx, id);
}
int cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, u32 zFormat, u32 aaFormat, u32 zCullDir, u32 zCullFormat, u32 sFunc, u32 sRef, u32 sMask)
{
cellGcmSys.Warning("TODO: cellGcmSetZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x)",
index, offset, width, height, cullStart, zFormat, aaFormat, zCullDir, zCullFormat, sFunc, sRef, sMask);
return CELL_OK;
}
int cellGcmBindZcull(u8 index)
{
cellGcmSys.Warning("TODO: cellGcmBindZcull(index=%d)", index);
return CELL_OK;
}
u32 cellGcmGetZcullInfo()
{
cellGcmSys.Warning("cellGcmGetZcullInfo()");
return Emu.GetGSManager().GetRender().m_zculls_addr;
}
int cellGcmGetFlipStatus()
{
return Emu.GetGSManager().GetRender().m_flip_status;
}
int cellGcmResetFlipStatus()
{
Emu.GetGSManager().GetRender().m_flip_status = 1;
return CELL_OK;
}
int cellGcmSetFlipMode(u32 mode)
{
cellGcmSys.Warning("cellGcmSetFlipMode(mode=%d)", mode);
switch(mode)
{
case CELL_GCM_DISPLAY_HSYNC:
case CELL_GCM_DISPLAY_VSYNC:
case CELL_GCM_DISPLAY_HSYNC_WITH_NOISE:
Emu.GetGSManager().GetRender().m_flip_mode = mode;
break;
default:
return CELL_EINVAL;
}
return CELL_OK;
}
u32 cellGcmGetTiledPitchSize(u32 size)
{
//TODO
cellGcmSys.Warning("cellGcmGetTiledPitchSize(size=%d)", size);
return size;
}
u32 cellGcmGetDefaultCommandWordSize()
{
cellGcmSys.Warning("cellGcmGetDefaultCommandWordSize()");
return 0x400;
}
u32 cellGcmGetDefaultSegmentWordSize()
{
cellGcmSys.Warning("cellGcmGetDefaultSegmentWordSize()");
return 0x100;
}
int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize)
{
cellGcmSys.Warning("cellGcmSetDefaultFifoSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize);
return CELL_OK;
}
int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size)
{
cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size);
Memory.Map(io, ea, size);
Emu.GetGSManager().GetRender().m_report_main_addr = ea;
return CELL_OK;
}
int cellGcmUnbindZcull(u8 index)
{
cellGcmSys.Warning("cellGcmUnbindZcull(index=%d)", index);
if(index >= 8)
return CELL_EINVAL;
return CELL_OK;
}
u64 cellGcmGetTimeStamp(u32 index)
{
cellGcmSys.Log("cellGcmGetTimeStamp(index=%d)", index);
return Memory.Read64(Memory.RSXFBMem.GetStartAddr() + index * 0x10);
}
int cellGcmSetFlipHandler(u32 handler_addr)
{
cellGcmSys.Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler_addr);
if(!Memory.IsGoodAddr(handler_addr) && handler_addr != 0)
{
return CELL_EFAULT;
}
Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr);
return 0;
}
s64 cellGcmFunc15()
{
cellGcmSys.Error("cellGcmFunc15()");
return 0;
}
s64 cellGcmSetFlipCommandWithWaitLabel()
int cellGcmSetFlipCommandWithWaitLabel(u32 ctx, u32 id, u32 label_index, u32 label_value)
{
cellGcmSys.Error("cellGcmSetFlipCommandWithWaitLabel()");
return 0;
int res = cellGcmSetPrepareFlip(ctx, id);
Memory.Write32(Memory.RSXCMDMem.GetStartAddr() + 0x10 * label_index, label_value);
return res == CELL_GCM_ERROR_FAILURE ? CELL_GCM_ERROR_FAILURE : CELL_OK;
}
int cellGcmInitCursor()
@ -80,14 +415,114 @@ int cellGcmGetCurrentDisplayBufferId(u32 id_addr)
return CELL_OK;
}
void cellGcmSetDefaultCommandBuffer()
{
cellGcmSys.Warning("cellGcmSetDefaultCommandBuffer()");
Memory.Write32(Emu.GetGSManager().GetRender().m_ctxt_addr, gcm_info.context_addr);
}
void cellGcmSetFlipStatus()
{
cellGcmSys.Warning("cellGcmSetFlipStatus()");
Emu.GetGSManager().GetRender().m_flip_status = 0;
}
int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank)
{
cellGcmSys.Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)",
index, location, offset, size, pitch, comp, base, bank);
if(index >= g_tiles_count || base >= 800 || bank >= 4)
{
return CELL_GCM_ERROR_INVALID_VALUE;
}
if(offset & 0xffff || size & 0xffff || pitch & 0xf)
{
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
}
if(location >= 2 || (comp != 0 && (comp < 7 || comp > 12)))
{
return CELL_GCM_ERROR_INVALID_ENUM;
}
if(comp)
{
cellGcmSys.Error("cellGcmSetTileInfo: bad comp! (%d)", comp);
}
auto& tile = Emu.GetGSManager().GetRender().m_tiles[index];
tile.m_location = location;
tile.m_offset = offset;
tile.m_size = size;
tile.m_pitch = pitch;
tile.m_comp = comp;
tile.m_base = base;
tile.m_bank = bank;
Memory.WriteData(Emu.GetGSManager().GetRender().m_tiles_addr + sizeof(CellGcmTileInfo) * index, tile.Pack());
return CELL_OK;
}
int cellGcmBindTile(u8 index)
{
cellGcmSys.Warning("cellGcmBindTile(index=%d)", index);
if(index >= g_tiles_count)
{
return CELL_GCM_ERROR_INVALID_VALUE;
}
auto& tile = Emu.GetGSManager().GetRender().m_tiles[index];
tile.m_binded = true;
return CELL_OK;
}
int cellGcmUnbindTile(u8 index)
{
cellGcmSys.Warning("cellGcmUnbindTile(index=%d)", index);
if(index >= g_tiles_count)
{
return CELL_GCM_ERROR_INVALID_VALUE;
}
auto& tile = Emu.GetGSManager().GetRender().m_tiles[index];
tile.m_binded = false;
return CELL_OK;
}
u32 cellGcmGetTileInfo()
{
cellGcmSys.Warning("cellGcmGetTileInfo()");
return Emu.GetGSManager().GetRender().m_tiles_addr;
}
int cellGcmInitDefaultFifoMode(int mode)
{
cellGcmSys.Warning("cellGcmInitDefaultFifoMode(mode=%d)", mode);
return CELL_OK;
}
u32 cellGcmGetReportDataAddressLocation(u8 location, u32 index)
{
ConLog.Warning("cellGcmGetReportDataAddressLocation(location=%d, index=%d)", location, index);
return Emu.GetGSManager().GetRender().m_report_main_addr;
}
void cellGcmSys_init()
{
cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize);
cellGcmSys.AddFunc(0x15bae46b, cellGcmInit);
cellGcmSys.AddFunc(0x21397818, cellGcmFlush);
cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand);
cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset);
cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15);
cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode);
cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress);
cellGcmSys.AddFunc(0x5e2ee0f0, cellGcmGetDefaultCommandWordSize);
cellGcmSys.AddFunc(0x72a577ce, cellGcmGetFlipStatus);
cellGcmSys.AddFunc(0x8cdf8c70, cellGcmGetDefaultSegmentWordSize);
@ -98,6 +533,8 @@ void cellGcmSys_init()
cellGcmSys.AddFunc(0xd8f88e1a, cellGcmSetFlipCommandWithWaitLabel);
cellGcmSys.AddFunc(0xe315a0b2, cellGcmGetConfiguration);
cellGcmSys.AddFunc(0x9dc04436, cellGcmBindZcull);
cellGcmSys.AddFunc(0xd34a420d, cellGcmSetZcull);
cellGcmSys.AddFunc(0xd9a0a879, cellGcmGetZcullInfo);
cellGcmSys.AddFunc(0x5a41c10f, cellGcmGetTimeStamp);
cellGcmSys.AddFunc(0xd9b7653e, cellGcmUnbindTile);
cellGcmSys.AddFunc(0xa75640e8, cellGcmUnbindZcull);
@ -113,4 +550,12 @@ void cellGcmSys_init()
cellGcmSys.AddFunc(0xf9bfdc72, cellGcmSetCursorImageOffset);
cellGcmSys.AddFunc(0x0e6b0dae, cellGcmGetDisplayInfo);
cellGcmSys.AddFunc(0x93806525, cellGcmGetCurrentDisplayBufferId);
cellGcmSys.AddFunc(0xbc982946, cellGcmSetDefaultCommandBuffer);
cellGcmSys.AddFunc(0xa47c09ff, cellGcmSetFlipStatus);
cellGcmSys.AddFunc(0xbd100dbc, cellGcmSetTileInfo);
cellGcmSys.AddFunc(0x4524cccd, cellGcmBindTile);
cellGcmSys.AddFunc(0x0b4b62d5, cellGcmSetPrepareFlip);
cellGcmSys.AddFunc(0x657571f7, cellGcmGetTileInfo);
cellGcmSys.AddFunc(0xcaabd992, cellGcmInitDefaultFifoMode);
cellGcmSys.AddFunc(0x8572bce2, cellGcmGetReportDataAddressLocation);
}

View File

@ -0,0 +1,39 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h"
#include "Emu/GS/GCM.h"
void cellRecs_init();
Module cellRecs(0x001f, cellRecs_init);
int cellRescSetConvertAndFlip(s32 indx)
{
cellRecs.Log("cellRescSetConvertAndFlip(indx=0x%x)", indx);
Emu.GetGSManager().GetRender().Draw();
return CELL_OK;
}
int cellRescSetWaitFlip()
{
return CELL_OK;
}
int cellRescSetFlipHandler(u32 handler_addr)
{
cellRecs.Warning("cellRescSetFlipHandler(handler_addr=%d)", handler_addr);
if(!Memory.IsGoodAddr(handler_addr) && handler_addr != 0)
{
return CELL_EFAULT;
}
Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr);
return 0;
}
void cellRecs_init()
{
cellRecs.AddFunc(0x25c107e6, cellRescSetConvertAndFlip);
cellRecs.AddFunc(0x0d3c22ce, cellRescSetWaitFlip);
cellRecs.AddFunc(0x2ea94661, cellRescSetFlipHandler);
}

View File

@ -35,7 +35,7 @@ static func_caller* sc_table[1024] =
null_func, null_func, null_func, null_func, null_func, //124
null_func, null_func, null_func, bind_func(sys_event_queue_create), null_func, //129
bind_func(sys_event_queue_receive), null_func, null_func, null_func, bind_func(sys_event_port_create), //134
null_func, bind_func(sys_event_port_connect_local), null_func, null_func, null_func, //139
null_func, bind_func(sys_event_port_connect_local), null_func, bind_func(sys_event_port_send), null_func, //139
null_func, null_func, null_func, null_func, null_func, //144
bind_func(sys_time_get_current_time), bind_func(sys_time_get_system_time), bind_func(sys_time_get_timebase_frequency), null_func, null_func, //149
null_func, null_func, null_func, null_func, null_func, //154

View File

@ -118,6 +118,7 @@ extern int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_q
extern int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout);
extern int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name);
extern int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id);
extern int sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3);
//sys_semaphore
extern int sys_semaphore_create(u32 sem_addr, u32 attr_addr, int initial_val, int max_val);
@ -216,30 +217,7 @@ extern int cellPadGetInfo2(u32 info_addr);
extern int cellPadSetPortSetting(u32 port_no, u32 port_setting);
//cellGcm
extern int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress);
extern int cellGcmMapMainMemory(u32 address, u32 size, u32 offset_addr);
extern int cellGcmCallback(u32 context_addr, u32 count);
extern int cellGcmGetConfiguration(u32 config_addr);
extern int cellGcmAddressToOffset(u32 address, u32 offset_addr);
extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height);
extern u32 cellGcmGetLabelAddress(u8 index);
extern u32 cellGcmGetControlRegister();
extern int cellGcmFlush(u32 ctx, u32 id);
extern void cellGcmSetTile(u32 index, u32 location, u32 offset, u32 size, u32 pitch, u32 comp, u32 base, u32 bank);
extern int cellGcmBindTile(u32 index);
extern int cellGcmBindZcull(u32 index, u32 offset, u32 width, u32 height, u32 cullStart, u32 zFormat, u32 aaFormat, u32 zCullDir, u32 zCullFormat, u32 sFunc, u32 sRef, u32 sMask);
extern int cellGcmGetFlipStatus();
extern int cellGcmResetFlipStatus();
extern u32 cellGcmGetTiledPitchSize(u32 size);
extern int cellGcmSetFlipMode(u32 mode);
extern u32 cellGcmGetDefaultCommandWordSize();
extern u32 cellGcmGetDefaultSegmentWordSize();
extern int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize);
extern int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size);
extern int cellGcmUnbindTile(u8 index);
extern int cellGcmUnbindZcull(u8 index);
extern u64 cellGcmGetTimeStamp(u32 index);
extern int cellGcmSetFlipHandler(u32 handler_addr);
//sys_tty
extern int sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr);

View File

@ -95,7 +95,7 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
GetCurrentPPUThread().WaitFor(queue_receive);
return CELL_OK;
return result;
}
int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name)
@ -110,6 +110,7 @@ int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name)
EventPort* eport = new EventPort();
u32 id = sys_event.GetNewId(eport);
eport->pos = 0;
eport->has_data = false;
eport->name = name ? name : id;
Memory.Write32(eport_id_addr, id);
@ -130,6 +131,37 @@ int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id)
EventPort* eport = (EventPort*)Emu.GetIdManager().GetIDData(event_port_id).m_data;
EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(event_queue_id).m_data;
equeue->ports[equeue->pos++] = eport;
eport->queue[eport->pos++] = equeue;
return CELL_OK;
}
int sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3)
{
sys_event.Warning("sys_event_port_send(event_port_id=0x%x, data1=0x%llx, data2=0x%llx, data3=0x%llx)",
event_port_id, data1, data2, data3);
if(!sys_event.CheckId(event_port_id))
{
return CELL_ESRCH;
}
EventPort* eport = (EventPort*)Emu.GetIdManager().GetIDData(event_port_id).m_data;
if(!eport->pos)
{
return CELL_ENOTCONN;
}
if(eport->has_data)
{
return CELL_EBUSY;
}
eport->has_data = true;
eport->data1 = data1;
eport->data2 = data2;
eport->data3 = data3;
return CELL_OK;
}

View File

@ -247,7 +247,13 @@ int cellFsStat(const u32 path_addr, const u32 sb_addr)
const wxString& path = Memory.ReadString(path_addr);
sys_fs.Log("cellFsFstat(path: %s, sb_addr: 0x%x)", path, sb_addr);
if(!wxFileExists(path)) return CELL_ENOENT;
vfsStream* f = Emu.GetVFS().Open(path, vfsRead);
if(!f || !f->IsOpened())
{
sys_fs.Warning("cellFsFstat: '%s' not found.", path);
Emu.GetVFS().Close(f);
return CELL_ENOENT;
}
Lv2FsStat stat;
stat.st_mode =
@ -261,7 +267,7 @@ int cellFsStat(const u32 path_addr, const u32 sb_addr)
stat.st_atime = 0; //TODO
stat.st_mtime = 0; //TODO
stat.st_ctime = 0; //TODO
stat.st_size = wxFile(path).Length();
stat.st_size = f->GetSize();
stat.st_blksize = 4096;
mem_class_t stat_c(sb_addr);
@ -274,6 +280,8 @@ int cellFsStat(const u32 path_addr, const u32 sb_addr)
stat_c += stat.st_size;
stat_c += stat.st_blksize;
Emu.GetVFS().Close(f);
return CELL_OK;
}

View File

@ -3,73 +3,7 @@
#include "Emu/GS/GCM.h"
extern Module cellGcmSys;
CellGcmConfig current_config;
CellGcmContextData current_context;
gcmInfo gcm_info;
struct gcm_offset
{
u16 ea;
u16 offset;
};
u32 map_offset_addr = 0;
u32 map_offset_pos = 0;
int cellGcmMapMainMemory(u32 address, u32 size, u32 offset_addr)
{
cellGcmSys.Warning("cellGcmMapMainMemory(address=0x%x,size=0x%x,offset_addr=0x%x)", address, size, offset_addr);
if(!Memory.IsGoodAddr(offset_addr, sizeof(u32))) return CELL_EFAULT;
Memory.Write32(offset_addr, address & 0xffff);
return CELL_OK;
}
int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
{
cellGcmSys.Log("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress);
const u32 local_size = 0xf900000; //TODO
const u32 local_addr = Memory.RSXFBMem.GetStartAddr();
map_offset_addr = 0;
map_offset_pos = 0;
current_config.ioSize = re32(ioSize);
current_config.ioAddress = re32(ioAddress);
current_config.localSize = re32(local_size);
current_config.localAddress = re32(local_addr);
current_config.memoryFrequency = re32(650000000);
current_config.coreFrequency = re32(500000000);
Memory.RSXFBMem.Alloc(local_size);
Memory.RSXCMDMem.Alloc(cmdSize);
u32 ctx_begin = ioAddress + 0x1000;
u32 ctx_size = 0x6ffc;
current_context.begin = re(ctx_begin);
current_context.end = re(ctx_begin + ctx_size);
current_context.current = current_context.begin;
current_context.callback = re32(Emu.GetRSXCallback() - 4);
gcm_info.context_addr = Memory.MainMem.Alloc(0x1000);
gcm_info.control_addr = gcm_info.context_addr + 0x40;
Memory.WriteData(gcm_info.context_addr, current_context);
Memory.Write32(context_addr, gcm_info.context_addr);
CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr];
ctrl.put = 0;
ctrl.get = 0;
ctrl.ref = -1;
Emu.GetGSManager().GetRender().m_gcm_buffers_addr = Memory.Alloc(sizeof(gcmBuffer) * 8, sizeof(gcmBuffer));
Emu.GetGSManager().GetRender().m_gcm_buffers_count = 0;
Emu.GetGSManager().GetRender().m_gcm_current_buffer = 0;
Emu.GetGSManager().GetRender().Init(ctx_begin, ctx_size, gcm_info.control_addr, local_addr);
return CELL_OK;
}
extern gcmInfo gcm_info;
int cellGcmCallback(u32 context_addr, u32 count)
{
@ -89,201 +23,3 @@ int cellGcmCallback(u32 context_addr, u32 count)
return CELL_OK;
}
int cellGcmGetConfiguration(u32 config_addr)
{
cellGcmSys.Log("cellGcmGetConfiguration(config_addr=0x%x)", config_addr);
if(!Memory.IsGoodAddr(config_addr, sizeof(CellGcmConfig))) return CELL_EFAULT;
Memory.WriteData(config_addr, current_config);
return CELL_OK;
}
int cellGcmAddressToOffset(u32 address, u32 offset_addr)
{
cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset_addr);
if(!Memory.IsGoodAddr(offset_addr, sizeof(u32))) return CELL_EFAULT;
if(!map_offset_addr)
{
map_offset_addr = Memory.Alloc(4*50, 4);
}
u32 sa = Memory.RSXFBMem.IsInMyRange(address) ? Memory.RSXFBMem.GetStartAddr() : re(current_context.begin);
u16 ea = (sa + address - sa) >> 16;
u32 offset = address - sa;
//Memory.Write16(map_offset_addr + map_offset_pos + 0, ea);
//Memory.Write16(map_offset_addr + map_offset_pos + 2, offset);
//map_offset_pos += 4;
Memory.Write32(offset_addr, offset);
return CELL_OK;
}
int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height)
{
cellGcmSys.Warning("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)",
id, offset, width ? pitch/width : pitch, width, height);
if(id > 7) return CELL_EINVAL;
gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(Emu.GetGSManager().GetRender().m_gcm_buffers_addr);
buffers[id].offset = re(offset);
buffers[id].pitch = re(pitch);
buffers[id].width = re(width);
buffers[id].height = re(height);
if(id + 1 > Emu.GetGSManager().GetRender().m_gcm_buffers_count)
{
Emu.GetGSManager().GetRender().m_gcm_buffers_count = id + 1;
}
return CELL_OK;
}
u32 cellGcmGetLabelAddress(u8 index)
{
cellGcmSys.Log("cellGcmGetLabelAddress(index=%d)", index);
return Memory.RSXCMDMem.GetStartAddr() + 0x10 * index;
}
u32 cellGcmGetControlRegister()
{
cellGcmSys.Log("cellGcmGetControlRegister()");
return gcm_info.control_addr;
}
int cellGcmFlush(u32 ctx, u32 id)
{
cellGcmSys.Log("cellGcmFlush(ctx=0x%x, id=0x%x)", ctx, id);
if(id > 1) return CELL_EINVAL;
Emu.GetGSManager().GetRender().Draw();
return CELL_OK;
}
void cellGcmSetTile(u32 index, u32 location, u32 offset, u32 size, u32 pitch, u32 comp, u32 base, u32 bank)
{
cellGcmSys.Warning("cellGcmSetTile(index=%d, location=%d, offset=0x%x, size=0x%x, pitch=0x%x, comp=0x%x, base=0x%x, bank=0x%x)",
index, location, offset, size, pitch, comp, base, bank);
//return CELL_OK;
}
int cellGcmBindTile(u32 index)
{
cellGcmSys.Warning("TODO: cellGcmBindTile(index=%d)", index);
return CELL_OK;
}
int cellGcmBindZcull(u32 index, u32 offset, u32 width, u32 height, u32 cullStart, u32 zFormat, u32 aaFormat, u32 zCullDir, u32 zCullFormat, u32 sFunc, u32 sRef, u32 sMask)
{
cellGcmSys.Warning("TODO: cellGcmBindZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x)", index, offset, width, height, cullStart, zFormat, aaFormat, zCullDir, zCullFormat, sFunc, sRef, sMask);
return CELL_OK;
}
int cellGcmGetFlipStatus()
{
return Emu.GetGSManager().GetRender().m_flip_status;
}
int cellGcmResetFlipStatus()
{
Emu.GetGSManager().GetRender().m_flip_status = 1;
return CELL_OK;
}
int cellGcmSetFlipMode(u32 mode)
{
cellGcmSys.Warning("cellGcmSetFlipMode(mode=%d)", mode);
switch(mode)
{
case CELL_GCM_DISPLAY_HSYNC:
case CELL_GCM_DISPLAY_VSYNC:
case CELL_GCM_DISPLAY_HSYNC_WITH_NOISE:
Emu.GetGSManager().GetRender().m_flip_mode = mode;
break;
default:
return CELL_EINVAL;
}
return CELL_OK;
}
u32 cellGcmGetTiledPitchSize(u32 size)
{
//TODO
cellGcmSys.Warning("cellGcmGetTiledPitchSize(size=%d)", size);
return size;
}
u32 cellGcmGetDefaultCommandWordSize()
{
cellGcmSys.Warning("cellGcmGetDefaultCommandWordSize()");
return 0x400;
}
u32 cellGcmGetDefaultSegmentWordSize()
{
cellGcmSys.Warning("cellGcmGetDefaultSegmentWordSize()");
return 0x100;
}
int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize)
{
cellGcmSys.Warning("cellGcmSetDefaultFifoSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize);
return CELL_OK;
}
int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size)
{
cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size);
Memory.Map(io, ea, size);
return CELL_OK;
}
int cellGcmUnbindTile(u8 index)
{
cellGcmSys.Warning("cellGcmUnbindTile(index=%d)", index);
if(index >= 15)
return CELL_EINVAL;
return CELL_OK;
}
int cellGcmUnbindZcull(u8 index)
{
cellGcmSys.Warning("cellGcmUnbindZcull(index=%d)", index);
if(index >= 8)
return CELL_EINVAL;
return CELL_OK;
}
u64 cellGcmGetTimeStamp(u32 index)
{
cellGcmSys.Log("cellGcmGetTimeStamp(index=%d)", index);
return Memory.Read64(Memory.RSXFBMem.GetStartAddr() + index * 0x10);
}
int cellGcmSetFlipHandler(u32 handler_addr)
{
cellGcmSys.Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler_addr);
if(!Memory.IsGoodAddr(handler_addr) && handler_addr != 0)
{
return CELL_EFAULT;
}
Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr);
return 0;
}

View File

@ -87,6 +87,12 @@ int cellPadGetData(u32 port_no, u32 data_addr)
case CELL_PAD_BTN_OFFSET_DIGITAL1: if(!(d1 & buttons[i].m_outKeyCode)){d1 |= buttons[i].m_outKeyCode; len++;} break;
case CELL_PAD_BTN_OFFSET_DIGITAL2: if(!(d2 & buttons[i].m_outKeyCode)){d2 |= buttons[i].m_outKeyCode; len++;} break;
}
if(buttons[i].m_flush)
{
buttons[i].m_pressed = false;
buttons[i].m_flush = false;
}
}
data.len = re(len);

View File

@ -11,7 +11,11 @@ int sys_process_getpid()
int sys_process_exit(int errorcode)
{
ConLog.Warning("sys_process_exit(%d)", errorcode);
#ifdef _DEBUG
Emu.Pause();
#else
Emu.Stop();
#endif
return CELL_OK;
}

View File

@ -196,7 +196,14 @@ void Emulator::Run()
//m_memory_viewer->ShowPC();
if(!m_dbg_console)
{
m_dbg_console = new DbgConsole();
}
else
{
GetDbgCon().Close();
GetDbgCon().Clear();
}
GetGSManager().Init();
GetCallbackManager().Init();
@ -260,12 +267,6 @@ void Emulator::Stop()
CurGameInfo.Reset();
Memory.Close();
if(m_dbg_console)
{
GetDbgCon().Close();
GetDbgCon().Clear();
}
//if(m_memory_viewer && m_memory_viewer->IsShown()) m_memory_viewer->Hide();
wxGetApp().SendDbgCommand(DID_STOPED_EMU);
}

View File

@ -15,6 +15,8 @@ struct sys_event_data
u64 data3;
};
struct EventQueue;
struct EventPort
{
u64 name;
@ -23,6 +25,8 @@ struct EventPort
u64 data3;
bool has_data;
PPCThread* thread;
EventQueue* queue[127];
int pos;
};
struct EventQueue

View File

@ -324,7 +324,7 @@ void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
m_btn_run->Enable();
m_btn_step->Enable();
m_btn_pause->Disable();
//DoUpdate();
DoUpdate();
break;
case DID_START_THREAD:
@ -510,7 +510,7 @@ void InterpreterDisAsmFrame::Task()
{
if(!CPU) return;
wxGetApp().SendDbgCommand(DID_RESUME_THREAD, CPU);
wxGetApp().SendDbgCommand(DID_RESUMED_THREAD, CPU);
bool dump_status = dump_enable;
//CPU.InitTls();
@ -535,4 +535,5 @@ void InterpreterDisAsmFrame::Task()
//CPU.FreeTls();
wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, CPU);
wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, CPU);
}

View File

@ -155,8 +155,8 @@ bool ELF64Loader::LoadShdrInfo(s64 offset)
shdr_name_arr.Clear();
if(ehdr.e_shoff == 0 && ehdr.e_shnum)
{
ConLog.Error("LoadShdr64 error: Section header offset is null!");
return false;
ConLog.Warning("LoadShdr64 error: Section header offset is null!");
return true;
}
elf64_f.Seek(offset < 0 ? ehdr.e_shoff : offset);

View File

@ -246,6 +246,7 @@
<ClCompile Include="Emu\SysCalls\lv2\SC_TTY.cpp" />
<ClCompile Include="Emu\SysCalls\Modules.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellGcmSys.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellResc.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellSysmodule.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellSysutil.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\sysPrxForUser.cpp" />

View File

@ -283,6 +283,9 @@
<ClCompile Include="Emu\SysCalls\Modules\cellSysutil.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\Modules\cellResc.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="rpcs3.rc" />