From 2e58f312d57865e603290fef6b0b99f5c9c9366c Mon Sep 17 00:00:00 2001 From: DHrpcs3 Date: Wed, 20 Jan 2016 17:12:49 +0300 Subject: [PATCH] rsx: implemented internal tasks queue (WIP) --- rpcs3/Emu/RSX/RSXThread.cpp | 48 ++++++++++++++++++++++++++++++++++++- rpcs3/Emu/RSX/RSXThread.h | 20 ++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 7267884070..bdcd893639 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -366,7 +366,7 @@ namespace rsx if (put == get || !Emu.IsRunning()) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + do_internal_task(); continue; } @@ -519,6 +519,52 @@ namespace rsx return get_system_time() * 1000; } + void thread::do_internal_task() + { + if (m_internal_tasks.empty()) + { + std::this_thread::sleep_for(1ms); + } + else + { + std::lock_guard lock{ m_mtx_task }; + + internal_task_entry &front = m_internal_tasks.front(); + + if (front.callback()) + { + front.promise.set_value(); + m_internal_tasks.pop_front(); + } + } + } + + std::future thread::add_internal_task(std::function callback) + { + std::lock_guard lock{ m_mtx_task }; + m_internal_tasks.emplace_back(callback); + + return m_internal_tasks.back().promise.get_future(); + } + + void thread::invoke(std::function callback) + { + if (get_thread_ctrl() == thread_ctrl::get_current()) + { + while (true) + { + if (callback()) + { + break; + } + } + } + else + { + add_internal_task(callback).wait(); + } + } + std::array thread::get_color_surface_addresses() const { u32 offset_color[] = diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index ec508ef42e..48304cefd2 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -329,6 +329,26 @@ namespace rsx virtual u64 timestamp() const; virtual bool on_access_violation(u32 address, bool is_writing) { return false; } + private: + std::mutex m_mtx_task; + + struct internal_task_entry + { + std::function callback; + std::promise promise; + + internal_task_entry(std::function callback) : callback(callback) + { + } + }; + + std::deque m_internal_tasks; + void do_internal_task(); + + public: + std::future add_internal_task(std::function callback); + void invoke(std::function callback); + /** * Fill buffer with 4x4 scale offset matrix. * Vertex shader's position is to be multiplied by this matrix.