mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-10 00:41:26 +12:00
rsx: Move render flip from rsx queue command to flip command
This commit is contained in:
parent
35139ebf5d
commit
699eadc84f
9 changed files with 243 additions and 130 deletions
|
@ -18,6 +18,9 @@
|
|||
#include "Utilities/GSL.h"
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
||||
#include <cereal/archives/binary.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
#include <fenv.h>
|
||||
|
@ -364,6 +367,11 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
void thread::on_spawn()
|
||||
{
|
||||
m_rsx_thread = std::this_thread::get_id();
|
||||
}
|
||||
|
||||
void thread::on_task()
|
||||
{
|
||||
if (supports_native_ui)
|
||||
|
@ -1348,6 +1356,12 @@ namespace rsx
|
|||
|
||||
void thread::do_local_task(FIFO_state state)
|
||||
{
|
||||
if (test(async_flip_requested, flip_request::emu_requested))
|
||||
{
|
||||
handle_emu_flip(async_flip_buffer);
|
||||
async_flip_requested.test_and_reset(flip_request::emu_requested);
|
||||
}
|
||||
|
||||
if (!in_begin_end && state != FIFO_state::lock_wait)
|
||||
{
|
||||
reader_lock lock(m_mtx_task);
|
||||
|
@ -2790,6 +2804,139 @@ namespace rsx
|
|||
return performance_counters.approximate_load;
|
||||
}
|
||||
|
||||
void thread::request_emu_flip(u32 buffer)
|
||||
{
|
||||
const bool is_rsxthr = std::this_thread::get_id() == m_rsx_thread;
|
||||
|
||||
// requested through command buffer
|
||||
if (is_rsxthr)
|
||||
{
|
||||
// async flip hasnt been handled before next requested...?
|
||||
if (test(async_flip_requested, flip_request::emu_requested))
|
||||
{
|
||||
handle_emu_flip(async_flip_buffer);
|
||||
async_flip_requested.test_and_reset(flip_request::emu_requested);
|
||||
}
|
||||
handle_emu_flip(buffer);
|
||||
}
|
||||
else // requested 'manually' through ppu syscall
|
||||
{
|
||||
// ignore multiple requests until previous happens
|
||||
if (test(async_flip_requested, flip_request::emu_requested))
|
||||
return;
|
||||
|
||||
async_flip_buffer = buffer;
|
||||
async_flip_requested.test_and_set(flip_request::emu_requested);
|
||||
}
|
||||
}
|
||||
|
||||
void thread::handle_emu_flip(u32 buffer)
|
||||
{
|
||||
if (user_asked_for_frame_capture && !g_cfg.video.strict_rendering_mode)
|
||||
{
|
||||
// not dealing with non-strict rendering capture for now
|
||||
user_asked_for_frame_capture = false;
|
||||
LOG_FATAL(RSX, "RSX Capture: Capture only supported when ran with strict rendering mode.");
|
||||
}
|
||||
else if (user_asked_for_frame_capture && !capture_current_frame)
|
||||
{
|
||||
capture_current_frame = true;
|
||||
user_asked_for_frame_capture = false;
|
||||
frame_debug.reset();
|
||||
frame_capture.reset();
|
||||
|
||||
// random number just to jumpstart the size
|
||||
frame_capture.replay_commands.reserve(8000);
|
||||
|
||||
// capture first tile state with nop cmd
|
||||
rsx::frame_capture_data::replay_command replay_cmd;
|
||||
replay_cmd.rsx_command = std::make_pair(NV4097_NO_OPERATION, 0);
|
||||
frame_capture.replay_commands.push_back(replay_cmd);
|
||||
capture::capture_display_tile_state(this, frame_capture.replay_commands.back());
|
||||
}
|
||||
else if (capture_current_frame)
|
||||
{
|
||||
capture_current_frame = false;
|
||||
std::stringstream os;
|
||||
cereal::BinaryOutputArchive archive(os);
|
||||
const std::string& filePath = fs::get_config_dir() + "capture.rrc";
|
||||
archive(frame_capture);
|
||||
{
|
||||
// todo: 'dynamicly' create capture filename, also may want to compress this data?
|
||||
fs::file f(filePath, fs::rewrite);
|
||||
f.write(os.str());
|
||||
}
|
||||
|
||||
LOG_SUCCESS(RSX, "capture successful: %s", filePath.c_str());
|
||||
|
||||
frame_capture.reset();
|
||||
Emu.Pause();
|
||||
}
|
||||
|
||||
double limit = 0.;
|
||||
switch (g_cfg.video.frame_limit)
|
||||
{
|
||||
case frame_limit_type::none: limit = 0.; break;
|
||||
case frame_limit_type::_59_94: limit = 59.94; break;
|
||||
case frame_limit_type::_50: limit = 50.; break;
|
||||
case frame_limit_type::_60: limit = 60.; break;
|
||||
case frame_limit_type::_30: limit = 30.; break;
|
||||
case frame_limit_type::_auto: limit = fps_limit; break; // TODO
|
||||
}
|
||||
|
||||
if (limit)
|
||||
{
|
||||
const u64 time = get_system_time() - Emu.GetPauseTime() - start_rsx_time;
|
||||
|
||||
if (int_flip_index == 0)
|
||||
{
|
||||
start_rsx_time = time;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert limit to expected time value
|
||||
double expected = int_flip_index * 1000000. / limit;
|
||||
|
||||
while (time >= expected + 1000000. / limit)
|
||||
{
|
||||
expected = int_flip_index++ * 1000000. / limit;
|
||||
}
|
||||
|
||||
if (expected > time + 1000)
|
||||
{
|
||||
const auto delay_us = static_cast<s64>(expected - time);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds{ delay_us / 1000 });
|
||||
performance_counters.idle_time += delay_us;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int_flip_index++;
|
||||
current_display_buffer = buffer;
|
||||
flip(buffer);
|
||||
// After each flip PS3 system is executing a routine that changes registers value to some default.
|
||||
// Some game use this default state (SH3).
|
||||
if (isHLE)
|
||||
reset();
|
||||
|
||||
last_flip_time = get_system_time() - 1000000;
|
||||
flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_DONE;
|
||||
|
||||
if (flip_handler)
|
||||
{
|
||||
intr_thread->cmd_list
|
||||
({
|
||||
{ ppu_cmd::set_args, 1 }, u64{ 1 },
|
||||
{ ppu_cmd::lle_call, flip_handler },
|
||||
{ ppu_cmd::sleep, 0 }
|
||||
});
|
||||
|
||||
intr_thread->notify();
|
||||
}
|
||||
sys_rsx_flip_event(buffer);
|
||||
}
|
||||
|
||||
|
||||
namespace reports
|
||||
{
|
||||
void ZCULL_control::set_enabled(class ::rsx::thread* ptimer, bool state)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue