mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
refactor(gpu): use a single ordered PM4 scheduler
This commit is contained in:
@@ -554,7 +554,7 @@ bool BufferCache::InvalidateMemory(PageFaultAccess access, uint64_t vaddr, uint6
|
||||
return action == CpuFaultAction::Continue;
|
||||
}
|
||||
if (GraphicsRunIsCommandProcessorThread()) {
|
||||
GraphicsRunFinishCommandProcessors();
|
||||
GraphicsRunFinishScheduler();
|
||||
}
|
||||
m_readback->Request(access, vaddr, size);
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#include "graphics/host_gpu/renderer/commandScheduler.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
|
||||
namespace Libs::Graphics {
|
||||
|
||||
void CommandScheduler::Begin(HW::Context& registers, HW::UserConfig& user_config,
|
||||
HW::Shader& shaders) {
|
||||
m_registers = ®isters;
|
||||
m_user_config = &user_config;
|
||||
m_shaders = &shaders;
|
||||
|
||||
if (!Active()) {
|
||||
for (auto& buffer: m_buffers) {
|
||||
buffer = std::make_unique<RenderCommandBuffer>();
|
||||
}
|
||||
m_current = 0;
|
||||
}
|
||||
|
||||
BindCurrent();
|
||||
if (!m_recording) {
|
||||
Current().Begin();
|
||||
m_recording = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CommandScheduler::Flush() {
|
||||
SubmitCurrent();
|
||||
BeginNext();
|
||||
}
|
||||
|
||||
CommandBuffer& CommandScheduler::FlushAndGetSubmitted() {
|
||||
auto& submitted = SubmitCurrent();
|
||||
BeginNext();
|
||||
return submitted;
|
||||
}
|
||||
|
||||
void CommandScheduler::Finish() {
|
||||
CheckActive();
|
||||
if (m_recording) {
|
||||
SubmitCurrent();
|
||||
}
|
||||
for (auto& buffer: m_buffers) {
|
||||
buffer->WaitForFenceAndReset();
|
||||
}
|
||||
BindCurrent();
|
||||
Current().Begin();
|
||||
m_recording = true;
|
||||
}
|
||||
|
||||
void CommandScheduler::FinishCurrent() {
|
||||
auto& submitted = SubmitCurrent();
|
||||
submitted.WaitForFenceAndReset();
|
||||
submitted.Begin();
|
||||
m_recording = true;
|
||||
}
|
||||
|
||||
void CommandScheduler::CheckActive() const {
|
||||
EXIT_IF(!Active() || m_current >= BufferCount);
|
||||
}
|
||||
|
||||
RenderCommandBuffer& CommandScheduler::Current() const {
|
||||
CheckActive();
|
||||
EXIT_IF(m_buffers[m_current] == nullptr);
|
||||
return *m_buffers[m_current];
|
||||
}
|
||||
|
||||
void CommandScheduler::BindCurrent() const {
|
||||
EXIT_IF(m_registers == nullptr || m_user_config == nullptr || m_shaders == nullptr);
|
||||
Current().Bind(*m_registers, *m_user_config, *m_shaders);
|
||||
}
|
||||
|
||||
CommandBuffer& CommandScheduler::SubmitCurrent() {
|
||||
CheckActive();
|
||||
EXIT_IF(!m_recording);
|
||||
auto& submitted = Current();
|
||||
submitted.End();
|
||||
submitted.Execute();
|
||||
m_recording = false;
|
||||
return submitted;
|
||||
}
|
||||
|
||||
void CommandScheduler::BeginNext() {
|
||||
EXIT_IF(m_recording);
|
||||
m_current = (m_current + 1) % BufferCount;
|
||||
Current().WaitForFenceAndReset();
|
||||
BindCurrent();
|
||||
Current().Begin();
|
||||
m_recording = true;
|
||||
}
|
||||
|
||||
} // namespace Libs::Graphics
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef EMULATOR_SRC_GRAPHICS_HOST_GPU_RENDERER_COMMANDSCHEDULER_H_
|
||||
#define EMULATOR_SRC_GRAPHICS_HOST_GPU_RENDERER_COMMANDSCHEDULER_H_
|
||||
|
||||
#include "common/common.h"
|
||||
#include "graphics/host_gpu/renderer/render.h"
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
namespace Libs::Graphics {
|
||||
|
||||
class CommandScheduler {
|
||||
public:
|
||||
static constexpr int BufferCount = 8;
|
||||
|
||||
CommandScheduler() = default;
|
||||
~CommandScheduler() = default;
|
||||
KYTY_CLASS_NO_COPY(CommandScheduler);
|
||||
|
||||
void Begin(HW::Context& registers, HW::UserConfig& user_config, HW::Shader& shaders);
|
||||
void Flush();
|
||||
CommandBuffer& FlushAndGetSubmitted();
|
||||
void Finish();
|
||||
void FinishCurrent();
|
||||
|
||||
[[nodiscard]] bool Active() const noexcept { return m_current >= 0; }
|
||||
void CheckActive() const;
|
||||
RenderCommandBuffer& Current() const;
|
||||
|
||||
private:
|
||||
void BindCurrent() const;
|
||||
CommandBuffer& SubmitCurrent();
|
||||
void BeginNext();
|
||||
|
||||
std::array<std::unique_ptr<RenderCommandBuffer>, BufferCount> m_buffers;
|
||||
int m_current = -1;
|
||||
bool m_recording = false;
|
||||
HW::Context* m_registers = nullptr;
|
||||
HW::UserConfig* m_user_config = nullptr;
|
||||
HW::Shader* m_shaders = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Libs::Graphics
|
||||
|
||||
#endif // EMULATOR_SRC_GRAPHICS_HOST_GPU_RENDERER_COMMANDSCHEDULER_H_
|
||||
@@ -129,17 +129,22 @@ private:
|
||||
|
||||
class RenderCommandBuffer final: public CommandBuffer {
|
||||
public:
|
||||
RenderCommandBuffer(HW::Context& registers, HW::UserConfig& user_config, HW::Shader& shaders)
|
||||
: m_registers(registers), m_user_config(user_config), m_shaders(shaders) {}
|
||||
RenderCommandBuffer() = default;
|
||||
|
||||
[[nodiscard]] HW::Context& GetRegisters() const noexcept { return m_registers; }
|
||||
[[nodiscard]] HW::UserConfig& GetUserConfig() const noexcept { return m_user_config; }
|
||||
[[nodiscard]] HW::Shader& GetShaders() const noexcept { return m_shaders; }
|
||||
void Bind(HW::Context& registers, HW::UserConfig& user_config, HW::Shader& shaders) noexcept {
|
||||
m_registers = ®isters;
|
||||
m_user_config = &user_config;
|
||||
m_shaders = &shaders;
|
||||
}
|
||||
|
||||
[[nodiscard]] HW::Context& GetRegisters() const noexcept { return *m_registers; }
|
||||
[[nodiscard]] HW::UserConfig& GetUserConfig() const noexcept { return *m_user_config; }
|
||||
[[nodiscard]] HW::Shader& GetShaders() const noexcept { return *m_shaders; }
|
||||
|
||||
private:
|
||||
HW::Context& m_registers;
|
||||
HW::UserConfig& m_user_config;
|
||||
HW::Shader& m_shaders;
|
||||
HW::Context* m_registers = nullptr;
|
||||
HW::UserConfig* m_user_config = nullptr;
|
||||
HW::Shader* m_shaders = nullptr;
|
||||
};
|
||||
|
||||
void RenderDrawIndex(uint64_t submit_id, RenderCommandBuffer& buffer, uint32_t index_type_and_size,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "common/common.h"
|
||||
#include "common/threads.h"
|
||||
#include "graphics/host_gpu/renderer/bufferCache.h"
|
||||
#include "graphics/host_gpu/renderer/commandScheduler.h"
|
||||
#include "graphics/host_gpu/renderer/descriptorCache.h"
|
||||
#include "graphics/host_gpu/renderer/framebufferCache.h"
|
||||
#include "graphics/host_gpu/renderer/gdsBuffer.h"
|
||||
@@ -30,6 +31,7 @@ public:
|
||||
[[nodiscard]] GraphicContext& GetGraphics() const noexcept { return m_graphics; }
|
||||
|
||||
Common::Mutex& GetMutex() { return m_mutex; }
|
||||
CommandScheduler& GetCommandScheduler() { return m_command_scheduler; }
|
||||
PipelineCache& GetPipelineCache() { return m_pipeline_cache; }
|
||||
DescriptorCache& GetDescriptorCache() { return m_descriptor_cache; }
|
||||
FramebufferCache& GetFramebufferCache() { return m_framebuffer_cache; }
|
||||
@@ -52,6 +54,7 @@ private:
|
||||
|
||||
GraphicContext& m_graphics;
|
||||
Common::Mutex m_mutex;
|
||||
CommandScheduler m_command_scheduler;
|
||||
PipelineCache m_pipeline_cache;
|
||||
DescriptorCache m_descriptor_cache;
|
||||
FramebufferCache m_framebuffer_cache;
|
||||
|
||||
@@ -3653,7 +3653,7 @@ bool TextureCache::InvalidateMemory(PageFaultAccess access, uint64_t vaddr, uint
|
||||
|
||||
if (needs_readback) {
|
||||
if (GraphicsRunIsCommandProcessorThread()) {
|
||||
GraphicsRunFinishCommandProcessors();
|
||||
GraphicsRunFinishScheduler();
|
||||
}
|
||||
m_readback->Request(access, vaddr, size);
|
||||
action = m_memory_tracker.BeginCpuFault(vaddr, size, access);
|
||||
|
||||
Reference in New Issue
Block a user