mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
renderer&guest_gpu: minor cleanup
This commit is contained in:
@@ -37,7 +37,7 @@ static thread_local CommandProcessor* g_current_processor = nullptr;
|
|||||||
static thread_local Pm4Execution* g_current_execution = nullptr;
|
static thread_local Pm4Execution* g_current_execution = nullptr;
|
||||||
static thread_local bool g_gpu_mutex_owned = false;
|
static thread_local bool g_gpu_mutex_owned = false;
|
||||||
static thread_local bool g_gpu_thread = false;
|
static thread_local bool g_gpu_thread = false;
|
||||||
static thread_local GpuState* g_gpu_state = nullptr;
|
static thread_local GuestGpu* g_gpu_state = nullptr;
|
||||||
|
|
||||||
class GpuMutexLock final {
|
class GpuMutexLock final {
|
||||||
public:
|
public:
|
||||||
@@ -60,115 +60,30 @@ private:
|
|||||||
Common::Mutex& m_mutex;
|
Common::Mutex& m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OwnedCmdBuffer {
|
|
||||||
OwnedCmdBuffer() = default;
|
|
||||||
explicit OwnedCmdBuffer(const uint32_t* data, uint32_t count) {
|
|
||||||
EXIT_IF(data == nullptr && count != 0);
|
|
||||||
if (count != 0) {
|
|
||||||
m_words.assign(data, data + count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool Empty() const noexcept { return m_words.empty(); }
|
|
||||||
[[nodiscard]] uint32_t Size() const noexcept { return static_cast<uint32_t>(m_words.size()); }
|
|
||||||
[[nodiscard]] uint32_t* Data() noexcept { return m_words.data(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<uint32_t> m_words;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GpuState {
|
|
||||||
public:
|
|
||||||
static constexpr uint32_t ComputePipeCount = 7;
|
|
||||||
static constexpr uint32_t QueuesPerComputePipe = 8;
|
|
||||||
static constexpr uint32_t ComputeQueueCount = ComputePipeCount * QueuesPerComputePipe;
|
|
||||||
static constexpr uint32_t QueueCount = 1 + ComputeQueueCount;
|
|
||||||
|
|
||||||
explicit GpuState(RenderContext& renderer): m_renderer(renderer) {
|
|
||||||
EXIT_NOT_IMPLEMENTED(!Common::Thread::IsMainThread());
|
|
||||||
m_gfx_cp = std::make_unique<CommandProcessor>(renderer);
|
|
||||||
m_thread = std::jthread(ThreadRun, this);
|
|
||||||
}
|
|
||||||
~GpuState();
|
|
||||||
|
|
||||||
KYTY_CLASS_NO_COPY(GpuState);
|
|
||||||
|
|
||||||
void Submit(uint32_t* cmd_draw_buffer, uint32_t num_draw_dw, uint32_t* cmd_const_buffer,
|
|
||||||
uint32_t num_const_dw, bool trigger_agc_interrupt_on_done);
|
|
||||||
void SubmitCompute(uint32_t queue, uint32_t* cmd_buffer, uint32_t num_dw,
|
|
||||||
bool trigger_agc_interrupt_on_done);
|
|
||||||
void SubmitFlipPreparation(uint64_t request_id);
|
|
||||||
void Done();
|
|
||||||
void Shutdown();
|
|
||||||
[[nodiscard]] bool IsStopping();
|
|
||||||
void SendCommand(Common::UniqueFunction<void>&& command);
|
|
||||||
void SendCommandSync(Common::UniqueFunction<void>&& command);
|
|
||||||
int GetFrameNum();
|
|
||||||
[[nodiscard]] static bool IsGpuThread() noexcept { return g_gpu_thread; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum class SubmissionType { Graphics, Compute, FlipPreparation };
|
|
||||||
|
|
||||||
struct Submission {
|
|
||||||
SubmissionType type = SubmissionType::Graphics;
|
|
||||||
uint32_t queue_id = 0;
|
|
||||||
OwnedCmdBuffer commands;
|
|
||||||
OwnedCmdBuffer constant_commands;
|
|
||||||
Pm4Execution command_execution;
|
|
||||||
Pm4Execution constant_execution;
|
|
||||||
bool trigger_agc_interrupt_on_done = false;
|
|
||||||
bool reset_processor = false;
|
|
||||||
bool started = false;
|
|
||||||
bool command_complete = false;
|
|
||||||
bool constant_complete = false;
|
|
||||||
bool blocked = false;
|
|
||||||
uint64_t flip_request_id = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Enqueue(Submission submission);
|
|
||||||
void WaitForIdle();
|
|
||||||
void ProcessCommands();
|
|
||||||
bool Process(Submission& submission);
|
|
||||||
static void ThreadRun(void* data);
|
|
||||||
CommandProcessor& GetProcessor(uint32_t queue_id);
|
|
||||||
|
|
||||||
RenderContext& m_renderer;
|
|
||||||
Common::Mutex m_submission_mutex;
|
|
||||||
Common::Mutex m_queue_mutex;
|
|
||||||
std::mutex m_shutdown_mutex;
|
|
||||||
Common::CondVar m_work_available;
|
|
||||||
Common::CondVar m_idle;
|
|
||||||
std::array<std::deque<Submission>, QueueCount> m_queues;
|
|
||||||
std::deque<Common::UniqueFunction<void>> m_commands;
|
|
||||||
std::atomic_uint32_t m_pending_commands {0};
|
|
||||||
uint32_t m_next_queue = 0;
|
|
||||||
uint32_t m_submission_count = 0;
|
|
||||||
bool m_processing = false;
|
|
||||||
bool m_graphics_done = true;
|
|
||||||
bool m_accepting = true;
|
|
||||||
bool m_stopping = false;
|
|
||||||
bool m_shutdown_complete = false;
|
|
||||||
|
|
||||||
std::unique_ptr<CommandProcessor> m_gfx_cp;
|
|
||||||
std::array<std::unique_ptr<CommandProcessor>, ComputeQueueCount> m_compute_cp;
|
|
||||||
|
|
||||||
uint64_t m_submit_id = 0;
|
|
||||||
std::atomic_int m_done_num = 0;
|
|
||||||
std::jthread m_thread;
|
|
||||||
|
|
||||||
friend class CommandProcessor;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool GraphicsRunDebugDumpEnabled() {
|
static bool GraphicsRunDebugDumpEnabled() {
|
||||||
return Config::GraphicsDebugDumpEnabled() &&
|
return Config::GraphicsDebugDumpEnabled() &&
|
||||||
Config::GetPrintfDirection() != Config::OutputDirection::Silent;
|
Config::GetPrintfDirection() != Config::OutputDirection::Silent;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpuState::~GpuState() {
|
GuestGpu::OwnedCmdBuffer::OwnedCmdBuffer(const uint32_t* data, uint32_t count) {
|
||||||
|
EXIT_IF(data == nullptr && count != 0);
|
||||||
|
if (count != 0) {
|
||||||
|
m_words.assign(data, data + count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GuestGpu::GuestGpu(RenderContext& renderer): m_renderer(renderer) {
|
||||||
|
EXIT_NOT_IMPLEMENTED(!Common::Thread::IsMainThread());
|
||||||
|
GraphicsInitJmpTables();
|
||||||
|
m_gfx_cp = std::make_unique<CommandProcessor>(renderer);
|
||||||
|
m_thread = std::jthread(ThreadRun, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
GuestGpu::~GuestGpu() {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::Shutdown() {
|
void GuestGpu::Shutdown() {
|
||||||
std::lock_guard shutdown_lock(m_shutdown_mutex);
|
std::lock_guard shutdown_lock(m_shutdown_mutex);
|
||||||
if (m_shutdown_complete) {
|
if (m_shutdown_complete) {
|
||||||
return;
|
return;
|
||||||
@@ -185,12 +100,12 @@ void GpuState::Shutdown() {
|
|||||||
m_shutdown_complete = true;
|
m_shutdown_complete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GpuState::IsStopping() {
|
bool GuestGpu::IsStopping() {
|
||||||
Common::LockGuard lock(m_queue_mutex);
|
Common::LockGuard lock(m_queue_mutex);
|
||||||
return m_stopping;
|
return m_stopping;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::SendCommand(Common::UniqueFunction<void>&& command) {
|
void GuestGpu::SendCommand(Common::UniqueFunction<void>&& command) {
|
||||||
EXIT_IF(!command);
|
EXIT_IF(!command);
|
||||||
if (IsGpuThread()) {
|
if (IsGpuThread()) {
|
||||||
command();
|
command();
|
||||||
@@ -203,7 +118,7 @@ void GpuState::SendCommand(Common::UniqueFunction<void>&& command) {
|
|||||||
m_work_available.Signal();
|
m_work_available.Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::ProcessCommands() {
|
void GuestGpu::ProcessCommands() {
|
||||||
EXIT_IF(!IsGpuThread());
|
EXIT_IF(!IsGpuThread());
|
||||||
while (m_pending_commands.load(std::memory_order_acquire) != 0) {
|
while (m_pending_commands.load(std::memory_order_acquire) != 0) {
|
||||||
Common::UniqueFunction<void> command;
|
Common::UniqueFunction<void> command;
|
||||||
@@ -218,7 +133,7 @@ void GpuState::ProcessCommands() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::SendCommandSync(Common::UniqueFunction<void>&& command) {
|
void GuestGpu::SendCommandSync(Common::UniqueFunction<void>&& command) {
|
||||||
EXIT_IF(!command);
|
EXIT_IF(!command);
|
||||||
if (IsGpuThread()) {
|
if (IsGpuThread()) {
|
||||||
command();
|
command();
|
||||||
@@ -232,8 +147,9 @@ void GpuState::SendCommandSync(Common::UniqueFunction<void>&& command) {
|
|||||||
done.acquire();
|
done.acquire();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::Submit(uint32_t* cmd_draw_buffer, uint32_t num_draw_dw, uint32_t* cmd_const_buffer,
|
void GuestGpu::Submit(uint32_t* cmd_draw_buffer, uint32_t num_draw_dw, uint32_t* cmd_const_buffer,
|
||||||
uint32_t num_const_dw, bool trigger_agc_interrupt_on_done) {
|
uint32_t num_const_dw, bool trigger_agc_interrupt_on_done) {
|
||||||
|
EXIT_IF(cmd_draw_buffer == nullptr || num_draw_dw == 0);
|
||||||
GpuMutexLock lock(m_submission_mutex);
|
GpuMutexLock lock(m_submission_mutex);
|
||||||
Submission submission;
|
Submission submission;
|
||||||
submission.type = SubmissionType::Graphics;
|
submission.type = SubmissionType::Graphics;
|
||||||
@@ -246,8 +162,9 @@ void GpuState::Submit(uint32_t* cmd_draw_buffer, uint32_t num_draw_dw, uint32_t*
|
|||||||
Enqueue(std::move(submission));
|
Enqueue(std::move(submission));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::SubmitCompute(uint32_t queue, uint32_t* cmd_buffer, uint32_t num_dw,
|
void GuestGpu::SubmitCompute(uint32_t queue, uint32_t* cmd_buffer, uint32_t num_dw,
|
||||||
bool trigger_agc_interrupt_on_done) {
|
bool trigger_agc_interrupt_on_done) {
|
||||||
|
EXIT_IF(cmd_buffer == nullptr || num_dw == 0);
|
||||||
GpuMutexLock lock(m_submission_mutex);
|
GpuMutexLock lock(m_submission_mutex);
|
||||||
|
|
||||||
constexpr uint32_t compute_queue_base = 0x20u;
|
constexpr uint32_t compute_queue_base = 0x20u;
|
||||||
@@ -263,7 +180,7 @@ void GpuState::SubmitCompute(uint32_t queue, uint32_t* cmd_buffer, uint32_t num_
|
|||||||
Enqueue(std::move(submission));
|
Enqueue(std::move(submission));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::SubmitFlipPreparation(uint64_t request_id) {
|
void GuestGpu::SubmitFlipPreparation(uint64_t request_id) {
|
||||||
GpuMutexLock lock(m_submission_mutex);
|
GpuMutexLock lock(m_submission_mutex);
|
||||||
Submission submission;
|
Submission submission;
|
||||||
submission.type = SubmissionType::FlipPreparation;
|
submission.type = SubmissionType::FlipPreparation;
|
||||||
@@ -274,7 +191,7 @@ void GpuState::SubmitFlipPreparation(uint64_t request_id) {
|
|||||||
Enqueue(std::move(submission));
|
Enqueue(std::move(submission));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::Done() {
|
void GuestGpu::Done() {
|
||||||
GpuMutexLock lock(m_submission_mutex);
|
GpuMutexLock lock(m_submission_mutex);
|
||||||
if (!IsGpuThread()) {
|
if (!IsGpuThread()) {
|
||||||
WaitForIdle();
|
WaitForIdle();
|
||||||
@@ -289,11 +206,11 @@ void GpuState::Done() {
|
|||||||
m_done_num++;
|
m_done_num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GpuState::GetFrameNum() {
|
int GuestGpu::GetFrameNum() const {
|
||||||
return m_done_num;
|
return m_done_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandProcessor& GpuState::GetProcessor(uint32_t queue_id) {
|
CommandProcessor& GuestGpu::GetProcessor(uint32_t queue_id) {
|
||||||
EXIT_IF(queue_id >= QueueCount);
|
EXIT_IF(queue_id >= QueueCount);
|
||||||
if (queue_id == 0) {
|
if (queue_id == 0) {
|
||||||
return *m_gfx_cp;
|
return *m_gfx_cp;
|
||||||
@@ -531,7 +448,7 @@ void CommandProcessor::DmaData(uint8_t engine, uint8_t dst_sel, uint8_t dst_cach
|
|||||||
dst_gds, src_gds);
|
dst_gds, src_gds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::Enqueue(Submission submission) {
|
void GuestGpu::Enqueue(Submission submission) {
|
||||||
EXIT_IF(submission.queue_id >= QueueCount);
|
EXIT_IF(submission.queue_id >= QueueCount);
|
||||||
Common::LockGuard lock(m_queue_mutex);
|
Common::LockGuard lock(m_queue_mutex);
|
||||||
EXIT_IF(!m_accepting);
|
EXIT_IF(!m_accepting);
|
||||||
@@ -540,15 +457,15 @@ void GpuState::Enqueue(Submission submission) {
|
|||||||
m_work_available.Signal();
|
m_work_available.Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::WaitForIdle() {
|
void GuestGpu::WaitForIdle() {
|
||||||
Common::LockGuard lock(m_queue_mutex);
|
Common::LockGuard lock(m_queue_mutex);
|
||||||
while (m_processing || !m_commands.empty() || m_submission_count != 0) {
|
while (m_processing || !m_commands.empty() || m_submission_count != 0) {
|
||||||
m_idle.Wait(&m_queue_mutex);
|
m_idle.Wait(&m_queue_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpuState::ThreadRun(void* data) {
|
void GuestGpu::ThreadRun(void* data) {
|
||||||
auto* gpu = static_cast<GpuState*>(data);
|
auto* gpu = static_cast<GuestGpu*>(data);
|
||||||
EXIT_IF(gpu == nullptr);
|
EXIT_IF(gpu == nullptr);
|
||||||
KYTY_PROFILER_THREAD("Thread_Gpu");
|
KYTY_PROFILER_THREAD("Thread_Gpu");
|
||||||
g_gpu_thread = true;
|
g_gpu_thread = true;
|
||||||
@@ -644,7 +561,7 @@ void GpuState::ThreadRun(void* data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GpuState::Process(Submission& submission) {
|
bool GuestGpu::Process(Submission& submission) {
|
||||||
const bool first_slice = !submission.started;
|
const bool first_slice = !submission.started;
|
||||||
if (first_slice && RenderDocCaptureRequested()) {
|
if (first_slice && RenderDocCaptureRequested()) {
|
||||||
Common::LockGuard render_lock(m_renderer.GetMutex());
|
Common::LockGuard render_lock(m_renderer.GetMutex());
|
||||||
@@ -1686,57 +1603,8 @@ void CommandProcessor::SynchronizeGpu() {
|
|||||||
GetScheduler().FinishCurrent();
|
GetScheduler().FinishCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
Gpu::Gpu(RenderContext& renderer) {
|
bool GuestGpu::IsGpuThread() noexcept {
|
||||||
EXIT_NOT_IMPLEMENTED(!Common::Thread::IsMainThread());
|
return g_gpu_thread;
|
||||||
GraphicsInitJmpTables();
|
|
||||||
m_state = std::make_unique<GpuState>(renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
Gpu::~Gpu() = default;
|
|
||||||
|
|
||||||
void Gpu::Shutdown() {
|
|
||||||
m_state->Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Gpu::IsStopping() {
|
|
||||||
return m_state->IsStopping();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gpu::SendCommand(Common::UniqueFunction<void>&& command) {
|
|
||||||
m_state->SendCommand(std::move(command));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gpu::SendCommandSync(Common::UniqueFunction<void>&& command) {
|
|
||||||
m_state->SendCommandSync(std::move(command));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gpu::Submit(uint32_t* draw_commands, uint32_t draw_size_dw, uint32_t* constant_commands,
|
|
||||||
uint32_t constant_size_dw, bool trigger_agc_interrupt_on_done) {
|
|
||||||
EXIT_IF(draw_commands == nullptr || draw_size_dw == 0);
|
|
||||||
m_state->Submit(draw_commands, draw_size_dw, constant_commands, constant_size_dw,
|
|
||||||
trigger_agc_interrupt_on_done);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gpu::SubmitCompute(uint32_t queue, uint32_t* commands, uint32_t size_dw,
|
|
||||||
bool trigger_agc_interrupt_on_done) {
|
|
||||||
EXIT_IF(commands == nullptr || size_dw == 0);
|
|
||||||
m_state->SubmitCompute(queue, commands, size_dw, trigger_agc_interrupt_on_done);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gpu::SubmitFlipPreparation(uint64_t request_id) {
|
|
||||||
m_state->SubmitFlipPreparation(request_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gpu::Done() {
|
|
||||||
m_state->Done();
|
|
||||||
}
|
|
||||||
|
|
||||||
int Gpu::GetFrameNum() const {
|
|
||||||
return m_state->GetFrameNum();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Gpu::IsGpuThread() noexcept {
|
|
||||||
return GpuState::IsGpuThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libs::Graphics
|
} // namespace Libs::Graphics
|
||||||
|
|||||||
@@ -3,20 +3,28 @@
|
|||||||
|
|
||||||
#include "common/abi.h"
|
#include "common/abi.h"
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
|
#include "common/threads.h"
|
||||||
#include "common/uniqueFunction.h"
|
#include "common/uniqueFunction.h"
|
||||||
|
#include "graphics/guest_gpu/command_processor/commandProcessor.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <atomic>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
class GpuState;
|
|
||||||
class RenderContext;
|
class RenderContext;
|
||||||
|
|
||||||
class Gpu final {
|
class GuestGpu final {
|
||||||
public:
|
public:
|
||||||
explicit Gpu(RenderContext& renderer);
|
explicit GuestGpu(RenderContext& renderer);
|
||||||
~Gpu();
|
~GuestGpu();
|
||||||
KYTY_CLASS_NO_COPY(Gpu);
|
KYTY_CLASS_NO_COPY(GuestGpu);
|
||||||
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
[[nodiscard]] bool IsStopping();
|
[[nodiscard]] bool IsStopping();
|
||||||
@@ -34,7 +42,76 @@ public:
|
|||||||
[[nodiscard]] static bool IsGpuThread() noexcept;
|
[[nodiscard]] static bool IsGpuThread() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<GpuState> m_state;
|
static constexpr uint32_t ComputePipeCount = 7;
|
||||||
|
static constexpr uint32_t QueuesPerComputePipe = 8;
|
||||||
|
static constexpr uint32_t ComputeQueueCount = ComputePipeCount * QueuesPerComputePipe;
|
||||||
|
static constexpr uint32_t QueueCount = 1 + ComputeQueueCount;
|
||||||
|
|
||||||
|
class OwnedCmdBuffer {
|
||||||
|
public:
|
||||||
|
OwnedCmdBuffer() = default;
|
||||||
|
explicit OwnedCmdBuffer(const uint32_t* data, uint32_t count);
|
||||||
|
|
||||||
|
[[nodiscard]] bool Empty() const noexcept { return m_words.empty(); }
|
||||||
|
[[nodiscard]] uint32_t Size() const noexcept {
|
||||||
|
return static_cast<uint32_t>(m_words.size());
|
||||||
|
}
|
||||||
|
[[nodiscard]] uint32_t* Data() noexcept { return m_words.data(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<uint32_t> m_words;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SubmissionType { Graphics, Compute, FlipPreparation };
|
||||||
|
|
||||||
|
struct Submission {
|
||||||
|
SubmissionType type = SubmissionType::Graphics;
|
||||||
|
uint32_t queue_id = 0;
|
||||||
|
OwnedCmdBuffer commands;
|
||||||
|
OwnedCmdBuffer constant_commands;
|
||||||
|
Pm4Execution command_execution;
|
||||||
|
Pm4Execution constant_execution;
|
||||||
|
bool trigger_agc_interrupt_on_done = false;
|
||||||
|
bool reset_processor = false;
|
||||||
|
bool started = false;
|
||||||
|
bool command_complete = false;
|
||||||
|
bool constant_complete = false;
|
||||||
|
bool blocked = false;
|
||||||
|
uint64_t flip_request_id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Enqueue(Submission submission);
|
||||||
|
void WaitForIdle();
|
||||||
|
void ProcessCommands();
|
||||||
|
bool Process(Submission& submission);
|
||||||
|
static void ThreadRun(void* data);
|
||||||
|
CommandProcessor& GetProcessor(uint32_t queue_id);
|
||||||
|
|
||||||
|
RenderContext& m_renderer;
|
||||||
|
Common::Mutex m_submission_mutex;
|
||||||
|
Common::Mutex m_queue_mutex;
|
||||||
|
std::mutex m_shutdown_mutex;
|
||||||
|
Common::CondVar m_work_available;
|
||||||
|
Common::CondVar m_idle;
|
||||||
|
std::array<std::deque<Submission>, QueueCount> m_queues;
|
||||||
|
std::deque<Common::UniqueFunction<void>> m_commands;
|
||||||
|
std::atomic_uint32_t m_pending_commands {0};
|
||||||
|
uint32_t m_next_queue = 0;
|
||||||
|
uint32_t m_submission_count = 0;
|
||||||
|
bool m_processing = false;
|
||||||
|
bool m_graphics_done = true;
|
||||||
|
bool m_accepting = true;
|
||||||
|
bool m_stopping = false;
|
||||||
|
bool m_shutdown_complete = false;
|
||||||
|
|
||||||
|
std::unique_ptr<CommandProcessor> m_gfx_cp;
|
||||||
|
std::array<std::unique_ptr<CommandProcessor>, ComputeQueueCount> m_compute_cp;
|
||||||
|
|
||||||
|
uint64_t m_submit_id = 0;
|
||||||
|
std::atomic_int m_done_num = 0;
|
||||||
|
std::jthread m_thread;
|
||||||
|
|
||||||
|
friend class CommandProcessor;
|
||||||
};
|
};
|
||||||
} // namespace Libs::Graphics
|
} // namespace Libs::Graphics
|
||||||
|
|
||||||
|
|||||||
+1
-5
@@ -257,11 +257,7 @@ void BufferCache::InvalidateMemory(uint64_t vaddr, uint64_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BufferCache::ReadMemory(uint64_t vaddr, uint64_t size, bool is_write) {
|
void BufferCache::ReadMemory(uint64_t vaddr, uint64_t size, bool is_write) {
|
||||||
if (Gpu::IsGpuThread()) {
|
if (!GuestGpu::IsGpuThread() && CommandScheduler::InDeferredOperation()) {
|
||||||
ReadMemoryOnGpu(vaddr, size, is_write);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (CommandScheduler::InDeferredOperation()) {
|
|
||||||
EXIT("unsupported buffer readback from an asynchronous GPU completion, "
|
EXIT("unsupported buffer readback from an asynchronous GPU completion, "
|
||||||
"addr=0x%016" PRIx64 " size=0x%016" PRIx64 "\n",
|
"addr=0x%016" PRIx64 " size=0x%016" PRIx64 "\n",
|
||||||
vaddr, size);
|
vaddr, size);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
class CommandScheduler;
|
class CommandScheduler;
|
||||||
class Gpu;
|
class GuestGpu;
|
||||||
|
|
||||||
class GpuResourceManager {
|
class GpuResourceManager {
|
||||||
public:
|
public:
|
||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] BufferCache& GetBufferCache() { return m_buffer_cache; }
|
[[nodiscard]] BufferCache& GetBufferCache() { return m_buffer_cache; }
|
||||||
[[nodiscard]] TextureCache& GetTextureCache() { return m_texture_cache; }
|
[[nodiscard]] TextureCache& GetTextureCache() { return m_texture_cache; }
|
||||||
void SetGpu(Gpu* gpu) noexcept { m_gpu = gpu; }
|
void SetGpu(GuestGpu* gpu) noexcept { m_gpu = gpu; }
|
||||||
|
|
||||||
[[nodiscard]] bool HandleFault(PageFaultAccess access, uint64_t fault_vaddr) noexcept;
|
[[nodiscard]] bool HandleFault(PageFaultAccess access, uint64_t fault_vaddr) noexcept;
|
||||||
[[nodiscard]] bool InvalidateMemory(uint64_t vaddr, uint64_t size);
|
[[nodiscard]] bool InvalidateMemory(uint64_t vaddr, uint64_t size);
|
||||||
@@ -39,7 +39,7 @@ private:
|
|||||||
TextureCache m_texture_cache;
|
TextureCache m_texture_cache;
|
||||||
mutable std::shared_mutex m_mapped_ranges_mutex;
|
mutable std::shared_mutex m_mapped_ranges_mutex;
|
||||||
RangeSet m_mapped_ranges;
|
RangeSet m_mapped_ranges;
|
||||||
Gpu* m_gpu = nullptr;
|
GuestGpu* m_gpu = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Libs::Graphics
|
} // namespace Libs::Graphics
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ RenderContext::~RenderContext() {
|
|||||||
void RenderContext::InitializeGpu(VideoOut::VideoOutDriver* video_out) {
|
void RenderContext::InitializeGpu(VideoOut::VideoOutDriver* video_out) {
|
||||||
EXIT_IF(m_gpu != nullptr);
|
EXIT_IF(m_gpu != nullptr);
|
||||||
m_video_out = video_out;
|
m_video_out = video_out;
|
||||||
m_gpu = std::make_unique<Gpu>(*this);
|
m_gpu = std::make_unique<GuestGpu>(*this);
|
||||||
m_gpu_resources.SetGpu(m_gpu.get());
|
m_gpu_resources.SetGpu(m_gpu.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ void RenderContext::ShutdownGpu() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Gpu& RenderContext::GetGpu() const {
|
GuestGpu& RenderContext::GetGpu() const {
|
||||||
EXIT_IF(m_gpu == nullptr);
|
EXIT_IF(m_gpu == nullptr);
|
||||||
return *m_gpu;
|
return *m_gpu;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class VideoOutDriver;
|
|||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
|
|
||||||
constexpr int AGC_USER_INTERRUPT_EVENT = 0x1800;
|
constexpr int AGC_USER_INTERRUPT_EVENT = 0x1800;
|
||||||
class Gpu;
|
class GuestGpu;
|
||||||
|
|
||||||
class RenderContext {
|
class RenderContext {
|
||||||
public:
|
public:
|
||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
[[nodiscard]] GraphicContext& GetGraphics() const noexcept { return m_graphics; }
|
[[nodiscard]] GraphicContext& GetGraphics() const noexcept { return m_graphics; }
|
||||||
void InitializeGpu(VideoOut::VideoOutDriver* video_out);
|
void InitializeGpu(VideoOut::VideoOutDriver* video_out);
|
||||||
void ShutdownGpu();
|
void ShutdownGpu();
|
||||||
[[nodiscard]] Gpu& GetGpu() const;
|
[[nodiscard]] GuestGpu& GetGpu() const;
|
||||||
[[nodiscard]] VideoOut::VideoOutDriver& GetVideoOut() const;
|
[[nodiscard]] VideoOut::VideoOutDriver& GetVideoOut() const;
|
||||||
|
|
||||||
Common::Mutex& GetMutex() { return m_mutex; }
|
Common::Mutex& GetMutex() { return m_mutex; }
|
||||||
@@ -67,7 +67,7 @@ private:
|
|||||||
PipelineCache m_pipeline_cache;
|
PipelineCache m_pipeline_cache;
|
||||||
SamplerCache m_sampler_cache;
|
SamplerCache m_sampler_cache;
|
||||||
GpuResourceManager m_gpu_resources;
|
GpuResourceManager m_gpu_resources;
|
||||||
std::unique_ptr<Gpu> m_gpu;
|
std::unique_ptr<GuestGpu> m_gpu;
|
||||||
VideoOut::VideoOutDriver* m_video_out = nullptr;
|
VideoOut::VideoOutDriver* m_video_out = nullptr;
|
||||||
|
|
||||||
Common::Mutex m_eop_mutex;
|
Common::Mutex m_eop_mutex;
|
||||||
|
|||||||
@@ -869,7 +869,7 @@ bool TryReadBacking(uint64_t vaddr, void* data, uint64_t size) {
|
|||||||
|
|
||||||
bool TryReadGpuCleanBacking(uint64_t vaddr, void* data, uint64_t size) {
|
bool TryReadGpuCleanBacking(uint64_t vaddr, void* data, uint64_t size) {
|
||||||
if (g_gpu_resources != nullptr && IsGpuAddressRange(vaddr, size)) {
|
if (g_gpu_resources != nullptr && IsGpuAddressRange(vaddr, size)) {
|
||||||
if (!Graphics::Gpu::IsGpuThread() ||
|
if (!Graphics::GuestGpu::IsGpuThread() ||
|
||||||
GetGpuResources().GetBufferCache().HasGpuDirtyBytes(vaddr, size) ||
|
GetGpuResources().GetBufferCache().HasGpuDirtyBytes(vaddr, size) ||
|
||||||
GetGpuResources().GetTextureCache().QueryRegion(vaddr, size).gpu_image_bytes) {
|
GetGpuResources().GetTextureCache().QueryRegion(vaddr, size).gpu_image_bytes) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1794,7 +1794,7 @@ public:
|
|||||||
gpu_thread = std::this_thread::get_id();
|
gpu_thread = std::this_thread::get_id();
|
||||||
Require("GpuCommandLane", "FIFO", order == 1,
|
Require("GpuCommandLane", "FIFO", order == 1,
|
||||||
"synchronous command overtook an older host command");
|
"synchronous command overtook an older host command");
|
||||||
Require("GpuCommandLane", "GPU context", Gpu::IsGpuThread(),
|
Require("GpuCommandLane", "GPU context", GuestGpu::IsGpuThread(),
|
||||||
"host command did not run on the GPU thread");
|
"host command did not run on the GPU thread");
|
||||||
gpu.SendCommandSync(
|
gpu.SendCommandSync(
|
||||||
[&nested_thread] { nested_thread = std::this_thread::get_id(); });
|
[&nested_thread] { nested_thread = std::this_thread::get_id(); });
|
||||||
|
|||||||
Reference in New Issue
Block a user