#include "graphics/host_gpu/renderer/renderContext.h" #include "common/assert.h" #include "common/logging/log.h" #include "graphics/guest_gpu/graphicsRun.h" #include "graphics/presentation/videoOut.h" #include "libs/errno.h" #include namespace Libs::Graphics { RenderContext::RenderContext(GraphicContext& graphics) : m_graphics(graphics), m_render_executor(*this), m_command_scheduler(*this, graphics), m_descriptor_heap(graphics, m_command_scheduler.GetMasterSemaphore()), m_pipeline_cache(graphics), m_sampler_cache(graphics), m_gpu_resources(graphics, m_command_scheduler) { EXIT_NOT_IMPLEMENTED(!Common::Thread::IsMainThread()); } RenderContext::~RenderContext() { ShutdownGpu(); m_command_scheduler.Shutdown(); } void RenderContext::InitializeGpu(VideoOut::VideoOutDriver* video_out) { EXIT_IF(m_gpu != nullptr); m_video_out = video_out; m_gpu = std::make_unique(*this); m_gpu_resources.SetGpu(m_gpu.get()); } void RenderContext::ShutdownGpu() { if (m_gpu != nullptr) { m_gpu_resources.SetGpu(nullptr); m_gpu->Shutdown(); m_gpu.reset(); } if (m_video_out != nullptr) { if (m_command_scheduler.Active()) { m_command_scheduler.Finish(); } m_command_scheduler.DrainPriorityOperations(); m_video_out = nullptr; } } GuestGpu& RenderContext::GetGpu() const { EXIT_IF(m_gpu == nullptr); return *m_gpu; } VideoOut::VideoOutDriver& RenderContext::GetVideoOut() const { EXIT_IF(m_video_out == nullptr); return *m_video_out; } void RenderContext::AddInterruptEq(LibKernel::EventQueue::KernelEqueue eq, int event_id) { Common::LockGuard lock(m_interrupt_mutex); auto it = std::find_if( m_interrupt_eqs.begin(), m_interrupt_eqs.end(), [eq, event_id](const auto& entry) { return entry.eq == eq && entry.event_id == event_id; }); if (it != m_interrupt_eqs.end()) { return; } m_interrupt_eqs.push_back({eq, event_id}); } void RenderContext::DeleteInterruptEq(LibKernel::EventQueue::KernelEqueue eq, int event_id) { Common::LockGuard lock(m_interrupt_mutex); auto it = std::find_if( m_interrupt_eqs.begin(), m_interrupt_eqs.end(), [eq, event_id](const auto& entry) { return entry.eq == eq && entry.event_id == event_id; }); if (it == m_interrupt_eqs.end()) { return; } m_interrupt_eqs.erase(it); } void RenderContext::TriggerInterrupt(int event_id, uint32_t context_id) { std::vector registrations; { Common::LockGuard lock(m_interrupt_mutex); for (const auto& registration: m_interrupt_eqs) { if (registration.event_id == event_id) { registrations.push_back(registration); } } } for (const auto& registration: registrations) { const auto result = LibKernel::EventQueue::KernelTriggerEvent( registration.eq, static_cast(registration.event_id), LibKernel::EventQueue::KERNEL_EVFILT_GRAPHICS, reinterpret_cast(static_cast(context_id))); if (result == LibKernel::KERNEL_ERROR_EBADF || result == LibKernel::KERNEL_ERROR_ENOENT) { DeleteInterruptEq(registration.eq, registration.event_id); continue; } EXIT_NOT_IMPLEMENTED(result != OK); } } } // namespace Libs::Graphics