diff --git a/rpcs3/Emu/FS/VFS.h b/rpcs3/Emu/FS/VFS.h index d46182fc51..2a09f20b74 100644 --- a/rpcs3/Emu/FS/VFS.h +++ b/rpcs3/Emu/FS/VFS.h @@ -20,7 +20,11 @@ struct VFSManagerEntry char* mount; vfsDeviceType device; - VFSManagerEntry() : device(vfsDevice_LocalFile) + VFSManagerEntry() + : device(vfsDevice_LocalFile) + , device_path("") + , path("") + , mount("") { } }; diff --git a/rpcs3/Emu/GS/GL/GLVertexProgram.cpp b/rpcs3/Emu/GS/GL/GLVertexProgram.cpp index 6dca47ffe7..96232ebd02 100644 --- a/rpcs3/Emu/GS/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/GS/GL/GLVertexProgram.cpp @@ -151,7 +151,7 @@ wxString GLVertexDecompilerThread::GetSRC(const u32 n, bool isSca) return ret; } -void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask) +void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask, bool set_dst) { if(d0.cond == 0) return; enum @@ -179,7 +179,7 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask } //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.mb_str()); + cond = wxString::Format("if(rc %s 0) ", cond.mb_str()); } wxString value = src_mask ? code + GetMask(is_sca) : code; @@ -189,40 +189,100 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask value = "clamp(" + value + ", 0.0, 1.0)"; } - wxString dest; - if(d3.dst == 5 || d3.dst == 6) + if(set_dst) { - int num = d3.dst == 5 ? 0 : 3; - - if(d3.vec_writemask_x) + wxString dest; + if(d0.cond_update_enable_0) { - ConLog.Error("Bad clip mask."); + dest = m_parr.AddParam(PARAM_NONE, "float", "rc"); + } + else 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); } - //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); + code = cond + dest + " = " + value; } else { - dest = GetDST(is_sca) + GetMask(is_sca); + code = cond + value; } - code = cond + dest + " = " + value; - - main += "\t" + code + ";\n"; + m_body.Add(code + wxString::Format(";//%d %d %d %d", d0.cond_reg_sel_1, d0.cond_test_enable, d0.cond_update_enable_0, d0.cond_update_enable_1)); } -void GLVertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask) +wxString GLVertexDecompilerThread::GetFunc() { - AddCode(false, code, src_mask); + u32 offset = (d2.iaddrh << 3) | d3.iaddrl; + wxString name = wxString::Format("func%u", offset); + + for(uint i=0; i=0; --i) + { + fp += wxString::Format("void %s();\n", m_funcs[i].name.mb_str()); + } + + wxString f = wxEmptyString; + + f += wxString::Format("void %s()\n{\n\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n%s}\n", m_funcs[0].name.mb_str(), BuildFuncBody(m_funcs[0]).mb_str()); + + for(uint i=1; i m_funcs; + + //wxString main; wxString& m_shader; Array& m_data; GLParamArray& m_parr; @@ -138,6 +148,10 @@ struct GLVertexDecompilerThread : public ThreadBase , m_shader(shader) , m_parr(parr) { + m_funcs.Add(new FuncInfo()); + m_funcs[0].offset = 0; + m_funcs[0].name = "main"; + //m_cur_func->body = "\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"; } wxString GetMask(bool is_sca); @@ -145,9 +159,11 @@ struct GLVertexDecompilerThread : public ThreadBase wxString GetScaMask(); wxString GetDST(bool is_sca = false); 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); + wxString GetFunc(); + void AddCode(bool is_sca, wxString code, bool src_mask = true, bool set_dst = true); + void AddVecCode(const wxString& code, bool src_mask = true, bool set_dst = true); + void AddScaCode(const wxString& code, bool set_dst = true); + wxString BuildFuncBody(const FuncInfo& func); wxString BuildCode(); virtual void Task(); diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index c8f4c84c19..626b7c4236 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -104,6 +104,41 @@ u32 RSXVertexData::GetTypeSize() index = (cmd - a) / m; \ case a \ +#define case_32(a, m) \ + case a + m: \ + case a + m * 2: \ + case a + m * 3: \ + case a + m * 4: \ + case a + m * 5: \ + case a + m * 6: \ + case a + m * 7: \ + case a + m * 8: \ + case a + m * 9: \ + case a + m * 10: \ + case a + m * 11: \ + case a + m * 12: \ + case a + m * 13: \ + case a + m * 14: \ + case a + m * 15: \ + case a + m * 16: \ + case a + m * 17: \ + case a + m * 18: \ + case a + m * 19: \ + case a + m * 20: \ + case a + m * 21: \ + case a + m * 22: \ + case a + m * 23: \ + case a + m * 24: \ + case a + m * 25: \ + case a + m * 26: \ + case a + m * 27: \ + case a + m * 28: \ + case a + m * 29: \ + case a + m * 30: \ + case a + m * 31: \ + index = (cmd - a) / m; \ + case a \ + void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count) { #if CMD_DEBUG @@ -170,6 +205,13 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 //ConLog.Warning("texture addr = 0x%x #offset = 0x%x, location=%d", tex_addr, offset, location); tex.SetOffset(tex_addr); tex.SetFormat(cubemap, dimension, format, mipmap); + + if(!tex.m_width || !tex.m_height) + { + gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(m_gcm_buffers_addr); + if(!tex.m_width) tex.m_width = re(buffers[m_gcm_current_buffer].width); + if(!tex.m_height) tex.m_height = re(buffers[m_gcm_current_buffer].height); + } } break; @@ -308,10 +350,24 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 { RSXTexture& tex = m_textures[index]; - const u16 height = args[0] & 0xffff; - const u16 width = args[0] >> 16; + u16 height = args[0] & 0xffff; + u16 width = args[0] >> 16; CMD_LOG("width=%d, height=%d", width, height); + + if(!width || !height) + { + ConLog.Warning("Bad texture rect: %dx%d (%dx%d)", width, height, tex.m_width, tex.m_height); + for(int i=0; idata.Clear(); @@ -677,8 +735,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 } break; - case NV4097_SET_TRANSFORM_PROGRAM: + case_32(NV4097_SET_TRANSFORM_PROGRAM, 4): { + //ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM[%d](%d)", index, count); + if(!m_cur_vertex_prog) { ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM: m_cur_vertex_prog == NULL"); diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index 48bdb55bfd..7f43d589a0 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -226,7 +226,7 @@ class RSXThread : public ThreadBase { public: static const uint m_textures_count = 16; - static const uint m_vertex_count = 16; + static const uint m_vertex_count = 32; static const uint m_fragment_count = 16; static const uint m_tiles_count = 15; diff --git a/rpcs3/Emu/SysCalls/Callback.cpp b/rpcs3/Emu/SysCalls/Callback.cpp index c062292092..af7013fd8e 100644 --- a/rpcs3/Emu/SysCalls/Callback.cpp +++ b/rpcs3/Emu/SysCalls/Callback.cpp @@ -9,7 +9,9 @@ Callback::Callback(u32 slot, u64 addr) , a1(0) , a2(0) , a3(0) + , a4(0) , m_has_data(false) + , m_name("Callback") { } @@ -38,11 +40,12 @@ bool Callback::HasData() const return m_has_data; } -void Callback::Handle(u64 _a1, u64 _a2, u64 _a3) +void Callback::Handle(u64 _a1, u64 _a2, u64 _a3, u64 _a4) { a1 = _a1; a2 = _a2; a3 = _a3; + a4 = _a4; m_has_data = true; } @@ -55,11 +58,12 @@ void Callback::Branch(bool wait) new_thread.SetEntry(m_addr); new_thread.SetPrio(1001); new_thread.SetStackSize(0x10000); - new_thread.SetName("Callback"); + new_thread.SetName(m_name); new_thread.SetArg(0, a1); new_thread.SetArg(1, a2); new_thread.SetArg(2, a3); + new_thread.SetArg(3, a4); new_thread.Run(); new_thread.Exec(); @@ -68,6 +72,11 @@ void Callback::Branch(bool wait) GetCurrentPPCThread()->Wait(new_thread); } +void Callback::SetName(const std::string& name) +{ + m_name = name; +} + Callback::operator bool() const { return GetAddr() != 0; diff --git a/rpcs3/Emu/SysCalls/Callback.h b/rpcs3/Emu/SysCalls/Callback.h index 49395f3527..a21709aee0 100644 --- a/rpcs3/Emu/SysCalls/Callback.h +++ b/rpcs3/Emu/SysCalls/Callback.h @@ -8,10 +8,13 @@ protected: bool m_has_data; + std::string m_name; + public: u64 a1; u64 a2; u64 a3; + u64 a4; u32 GetSlot() const; u64 GetAddr() const; @@ -20,8 +23,9 @@ public: bool HasData() const; Callback(u32 slot = 0, u64 addr = 0); - void Handle(u64 a1 = 0, u64 a2 = 0, u64 a3 = 0); + void Handle(u64 a1 = 0, u64 a2 = 0, u64 a3 = 0, u64 a4 = 0); void Branch(bool wait); + void SetName(const std::string& name); operator bool() const; }; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index d904646a77..297335e8e1 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -135,6 +135,79 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) return CELL_OK; } +/*struct CellFsAio +{ + be_t fd; + be_t offset; + be_t buf_addr; + be_t size; + be_t user_data; +}; + +int cellFsAioRead(mem_ptr_t aio, mem32_t id, mem32_t func_addr) +{ + if(!aio.IsGood() || !id.IsGood() || !func_addr.IsGood()) + return CELL_EFAULT; + + //CellFsAio *xaio, CellFsErrno error, int xid, uint64_t size; + Callback callback; + callback.SetAddr(func_addr); + callback.SetName("cellFsAioReadCallback"); + MemoryAllocator> nread; + int error = cellFsRead(aio->fd, id.GetAddr(), aio->size, nread); + callback.Handle(aio.GetAddr(), error, id, *nread); + callback.Branch(true); + + return CELL_OK; +}*/ + +std::atomic g_FsAioReadID = 0; + +int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, u32 func_addr) +{ + ID id; + u32 fd = (u32)aio->fd; + if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; + vfsFileBase& orig_file = *(vfsFileBase*)id.m_data; + //open the file again (to prevent access conflicts roughly) + vfsStream& file = vfsLocalFile(orig_file.GetPath().AfterFirst('/'), vfsRead); + + u64 nbytes = (u64)aio->size; + const u32 buf_addr = (u32)aio->buf_addr; + if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) + { + MemoryBlock& block = Memory.GetMemByAddr(buf_addr); + nbytes = block.GetSize() - (buf_addr - block.GetStartAddr()); + } + + //read data immediately (actually it should be read in special thread) + file.Seek((u64)aio->offset); + const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; + file.Close(); + + //get a unique id for the callback + const u32 xid = g_FsAioReadID++; + aio_id = xid; + + sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x[%s], id_addr: 0x%x, func_addr: 0x%x[res=%d, addr=0x%x])", aio.GetAddr(), + orig_file.GetPath().c_str(), aio_id.GetAddr(), func_addr, res, (u32)aio->buf_addr); + + //TODO: init the callback + CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); + new_thread.SetEntry(func_addr); + new_thread.SetPrio(1001); + new_thread.SetStackSize(0x10000); + new_thread.SetName("FsAioReadCallback"); + new_thread.SetArg(0, aio.GetAddr()); //xaio + new_thread.SetArg(1, CELL_OK); //error code + new_thread.SetArg(2, xid); //xid (unique id) + new_thread.SetArg(3, res); //size (bytes read) + new_thread.Run(); + new_thread.Exec(); + + return CELL_OK; +} + void sys_fs_init() { sys_fs.AddFunc(0x718bf5f8, cellFsOpen); @@ -155,6 +228,5 @@ void sys_fs_init() sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate); sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate); sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize); - sys_fs.AddFunc(0xc1c507e7, cellFsAioRead); } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index 67574f3a15..8e873b7972 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -385,50 +385,3 @@ int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size) return CELL_OK; } - -std::atomic g_FsAioReadID = 0; - -int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, u32 func_addr) -{ - ID id; - u32 fd = (u32)aio->fd; - if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - vfsFileBase& orig_file = *(vfsFileBase*)id.m_data; - //open the file again (to prevent access conflicts roughly) - vfsStream& file = vfsLocalFile(orig_file.GetPath().AfterFirst('/'), vfsRead); - - u64 nbytes = (u64)aio->size; - const u32 buf_addr = (u32)aio->buf_addr; - if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) - { - MemoryBlock& block = Memory.GetMemByAddr(buf_addr); - nbytes = block.GetSize() - (buf_addr - block.GetStartAddr()); - } - - //read data immediately (actually it should be read in special thread) - file.Seek((u64)aio->offset); - const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; - file.Close(); - - //get a unique id for the callback - const u32 xid = g_FsAioReadID++; - aio_id = xid; - - sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x[%s], id_addr: 0x%x, func_addr: 0x%x[res=%d, addr=0x%x])", aio.GetAddr(), - orig_file.GetPath().c_str(), aio_id.GetAddr(), func_addr, res, (u32)aio->buf_addr); - - //TODO: init the callback - CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); - new_thread.SetEntry(func_addr); - new_thread.SetPrio(1001); - new_thread.SetStackSize(0x10000); - new_thread.SetName("FsAioReadCallback"); - new_thread.SetArg(0, aio.GetAddr()); //xaio - new_thread.SetArg(1, CELL_OK); //error code - new_thread.SetArg(2, xid); //xid (unique id) - new_thread.SetArg(3, res); //size (bytes read) - new_thread.Run(); - new_thread.Exec(); - - return CELL_OK; -} diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index 1b07784925..2f1c27f98c 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -33,6 +33,23 @@ u32 LoadSpuImage(vfsStream& stream, u32& spu_ep) spu_ep = l.GetEntry(); return spu_offset; } +/*u64 g_last_spu_offset = 0; +static const u64 g_spu_alloc_size = 0x1000000; + +u32 LoadSpuImage(vfsStream& stream, u64 address) +{ + ELFLoader l(stream); + l.LoadInfo(); + l.LoadData(address); + + return address + l.GetEntry(); +} + +u32 LoadSpuImage(vfsStream& stream) +{ + g_last_spu_offset = Memory.MainMem.Alloc(g_spu_alloc_size); + return LoadSpuImage(stream, g_last_spu_offset); +}*/ //156 int sys_spu_image_open(mem_ptr_t img, u32 path_addr) diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index d675ab8b3f..5f5beceeb7 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -493,7 +493,7 @@ void RSXDebugger::GetTexture() m_list_texture->SetItem(i, 5, wxString::Format("0x%x", render.m_textures[i].m_format)); m_list_texture->SetItem(i, 6, wxString::Format("0x%x", render.m_textures[i].m_mipmap)); m_list_texture->SetItem(i, 7, wxString::Format("0x%x", render.m_textures[i].m_pitch)); - m_list_texture->SetItem(i, 8, wxString::Format("%d x %d", + m_list_texture->SetItem(i, 8, wxString::Format("%dx%d", render.m_textures[i].m_width, render.m_textures[i].m_height)); diff --git a/rpcs3/Gui/VFSManager.cpp b/rpcs3/Gui/VFSManager.cpp index 44d276b398..2215be3949 100644 --- a/rpcs3/Gui/VFSManager.cpp +++ b/rpcs3/Gui/VFSManager.cpp @@ -188,7 +188,7 @@ void VFSManagerDialog::OnAdd(wxCommandEvent& event) m_list->SetItemState(i, i == idx ? wxLIST_STATE_SELECTED : ~wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); } - wxCommandEvent ce; + wxCommandEvent ce; OnEntryConfig(ce); }