mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
Add cellVdec hack (stolen TLS)
This commit is contained in:
parent
144f6809bf
commit
ab4e66a0bf
@ -3,6 +3,8 @@
|
|||||||
#include "Emu/IdManager.h"
|
#include "Emu/IdManager.h"
|
||||||
#include "Emu/Cell/PPUModule.h"
|
#include "Emu/Cell/PPUModule.h"
|
||||||
#include "Emu/Cell/lv2/sys_sync.h"
|
#include "Emu/Cell/lv2/sys_sync.h"
|
||||||
|
#include "Emu/Cell/lv2/sys_ppu_thread.h"
|
||||||
|
#include "sysPrxForUser.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -74,11 +76,14 @@ struct vdec_thread : ppu_thread
|
|||||||
u32 frc_set{}; // Frame Rate Override
|
u32 frc_set{}; // Frame Rate Override
|
||||||
u64 next_pts{};
|
u64 next_pts{};
|
||||||
u64 next_dts{};
|
u64 next_dts{};
|
||||||
|
u64 ppu_tid{};
|
||||||
|
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
std::queue<vdec_frame> out;
|
std::queue<vdec_frame> out;
|
||||||
u32 max_frames = 60;
|
u32 max_frames = 60;
|
||||||
|
|
||||||
|
atomic_t<u32> au_count{0};
|
||||||
|
|
||||||
vdec_thread(s32 type, u32 profile, u32 addr, u32 size, vm::ptr<CellVdecCbMsg> func, u32 arg, u32 prio, u32 stack)
|
vdec_thread(s32 type, u32 profile, u32 addr, u32 size, vm::ptr<CellVdecCbMsg> func, u32 arg, u32 prio, u32 stack)
|
||||||
: ppu_thread("HLE Video Decoder", prio, stack)
|
: ppu_thread("HLE Video Decoder", prio, stack)
|
||||||
, type(type)
|
, type(type)
|
||||||
@ -351,6 +356,11 @@ struct vdec_thread : ppu_thread
|
|||||||
cb_func(*this, id, vcmd == vdec_cmd::decode ? CELL_VDEC_MSG_TYPE_AUDONE : CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, cb_arg);
|
cb_func(*this, id, vcmd == vdec_cmd::decode ? CELL_VDEC_MSG_TYPE_AUDONE : CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, cb_arg);
|
||||||
lv2_obj::sleep(*this);
|
lv2_obj::sleep(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vcmd == vdec_cmd::decode)
|
||||||
|
{
|
||||||
|
au_count--;
|
||||||
|
}
|
||||||
|
|
||||||
while (std::lock_guard<std::mutex>{mutex}, max_frames && out.size() > max_frames)
|
while (std::lock_guard<std::mutex>{mutex}, max_frames && out.size() > max_frames)
|
||||||
{
|
{
|
||||||
@ -397,7 +407,7 @@ u32 vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0 */, vm::ptr<C
|
|||||||
attr->decoderVerLower = 0x280000; // from dmux
|
attr->decoderVerLower = 0x280000; // from dmux
|
||||||
attr->decoderVerUpper = 0x260000;
|
attr->decoderVerUpper = 0x260000;
|
||||||
attr->memSize = 4 * 1024 * 1024; // 4 MB
|
attr->memSize = 4 * 1024 * 1024; // 4 MB
|
||||||
attr->cmdDepth = 16;
|
attr->cmdDepth = 4;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,7 +425,7 @@ s32 cellVdecQueryAttrEx(vm::cptr<CellVdecTypeEx> type, vm::ptr<CellVdecAttr> att
|
|||||||
return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr);
|
return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cellVdecOpen(vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
|
s32 cellVdecOpen(ppu_thread& ppu, vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
|
||||||
{
|
{
|
||||||
cellVdec.warning("cellVdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
|
cellVdec.warning("cellVdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
|
||||||
|
|
||||||
@ -425,12 +435,17 @@ s32 cellVdecOpen(vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm
|
|||||||
// Hack: store thread id (normally it should be pointer)
|
// Hack: store thread id (normally it should be pointer)
|
||||||
*handle = vdec->id;
|
*handle = vdec->id;
|
||||||
|
|
||||||
|
vm::var<u64> _tid;
|
||||||
|
CALL_FUNC(ppu, sys_ppu_thread_create, ppu, +_tid, 1148, 0, 900, 0x4000, SYS_PPU_THREAD_CREATE_INTERRUPT, vm::null);
|
||||||
|
vdec->gpr[13] = idm::get<ppu_thread>(*_tid)->gpr[13];
|
||||||
|
vdec->ppu_tid = *_tid;
|
||||||
|
|
||||||
vdec->run();
|
vdec->run();
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cellVdecOpenEx(vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
|
s32 cellVdecOpenEx(ppu_thread& ppu, vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
|
||||||
{
|
{
|
||||||
cellVdec.warning("cellVdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
|
cellVdec.warning("cellVdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
|
||||||
|
|
||||||
@ -440,6 +455,11 @@ s32 cellVdecOpenEx(vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> r
|
|||||||
// Hack: store thread id (normally it should be pointer)
|
// Hack: store thread id (normally it should be pointer)
|
||||||
*handle = vdec->id;
|
*handle = vdec->id;
|
||||||
|
|
||||||
|
vm::var<u64> _tid;
|
||||||
|
CALL_FUNC(ppu, sys_ppu_thread_create, ppu, +_tid, 1148, 0, 900, 0x4000, SYS_PPU_THREAD_CREATE_INTERRUPT, vm::null);
|
||||||
|
vdec->gpr[13] = idm::get<ppu_thread>(*_tid)->gpr[13];
|
||||||
|
vdec->ppu_tid = *_tid;
|
||||||
|
|
||||||
vdec->run();
|
vdec->run();
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
@ -467,6 +487,8 @@ s32 cellVdecClose(ppu_thread& ppu, u32 handle)
|
|||||||
vdec->notify();
|
vdec->notify();
|
||||||
vdec->join();
|
vdec->join();
|
||||||
idm::remove<ppu_thread>(handle);
|
idm::remove<ppu_thread>(handle);
|
||||||
|
|
||||||
|
CALL_FUNC(ppu, sys_interrupt_thread_disestablish, ppu, vdec->ppu_tid);
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,6 +535,11 @@ s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInf
|
|||||||
return CELL_VDEC_ERROR_ARG;
|
return CELL_VDEC_ERROR_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vdec->au_count.fetch_op([](u32& c) { if (c < 4) c++; }) >= 4)
|
||||||
|
{
|
||||||
|
return CELL_VDEC_ERROR_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: check info
|
// TODO: check info
|
||||||
vdec->cmd_list
|
vdec->cmd_list
|
||||||
({
|
({
|
||||||
|
@ -52,6 +52,9 @@ error_code sys_lwcond_signal_all(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond);
|
|||||||
error_code sys_lwcond_signal_to(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_thread_id);
|
error_code sys_lwcond_signal_to(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_thread_id);
|
||||||
error_code sys_lwcond_wait(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout);
|
error_code sys_lwcond_wait(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout);
|
||||||
|
|
||||||
|
error_code sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::cptr<char> threadname);
|
||||||
|
error_code sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih);
|
||||||
|
|
||||||
void sys_ppu_thread_exit(ppu_thread& CPU, u64 val);
|
void sys_ppu_thread_exit(ppu_thread& CPU, u64 val);
|
||||||
void sys_game_process_exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags);
|
void sys_game_process_exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags);
|
||||||
void sys_game_process_exitspawn2(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags);
|
void sys_game_process_exitspawn2(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags);
|
||||||
|
@ -130,6 +130,12 @@ error_code _sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih, vm::ptr<u
|
|||||||
|
|
||||||
if (!handler)
|
if (!handler)
|
||||||
{
|
{
|
||||||
|
if (const auto thread = idm::withdraw<ppu_thread>(ih))
|
||||||
|
{
|
||||||
|
*r13 = thread->gpr[13];
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user