-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TESTERS NEEDED] cellAtracXdec implementation #15538
base: master
Are you sure you want to change the base?
Conversation
ensure(handle.aligned(0x80)); // LLE cellAdec aligns the address to 128 bytes | ||
ensure(!!notifyAuDone && !!notifyAuDoneArg && !!notifyPcmOut && !!notifyPcmOutArg && !!notifyError && !!notifyErrorArg && !!notifySeqDone && !!notifySeqDoneArg); // These should always be set by LLE cellAdec | ||
|
||
new (handle.get_ptr()) AtracXdecContext(notifyAuDone, notifyAuDoneArg, notifyPcmOut, notifyPcmOutArg, notifyError, notifyErrorArg, notifySeqDone, notifySeqDoneArg, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Write out the context using wrote_to_ptr.
handle, notifyAuDone, notifyAuDoneArg, notifyPcmOut, notifyPcmOutArg, notifyError, notifyErrorArg, notifySeqDone, notifySeqDoneArg, res, spursRes); | ||
|
||
ensure(!!handle && !!res); // Not checked on LLE | ||
ensure(handle.aligned(0x80)); // LLE cellAdec aligns the address to 128 bytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then align it down manually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my comment there was a bit confusing. This function on LLE does not align the address manually or check the alignment. I've rewritten it to make it clearer.
return handle->send_command<AtracXdecCmdType::decode_au>(ppu, pcmHandle, *auInfo); | ||
} | ||
|
||
void _CellAdecCoreOpGetVersion_atracx(vm::ptr<std::array<u8, 4>> version) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simply use vm::ptr<u8[4]>, I think its unspecifued behavior for std::array to match c array in byte size.
// For savestates, restore argument | ||
idm::get<named_thread<ppu_thread>>(static_cast<u32>(atxdec->thread_id))->cmd_list | ||
({ | ||
{ ppu_cmd::set_args, 1 }, static_cast<u64>(atxdec.addr()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Dont check thread_state::state for it, check cpu_flag::again state if it was raised inside exec(). (checking the reason the thread was aborted)
- When ::again flag is set, whats saved in r3 to r6 is ppu_thread::syscall_args, so you rather save to syscall_args[0] instead of this.
queue_not_empty.wait(queue_mutex, 20000); | ||
} | ||
|
||
if (!run_thread || thread_ctrl::state() == thread_state::aborting) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather, check cpu_thread::is_stopped(), raise ::again flag if stopped.
{ | ||
ensure(!!handle && !!pcmStartAddr); // Not checked on LLE | ||
|
||
std::memcpy(outBuffer.get_ptr(), pcmStartAddr.get_ptr(), handle->decoder.pcm_output_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be an assert before this, checking memory safety with vm::check_addr.
|
||
if (sample >= std::bit_cast<f32>(std::bit_cast<u32>(1.f) - 1)) | ||
{ | ||
output_f32[sample_idx * decoder.nch_in + ATXDEC_AVCODEC_CH_MAP[decoder.ch_config_idx - 1][channel_idx]] = std::bit_cast<be_t<f32>>(std::array<u8, 4>{ 0x3f, 0x7f, 0xff, 0xff }); // Prevents an unnecessary endian swap |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can do something like "\x37\x7f\xff\xff"_u32 (resulting in u32)
Known issues
The issue is caused by the game sending invalid data to the decoder. The thread "bnusCoreDecoderAT3PThread" then just exits when it receives the error. I assume this is because of a race condition in the game. I tried slowing down the decoder thread to match realhw as closely as possible, but that didn't improve anything.
I was able to trigger this issue in Tales of Xillia 1+2 and Tekken 6 as well, it's likely other NU engine games are also affected.
Setting PPU Thread Count to 1 still works around the issue with HLE.