kernel: equeue: minor refactoring

This commit is contained in:
psucien 2024-07-09 12:12:15 +02:00 committed by georgemoralis
parent ea7465a82d
commit 465cb0413e
9 changed files with 159 additions and 125 deletions

View File

@ -41,6 +41,8 @@ enum MarkersPallete : int {
#define RENDERER_TRACE ZoneScopedC(RendererMarkerColor) #define RENDERER_TRACE ZoneScopedC(RendererMarkerColor)
#define HLE_TRACE ZoneScopedC(HleMarkerColor) #define HLE_TRACE ZoneScopedC(HleMarkerColor)
#define TRACE_HINT(str) ZoneText(str.c_str(), str.size())
#define TRACE_WARN(msg) \ #define TRACE_WARN(msg) \
[](const auto& msg) { TracyMessageC(msg.c_str(), msg.size(), tracy::Color::DarkOrange); }(msg); [](const auto& msg) { TracyMessageC(msg.c_str(), msg.size(), tracy::Color::DarkOrange); }(msg);
#define TRACE_ERROR(msg) \ #define TRACE_ERROR(msg) \

View File

@ -26,6 +26,17 @@ using namespace AmdGpu;
static std::unique_ptr<AmdGpu::Liverpool> liverpool; static std::unique_ptr<AmdGpu::Liverpool> liverpool;
enum GnmEventIdents : u64 {
Compute0RelMem = 0x00,
Compute1RelMem = 0x01,
Compute2RelMem = 0x02,
Compute3RelMem = 0x03,
Compute4RelMem = 0x04,
Compute5RelMem = 0x05,
Compute6RelMem = 0x06,
GfxEop = 0x40
};
enum ShaderStages : u32 { enum ShaderStages : u32 {
Cs, Cs,
Ps, Ps,
@ -327,10 +338,6 @@ static inline u32* ClearContextState(u32* cmdbuf) {
s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata) { s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata) {
LOG_TRACE(Lib_GnmDriver, "called"); LOG_TRACE(Lib_GnmDriver, "called");
if (id != SceKernelEvent::Type::GfxEop) {
return ORBIS_OK;
}
ASSERT_MSG(id == SceKernelEvent::Type::GfxEop);
if (!eq) { if (!eq) {
return ORBIS_KERNEL_ERROR_EBADF; return ORBIS_KERNEL_ERROR_EBADF;
@ -338,20 +345,20 @@ s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata) {
EqueueEvent kernel_event{}; EqueueEvent kernel_event{};
kernel_event.event.ident = id; kernel_event.event.ident = id;
kernel_event.event.filter = EVFILT_GRAPHICS_CORE; kernel_event.event.filter = SceKernelEvent::Filter::GraphicsCore;
kernel_event.event.flags = 1; kernel_event.event.flags = SceKernelEvent::Flags::Add;
kernel_event.event.fflags = 0; kernel_event.event.fflags = 0;
kernel_event.event.data = id; kernel_event.event.data = id;
kernel_event.event.udata = udata; kernel_event.event.udata = udata;
eq->addEvent(kernel_event); eq->AddEvent(kernel_event);
Platform::IrqC::Instance()->Register( Platform::IrqC::Instance()->Register(
Platform::InterruptId::GfxEop, Platform::InterruptId::GfxEop,
[=](Platform::InterruptId irq) { [=](Platform::InterruptId irq) {
ASSERT_MSG(irq == Platform::InterruptId::GfxEop, ASSERT_MSG(irq == Platform::InterruptId::GfxEop,
"An unexpected IRQ occured"); // We need to conver IRQ# to event id and do "An unexpected IRQ occured"); // We need to convert IRQ# to event id and do
// proper filtering in trigger function // proper filtering in trigger function
eq->triggerEvent(SceKernelEvent::Type::GfxEop, EVFILT_GRAPHICS_CORE, nullptr); eq->TriggerEvent(GnmEventIdents::GfxEop, SceKernelEvent::Filter::GraphicsCore, nullptr);
}, },
eq); eq);
return ORBIS_OK; return ORBIS_OK;
@ -455,13 +462,13 @@ int PS4_SYSV_ABI sceGnmDebugHardwareStatus() {
s32 PS4_SYSV_ABI sceGnmDeleteEqEvent(SceKernelEqueue eq, u64 id) { s32 PS4_SYSV_ABI sceGnmDeleteEqEvent(SceKernelEqueue eq, u64 id) {
LOG_TRACE(Lib_GnmDriver, "called"); LOG_TRACE(Lib_GnmDriver, "called");
ASSERT_MSG(id == SceKernelEvent::Type::GfxEop); ASSERT_MSG(id == GnmEventIdents::GfxEop);
if (!eq) { if (!eq) {
return ORBIS_KERNEL_ERROR_EBADF; return ORBIS_KERNEL_ERROR_EBADF;
} }
eq->removeEvent(id); eq->RemoveEvent(id);
Platform::IrqC::Instance()->Unregister(Platform::InterruptId::GfxEop, eq); Platform::IrqC::Instance()->Unregister(Platform::InterruptId::GfxEop, eq);
return ORBIS_OK; return ORBIS_OK;

View File

@ -8,32 +8,40 @@ namespace Libraries::Kernel {
EqueueInternal::~EqueueInternal() = default; EqueueInternal::~EqueueInternal() = default;
int EqueueInternal::addEvent(const EqueueEvent& event) { bool EqueueInternal::AddEvent(EqueueEvent& event) {
std::scoped_lock lock{m_mutex}; std::scoped_lock lock{m_mutex};
ASSERT(!event.isTriggered); event.time_added = std::chrono::high_resolution_clock::now();
// TODO check if event is already exists and return it. Currently we just add in m_events array const auto& it = std::ranges::find(m_events, event);
m_events.push_back(event); if (it != m_events.cend()) {
return 0; *it = event;
} else {
m_events.emplace_back(event);
} }
int EqueueInternal::removeEvent(u64 id) { return true;
}
bool EqueueInternal::RemoveEvent(u64 id) {
bool has_found = false;
std::scoped_lock lock{m_mutex}; std::scoped_lock lock{m_mutex};
const auto& event_q = const auto& it =
std::ranges::find_if(m_events, [id](auto& ev) { return ev.event.ident == id; }); std::ranges::find_if(m_events, [id](auto& ev) { return ev.event.ident == id; });
ASSERT(event_q != m_events.cend()); if (it != m_events.cend()) {
m_events.erase(event_q); m_events.erase(it);
return 0; has_found = true;
}
return has_found;
} }
int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) { int EqueueInternal::WaitForEvents(SceKernelEvent* ev, int num, u32 micros) {
std::unique_lock lock{m_mutex}; std::unique_lock lock{m_mutex};
int ret = 0; int ret = 0;
const auto predicate = [&] { const auto predicate = [&] {
ret = getTriggeredEvents(ev, num); ret = GetTriggeredEvents(ev, num);
return ret > 0; return ret > 0;
}; };
@ -45,28 +53,38 @@ int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) {
return ret; return ret;
} }
bool EqueueInternal::triggerEvent(u64 ident, s16 filter, void* trigger_data) { bool EqueueInternal::TriggerEvent(u64 ident, s16 filter, void* trigger_data) {
bool has_found = false;
{ {
std::scoped_lock lock{m_mutex}; std::scoped_lock lock{m_mutex};
for (auto& event : m_events) { for (auto& event : m_events) {
if (event.event.ident == ident) { // event filter? ASSERT_MSG(event.event.filter == filter,
event.trigger(trigger_data); "Event to trigger doesn't match to queue events");
if (event.event.ident == ident) {
event.Trigger(trigger_data);
has_found = true;
} }
} }
} }
m_cond.notify_one(); m_cond.notify_one();
return has_found;
return true;
} }
int EqueueInternal::getTriggeredEvents(SceKernelEvent* ev, int num) { int EqueueInternal::GetTriggeredEvents(SceKernelEvent* ev, int num) {
int ret = 0; int ret = 0;
for (auto& event : m_events) { for (auto& event : m_events) {
if (event.isTriggered) { if (event.IsTriggered()) {
if (ev->flags & SceKernelEvent::Flags::Clear) {
event.Reset();
}
ev[ret++] = event.event; ev[ret++] = event.event;
event.reset();
if (ret == num) {
break;
}
} }
} }

View File

@ -11,83 +11,76 @@
namespace Libraries::Kernel { namespace Libraries::Kernel {
constexpr s16 EVFILT_READ = -1;
constexpr s16 EVFILT_WRITE = -2;
constexpr s16 EVFILT_AIO = -3; // attached to aio requests
constexpr s16 EVFILT_VNODE = -4; // attached to vnodes
constexpr s16 EVFILT_PROC = -5; // attached to struct proc
constexpr s16 EVFILT_SIGNAL = -6; // attached to struct proc
constexpr s16 EVFILT_TIMER = -7; // timers
constexpr s16 EVFILT_FS = -9; // filesystem events
constexpr s16 EVFILT_LIO = -10; // attached to lio requests
constexpr s16 EVFILT_USER = -11; // User events
constexpr s16 EVFILT_POLLING = -12;
constexpr s16 EVFILT_VIDEO_OUT = -13;
constexpr s16 EVFILT_GRAPHICS_CORE = -14;
constexpr s16 EVFILT_HRTIMER = -15;
constexpr s16 EVFILT_UVD_TRAP = -16;
constexpr s16 EVFILT_VCE_TRAP = -17;
constexpr s16 EVFILT_SDMA_TRAP = -18;
constexpr s16 EVFILT_REG_EV = -19;
constexpr s16 EVFILT_GPU_EXCEPTION = -20;
constexpr s16 EVFILT_GPU_SYSTEM_EXCEPTION = -21;
constexpr s16 EVFILT_GPU_DBGGC_EV = -22;
constexpr s16 EVFILT_SYSCOUNT = 22;
constexpr u16 EV_ONESHOT = 0x10; // only report one occurrence
constexpr u16 EV_CLEAR = 0x20; // clear event state after reporting
constexpr u16 EV_RECEIPT = 0x40; // force EV_ERROR on success, data=0
constexpr u16 EV_DISPATCH = 0x80; // disable event after reporting
constexpr u16 EV_SYSFLAGS = 0xF000; // reserved by system
constexpr u16 EV_FLAG1 = 0x2000; // filter-specific flag
class EqueueInternal; class EqueueInternal;
struct EqueueEvent; struct EqueueEvent;
using TriggerFunc = void (*)(EqueueEvent* event, void* trigger_data);
using ResetFunc = void (*)(EqueueEvent* event);
using DeleteFunc = void (*)(EqueueInternal* eq, EqueueEvent* event);
struct SceKernelEvent { struct SceKernelEvent {
enum Type : u64 { enum Filter : s16 {
Compute0RelMem = 0x00, None = 0,
Compute1RelMem = 0x01, Read = -1,
Compute2RelMem = 0x02, Write = -2,
Compute3RelMem = 0x03, Aio = -3,
Compute4RelMem = 0x04, Vnode = -4,
Compute5RelMem = 0x05, Proc = -5,
Compute6RelMem = 0x06, Signal = -6,
GfxEop = 0x40 Timer = -7,
Fs = -9,
Lio = -10,
User = -11,
Polling = -12,
VideoOut = -13,
GraphicsCore = -14,
HrTimer = -15,
};
enum Flags : u16 {
Add = 1u,
Delete = 2u,
Enable = 4u,
Disable = 8u,
OneShot = 0x10u,
Clear = 0x20u,
Receipt = 0x40u,
Dispatch = 0x80u,
Flag1 = 0x2000u,
System = 0xf000u,
}; };
u64 ident = 0; /* identifier for this event */ u64 ident = 0; /* identifier for this event */
s16 filter = 0; /* filter for event */ Filter filter = Filter::None; /* filter for event */
u16 flags = 0; u16 flags = 0;
u32 fflags = 0; u32 fflags = 0;
u64 data = 0; u64 data = 0;
void* udata = nullptr; /* opaque user data identifier */ void* udata = nullptr; /* opaque user data identifier */
}; };
struct Filter {
void* data = nullptr;
};
struct EqueueEvent { struct EqueueEvent {
bool isTriggered = false;
SceKernelEvent event; SceKernelEvent event;
Filter filter; void* data = nullptr;
std::chrono::steady_clock::time_point time_added;
void reset() { void Reset() {
isTriggered = false; is_triggered = false;
event.fflags = 0; event.fflags = 0;
event.data = 0; event.data = 0;
} }
void trigger(void* data) { void Trigger(void* data) {
isTriggered = true; is_triggered = true;
event.fflags++; event.fflags++;
event.data = reinterpret_cast<uintptr_t>(data); event.data = reinterpret_cast<uintptr_t>(data);
} }
bool IsTriggered() const {
return is_triggered;
}
bool operator==(const EqueueEvent& ev) const {
return ev.event.ident == event.ident;
}
private:
bool is_triggered = false;
}; };
class EqueueInternal { class EqueueInternal {
@ -97,11 +90,14 @@ public:
void setName(const std::string& m_name) { void setName(const std::string& m_name) {
this->m_name = m_name; this->m_name = m_name;
} }
int addEvent(const EqueueEvent& event); const auto& GetName() const {
int removeEvent(u64 id); return m_name;
int waitForEvents(SceKernelEvent* ev, int num, u32 micros); }
bool triggerEvent(u64 ident, s16 filter, void* trigger_data); bool AddEvent(EqueueEvent& event);
int getTriggeredEvents(SceKernelEvent* ev, int num); bool RemoveEvent(u64 id);
int WaitForEvents(SceKernelEvent* ev, int num, u32 micros);
bool TriggerEvent(u64 ident, s16 filter, void* trigger_data);
int GetTriggeredEvents(SceKernelEvent* ev, int num);
private: private:
std::string m_name; std::string m_name;

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/libraries/error_codes.h" #include "core/libraries/error_codes.h"
#include "core/libraries/kernel/event_queues.h" #include "core/libraries/kernel/event_queues.h"
@ -43,31 +44,33 @@ int PS4_SYSV_ABI sceKernelDeleteEqueue(SceKernelEqueue eq) {
int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, SceKernelEvent* ev, int num, int* out, int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, SceKernelEvent* ev, int num, int* out,
SceKernelUseconds* timo) { SceKernelUseconds* timo) {
LOG_INFO(Kernel_Event, "num = {}", num); HLE_TRACE;
TRACE_HINT(eq->GetName());
LOG_TRACE(Kernel_Event, "equeue = {} num = {}", eq->GetName(), num);
if (eq == nullptr) { if (eq == nullptr) {
return ORBIS_KERNEL_ERROR_EBADF; return ORBIS_KERNEL_ERROR_EBADF;
} }
if (ev == nullptr) { if (ev == nullptr) {
return SCE_KERNEL_ERROR_EFAULT; return ORBIS_KERNEL_ERROR_EFAULT;
} }
if (num < 1) { if (num < 1) {
return SCE_KERNEL_ERROR_EINVAL; return ORBIS_KERNEL_ERROR_EINVAL;
} }
if (timo == nullptr) { // wait until an event arrives without timing out if (timo == nullptr) { // wait until an event arrives without timing out
*out = eq->waitForEvents(ev, num, 0); *out = eq->WaitForEvents(ev, num, 0);
} }
if (timo != nullptr) { if (timo != nullptr) {
// Only events that have already arrived at the time of this function call can be received // Only events that have already arrived at the time of this function call can be received
if (*timo == 0) { if (*timo == 0) {
*out = eq->getTriggeredEvents(ev, num); *out = eq->GetTriggeredEvents(ev, num);
} else { } else {
// Wait until an event arrives with timing out // Wait until an event arrives with timing out
*out = eq->waitForEvents(ev, num, *timo); *out = eq->WaitForEvents(ev, num, *timo);
} }
} }
@ -83,16 +86,15 @@ int PS4_SYSV_ABI sceKernelAddUserEvent(SceKernelEqueue eq, int id) {
return ORBIS_KERNEL_ERROR_EBADF; return ORBIS_KERNEL_ERROR_EBADF;
} }
Kernel::EqueueEvent event{}; EqueueEvent event{};
event.isTriggered = false;
event.event.ident = id; event.event.ident = id;
event.event.filter = Kernel::EVFILT_USER; event.event.filter = SceKernelEvent::Filter::User;
event.event.udata = 0; event.event.udata = 0;
event.event.flags = 1; event.event.flags = SceKernelEvent::Flags::Add;
event.event.fflags = 0; event.event.fflags = 0;
event.event.data = 0; event.event.data = 0;
return eq->addEvent(event); return eq->AddEvent(event) ? ORBIS_OK : ORBIS_KERNEL_ERROR_ENOMEM;
} }
int PS4_SYSV_ABI sceKernelAddUserEventEdge(SceKernelEqueue eq, int id) { int PS4_SYSV_ABI sceKernelAddUserEventEdge(SceKernelEqueue eq, int id) {
@ -100,33 +102,41 @@ int PS4_SYSV_ABI sceKernelAddUserEventEdge(SceKernelEqueue eq, int id) {
return ORBIS_KERNEL_ERROR_EBADF; return ORBIS_KERNEL_ERROR_EBADF;
} }
Kernel::EqueueEvent event{}; EqueueEvent event{};
event.isTriggered = false;
event.event.ident = id; event.event.ident = id;
event.event.filter = Kernel::EVFILT_USER; event.event.filter = SceKernelEvent::Filter::User;
event.event.udata = 0; event.event.udata = 0;
event.event.flags = 0x21; event.event.flags = SceKernelEvent::Flags::Add | SceKernelEvent::Flags::Clear;
event.event.fflags = 0; event.event.fflags = 0;
event.event.data = 0; event.event.data = 0;
return eq->addEvent(event); return eq->AddEvent(event) ? ORBIS_OK : ORBIS_KERNEL_ERROR_ENOMEM;
} }
void* PS4_SYSV_ABI sceKernelGetEventUserData(const SceKernelEvent* ev) { void* PS4_SYSV_ABI sceKernelGetEventUserData(const SceKernelEvent* ev) {
if (!ev) { ASSERT(ev);
return nullptr;
}
return ev->udata; return ev->udata;
} }
int PS4_SYSV_ABI sceKernelTriggerUserEvent(SceKernelEqueue eq, int id, void* udata) { int PS4_SYSV_ABI sceKernelTriggerUserEvent(SceKernelEqueue eq, int id, void* udata) {
eq->triggerEvent(id, Kernel::EVFILT_USER, udata); if (eq == nullptr) {
return ORBIS_KERNEL_ERROR_EBADF;
}
if (!eq->TriggerEvent(id, SceKernelEvent::Filter::User, udata)) {
return ORBIS_KERNEL_ERROR_ENOENT;
}
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceKernelDeleteUserEvent(SceKernelEqueue eq, int id) { int PS4_SYSV_ABI sceKernelDeleteUserEvent(SceKernelEqueue eq, int id) {
eq->removeEvent(id); if (eq == nullptr) {
return ORBIS_KERNEL_ERROR_EBADF;
}
if (!eq->RemoveEvent(id)) {
return ORBIS_KERNEL_ERROR_ENOENT;
}
return ORBIS_OK; return ORBIS_OK;
} }

View File

@ -19,5 +19,6 @@ int PS4_SYSV_ABI sceKernelTriggerUserEvent(SceKernelEqueue eq, int id, void* uda
int PS4_SYSV_ABI sceKernelDeleteUserEvent(SceKernelEqueue eq, int id); int PS4_SYSV_ABI sceKernelDeleteUserEvent(SceKernelEqueue eq, int id);
int PS4_SYSV_ABI sceKernelAddUserEvent(SceKernelEqueue eq, int id); int PS4_SYSV_ABI sceKernelAddUserEvent(SceKernelEqueue eq, int id);
int PS4_SYSV_ABI sceKernelAddUserEventEdge(SceKernelEqueue eq, int id); int PS4_SYSV_ABI sceKernelAddUserEventEdge(SceKernelEqueue eq, int id);
s32 PS4_SYSV_ABI sceKernelAddHRTimerEvent(SceKernelEqueue eq, int id, timespec* ts, void* udata);
} // namespace Libraries::Kernel } // namespace Libraries::Kernel

View File

@ -295,8 +295,8 @@ int PS4_SYSV_ABI sceKernelUuidCreate(OrbisKernelUuid* orbisUuid) {
return 0; return 0;
} }
char* PS4_SYSV_ABI sceKernelGetFsSandboxRandomWord() { const char* PS4_SYSV_ABI sceKernelGetFsSandboxRandomWord() {
char* path = "sys"; const char* path = "sys";
return path; return path;
} }
@ -353,6 +353,7 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("vz+pg2zdopI", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventUserData); LIB_FUNCTION("vz+pg2zdopI", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventUserData);
LIB_FUNCTION("4R6-OvI2cEA", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEvent); LIB_FUNCTION("4R6-OvI2cEA", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEvent);
LIB_FUNCTION("WDszmSbWuDk", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEventEdge); LIB_FUNCTION("WDszmSbWuDk", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEventEdge);
LIB_FUNCTION("R74tt43xP6k", "libkernel", 1, "libkernel", 1, 1, sceKernelAddHRTimerEvent);
LIB_FUNCTION("F6e0kwo4cnk", "libkernel", 1, "libkernel", 1, 1, sceKernelTriggerUserEvent); LIB_FUNCTION("F6e0kwo4cnk", "libkernel", 1, "libkernel", 1, 1, sceKernelTriggerUserEvent);
LIB_FUNCTION("LJDwdSNTnDg", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteUserEvent); LIB_FUNCTION("LJDwdSNTnDg", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteUserEvent);

View File

@ -196,7 +196,7 @@ void VideoOutDriver::Flip(std::chrono::microseconds timeout) {
// Trigger flip events for the port. // Trigger flip events for the port.
for (auto& event : req.port->flip_events) { for (auto& event : req.port->flip_events) {
if (event != nullptr) { if (event != nullptr) {
event->triggerEvent(SCE_VIDEO_OUT_EVENT_FLIP, Kernel::EVFILT_VIDEO_OUT, event->TriggerEvent(SCE_VIDEO_OUT_EVENT_FLIP, Kernel::SceKernelEvent::Filter::VideoOut,
reinterpret_cast<void*>(req.flip_arg)); reinterpret_cast<void*>(req.flip_arg));
} }
} }
@ -252,7 +252,8 @@ void VideoOutDriver::Vblank() {
// Trigger flip events for the port. // Trigger flip events for the port.
for (auto& event : main_port.vblank_events) { for (auto& event : main_port.vblank_events) {
if (event != nullptr) { if (event != nullptr) {
event->triggerEvent(SCE_VIDEO_OUT_EVENT_VBLANK, Kernel::EVFILT_VIDEO_OUT, nullptr); event->TriggerEvent(SCE_VIDEO_OUT_EVENT_VBLANK,
Kernel::SceKernelEvent::Filter::VideoOut, nullptr);
} }
} }
} }

View File

@ -48,16 +48,15 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Kernel::SceKernelEqueue eq, s32 handle,
} }
Kernel::EqueueEvent event{}; Kernel::EqueueEvent event{};
event.isTriggered = false;
event.event.ident = SCE_VIDEO_OUT_EVENT_FLIP; event.event.ident = SCE_VIDEO_OUT_EVENT_FLIP;
event.event.filter = Kernel::EVFILT_VIDEO_OUT; event.event.filter = Kernel::SceKernelEvent::Filter::VideoOut;
event.event.udata = udata; event.event.udata = udata;
event.event.fflags = 0; event.event.fflags = 0;
event.event.data = 0; event.event.data = 0;
event.filter.data = port; event.data = port;
port->flip_events.push_back(eq); port->flip_events.push_back(eq);
return eq->addEvent(event); return eq->AddEvent(event);
} }
s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::SceKernelEqueue eq, s32 handle, void* udata) { s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::SceKernelEqueue eq, s32 handle, void* udata) {
@ -73,16 +72,15 @@ s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::SceKernelEqueue eq, s32 handl
} }
Kernel::EqueueEvent event{}; Kernel::EqueueEvent event{};
event.isTriggered = false;
event.event.ident = SCE_VIDEO_OUT_EVENT_VBLANK; event.event.ident = SCE_VIDEO_OUT_EVENT_VBLANK;
event.event.filter = Kernel::EVFILT_VIDEO_OUT; event.event.filter = Kernel::SceKernelEvent::Filter::VideoOut;
event.event.udata = udata; event.event.udata = udata;
event.event.fflags = 0; event.event.fflags = 0;
event.event.data = 0; event.event.data = 0;
event.filter.data = port; event.data = port;
port->vblank_events.push_back(eq); port->vblank_events.push_back(eq);
return eq->addEvent(event); return eq->AddEvent(event);
} }
s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses, s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses,