event queue events now process nicely

This commit is contained in:
georgemoralis 2023-09-11 13:14:13 +03:00
parent 0c39b808bf
commit ab932e7503
7 changed files with 82 additions and 6 deletions

View file

@ -1,4 +1,5 @@
#include "video_out_ctx.h" #include "video_out_ctx.h"
#include <Core/PS4/HLE/LibKernel.h> #include <Core/PS4/HLE/LibKernel.h>
namespace HLE::Graphics::Objects { namespace HLE::Graphics::Objects {
@ -30,7 +31,7 @@ int VideoOutCtx::Open() {
VideoConfigInternal* VideoOutCtx::getCtx(int handle) { VideoConfigInternal* VideoOutCtx::getCtx(int handle) {
if (handle != 1) return nullptr; if (handle != 1) return nullptr;
return &m_video_out_ctx; // assuming that it's the only ctx TODO check if we need more return &m_video_out_ctx; // assuming that it's the only ctx TODO check if we need more
} }
void FlipQueue::getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out) { void FlipQueue::getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out) {
@ -39,7 +40,7 @@ void FlipQueue::getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* o
*out = cfg->m_flip_status; *out = cfg->m_flip_status;
} }
bool FlipQueue::submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg) { bool FlipQueue::submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg) {
Lib::LockMutexGuard lock(m_mutex); Lib::LockMutexGuard lock(m_mutex);
if (m_requests.size() >= 2) { if (m_requests.size() >= 2) {
@ -62,5 +63,41 @@ bool FlipQueue::submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg) {
return true; return true;
} }
}; // namespace HLE::Graphics::Objects bool FlipQueue::flip(u32 micros) {
m_mutex.LockMutex();
if (m_requests.size() == 0) {
m_submit_cond.WaitCondVarFor(&m_mutex, micros);
if (m_requests.size() == 0) {
m_mutex.UnlockMutex();
return false;
}
}
auto request = m_requests.at(0); // proceed first request
m_mutex.UnlockMutex();
request.cfg->m_mutex.LockMutex();
for (auto& flip_eq : request.cfg->m_flip_evtEq) {
if (flip_eq != nullptr) {
flip_eq->triggerEvent(SCE_VIDEO_OUT_EVENT_FLIP, HLE::Kernel::Objects::EVFILT_VIDEO_OUT, reinterpret_cast<void*>(request.flip_arg));
}
}
request.cfg->m_mutex.UnlockMutex();
m_requests.erase(m_requests.begin());
m_done_cond.SignalCondVar();
request.cfg->m_flip_status.count++;
//TODO request.cfg->m_flip_status.processTime = LibKernel::KernelGetProcessTime();
request.cfg->m_flip_status.tsc = HLE::Libs::LibKernel::sceKernelReadTsc();
request.cfg->m_flip_status.submitTsc = request.submit_tsc;
request.cfg->m_flip_status.flipArg = request.flip_arg;
request.cfg->m_flip_status.currentBuffer = request.index;
request.cfg->m_flip_status.flipPendingNum = static_cast<int>(m_requests.size());
m_mutex.UnlockMutex();
return false;
}
}; // namespace HLE::Graphics::Objects

View file

@ -25,6 +25,7 @@ class FlipQueue {
void getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out); void getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out);
bool submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg); bool submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg);
bool flip(u32 micros);
private: private:
struct Request { struct Request {
VideoConfigInternal* cfg; VideoConfigInternal* cfg;

View file

@ -21,6 +21,12 @@ void videoOutInit(u32 width, u32 height) {
auto* videoOut = Singleton<HLE::Graphics::Objects::VideoOutCtx>::Instance(); auto* videoOut = Singleton<HLE::Graphics::Objects::VideoOutCtx>::Instance();
videoOut->Init(width, height); videoOut->Init(width, height);
} }
bool videoOutFlip(u32 micros) {
auto* videoOut = Singleton<HLE::Graphics::Objects::VideoOutCtx>::Instance();
return videoOut->getFlipQueue().flip(micros);
}
std::string getPixelFormatString(s32 format) { std::string getPixelFormatString(s32 format) {
switch (format) { switch (format) {
case SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB: return "PIXEL_FORMAT_A8R8G8B8_SRGB"; case SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB: return "PIXEL_FORMAT_A8R8G8B8_SRGB";
@ -64,6 +70,15 @@ static void flip_reset_event_func(HLE::Kernel::Objects::EqueueEvent* event) {
event->event.fflags = 0; event->event.fflags = 0;
event->event.data = 0; event->event.data = 0;
} }
static void flip_trigger_event_func(HLE::Kernel::Objects::EqueueEvent* event, void* trigger_data) {
event->isTriggered = true;
event->event.fflags++;
event->event.data = reinterpret_cast<intptr_t>(trigger_data);
}
static void flip_delete_event_func(LibKernel::EventQueues::SceKernelEqueue eq, HLE::Kernel::Objects::EqueueEvent* event) {
BREAKPOINT(); // TODO
}
s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue eq, s32 handle, void* udata) { s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue eq, s32 handle, void* udata) {
PRINT_FUNCTION_NAME(); PRINT_FUNCTION_NAME();
auto* videoOut = Singleton<HLE::Graphics::Objects::VideoOutCtx>::Instance(); auto* videoOut = Singleton<HLE::Graphics::Objects::VideoOutCtx>::Instance();
@ -86,9 +101,9 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue
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.delete_event_func = flip_event_delete_func;//called in sceKernelDeleteEvent //TODO event.filter.delete_event_func = flip_delete_event_func;
event.filter.reset_event_func = flip_reset_event_func; event.filter.reset_event_func = flip_reset_event_func;
// event.filter.trigger_event_func = flip_event_trigger_func;//called in sceKernelTriggerEvent //TODO event.filter.trigger_event_func = flip_trigger_event_func;
event.filter.data = ctx; event.filter.data = ctx;
int result = eq->addEvent(event); int result = eq->addEvent(event);
@ -127,7 +142,7 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode
BREAKPOINT(); // blank output not supported BREAKPOINT(); // blank output not supported
} }
if (bufferIndex < -1 || bufferIndex > 15) { if (bufferIndex < -1 || bufferIndex > 15) {
LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip invalid bufferIndex {}\n",bufferIndex); LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip invalid bufferIndex {}\n", bufferIndex);
return SCE_VIDEO_OUT_ERROR_INVALID_INDEX; return SCE_VIDEO_OUT_ERROR_INVALID_INDEX;
} }
LOG_INFO_IF(log_file_videoout, "bufferIndex = {}\n", bufferIndex); LOG_INFO_IF(log_file_videoout, "bufferIndex = {}\n", bufferIndex);

View file

@ -90,6 +90,7 @@ struct SceVideoOutVblankStatus {
void videoOutInit(u32 width, u32 height); void videoOutInit(u32 width, u32 height);
std::string getPixelFormatString(s32 format); std::string getPixelFormatString(s32 format);
void videoOutRegisterLib(SymbolsResolver* sym); void videoOutRegisterLib(SymbolsResolver* sym);
bool videoOutFlip(u32 micros);
void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(SceVideoOutBufferAttribute* attribute, u32 pixelFormat, u32 tilingMode, u32 aspectRatio, u32 width, void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(SceVideoOutBufferAttribute* attribute, u32 pixelFormat, u32 tilingMode, u32 aspectRatio, u32 width,
u32 height, u32 pitchInPixel); u32 height, u32 pitchInPixel);

View file

@ -49,6 +49,25 @@ int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) {
return 0; return 0;
} }
bool EqueueInternal::triggerEvent(u64 ident, s16 filter, void* trigger_data) {
Lib::LockMutexGuard lock(m_mutex);
if (m_events.size() > 1) {
BREAKPOINT(); // we currently support one event
}
auto& event = m_events[0];
if (event.filter.trigger_event_func != nullptr) {
event.filter.trigger_event_func(&event, trigger_data);
} else {
event.isTriggered = true;
}
m_cond.SignalCondVar();
return true;
}
int EqueueInternal::getTriggeredEvents(SceKernelEvent* ev, int num) { int EqueueInternal::getTriggeredEvents(SceKernelEvent* ev, int num) {
Lib::LockMutexGuard lock(m_mutex); Lib::LockMutexGuard lock(m_mutex);

View file

@ -67,6 +67,7 @@ class EqueueInternal {
void setName(const std::string& m_name) { this->m_name = m_name; } void setName(const std::string& m_name) { this->m_name = m_name; }
int addEvent(const EqueueEvent& event); int addEvent(const EqueueEvent& event);
int waitForEvents(SceKernelEvent* ev, int num, u32 micros); int waitForEvents(SceKernelEvent* ev, int num, u32 micros);
bool triggerEvent(u64 ident, s16 filter, void* trigger_data);
int getTriggeredEvents(SceKernelEvent* ev, int num); int getTriggeredEvents(SceKernelEvent* ev, int num);
private: private:
std::string m_name; std::string m_name;

View file

@ -1,9 +1,11 @@
#include "emulator.h" #include "emulator.h"
#include "Core/PS4/HLE/Graphics/video_out.h"
namespace Emulator { namespace Emulator {
void emuInit() {} void emuInit() {}
void emuRun() { void emuRun() {
for (;;) { for (;;) {
HLE::Libs::Graphics::VideoOut::videoOutFlip(100000);//flip every 0.1 sec
} }
} }
} // namespace emulator } // namespace emulator