sceVideoOutSubmitFlip implementation

This commit is contained in:
georgemoralis 2023-09-10 12:59:21 +03:00
parent f1b1eacb67
commit 0c39b808bf
6 changed files with 70 additions and 6 deletions

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
constexpr int SCE_OK = 0; constexpr int SCE_OK = 0;
constexpr int SCE_KERNEL_ERROR_EBADF = 0x80020009; constexpr int SCE_KERNEL_ERROR_EBADF = 0x80020009;
constexpr int SCE_KERNEL_ERROR_ENOMEM = 0x8002000c; // Insufficient memory constexpr int SCE_KERNEL_ERROR_ENOMEM = 0x8002000c; // Insufficient memory
constexpr int SCE_KERNEL_ERROR_EFAULT = 0x8002000e; // Invalid address pointer constexpr int SCE_KERNEL_ERROR_EFAULT = 0x8002000e; // Invalid address pointer
constexpr int SCE_KERNEL_ERROR_EINVAL = 0x80020016; // null or invalid states constexpr int SCE_KERNEL_ERROR_EINVAL = 0x80020016; // null or invalid states
@ -11,5 +11,7 @@ constexpr int SCE_KERNEL_ERROR_ENAMETOOLONG = 0x8002003f; // character strings
// videoOut // videoOut
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; // invalid argument constexpr int SCE_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; // invalid argument
constexpr int SCE_VIDEO_OUT_ERROR_RESOURCE_BUSY = 0x80290009; // already opened constexpr int SCE_VIDEO_OUT_ERROR_RESOURCE_BUSY = 0x80290009; // already opened
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_INDEX = 0x8029000A; // invalid buffer index
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_HANDLE = 0x8029000B; // invalid handle constexpr int SCE_VIDEO_OUT_ERROR_INVALID_HANDLE = 0x8029000B; // invalid handle
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; // Invalid event queue constexpr int SCE_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; // Invalid event queue
constexpr int SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full

View File

@ -1,4 +1,5 @@
#include "video_out_ctx.h" #include "video_out_ctx.h"
#include <Core/PS4/HLE/LibKernel.h>
namespace HLE::Graphics::Objects { namespace HLE::Graphics::Objects {
@ -38,5 +39,28 @@ 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) {
Lib::LockMutexGuard lock(m_mutex);
if (m_requests.size() >= 2) {
return false;
}
Request r{};
r.cfg = cfg;
r.index = index;
r.flip_arg = flip_arg;
r.submit_tsc = HLE::Libs::LibKernel::sceKernelReadTsc();
m_requests.push_back(r);
cfg->m_flip_status.flipPendingNum = static_cast<int>(m_requests.size());
cfg->m_flip_status.gcQueueNum = 0;
m_submit_cond.SignalCondVar();
return true;
}
}; // namespace HLE::Graphics::Objects }; // namespace HLE::Graphics::Objects

View File

@ -24,9 +24,19 @@ class FlipQueue {
virtual ~FlipQueue() {} virtual ~FlipQueue() {}
void getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out); void getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out);
bool submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg);
private: private:
struct Request {
VideoConfigInternal* cfg;
int index;
int64_t flip_arg;
uint64_t submit_tsc;
};
Lib::Mutex m_mutex; Lib::Mutex m_mutex;
Lib::ConditionVariable m_submit_cond;
Lib::ConditionVariable m_done_cond;
std::vector<Request> m_requests;
}; };
class VideoOutCtx { class VideoOutCtx {

View File

@ -116,9 +116,30 @@ s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle) {
return 0; return 0;
} }
s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode, s64 flipArg) { s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode, s64 flipArg) {
// BREAKPOINT(); PRINT_FUNCTION_NAME();
PRINT_DUMMY_FUNCTION_NAME(); auto* videoOut = Singleton<HLE::Graphics::Objects::VideoOutCtx>::Instance();
return 0; auto* ctx = videoOut->getCtx(handle);
if (flipMode != 1) {
BREAKPOINT(); // only flipmode==1 is supported
}
if (bufferIndex == -1) {
BREAKPOINT(); // blank output not supported
}
if (bufferIndex < -1 || bufferIndex > 15) {
LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip invalid bufferIndex {}\n",bufferIndex);
return SCE_VIDEO_OUT_ERROR_INVALID_INDEX;
}
LOG_INFO_IF(log_file_videoout, "bufferIndex = {}\n", bufferIndex);
LOG_INFO_IF(log_file_videoout, "flipMode = {}\n", flipMode);
LOG_INFO_IF(log_file_videoout, "flipArg = {}\n", flipArg);
if (!videoOut->getFlipQueue().submitFlip(ctx, bufferIndex, flipArg)) {
LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip flip queue is full\n");
return SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL;
}
return SCE_OK;
} }
s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, SceVideoOutFlipStatus* status) { s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, SceVideoOutFlipStatus* status) {
PRINT_FUNCTION_NAME(); PRINT_FUNCTION_NAME();

View File

@ -21,6 +21,11 @@ namespace HLE::Libs::LibKernel {
static PS4_SYSV_ABI void stack_chk_fail() { BREAKPOINT(); static PS4_SYSV_ABI void stack_chk_fail() { BREAKPOINT();
} }
u64 PS4_SYSV_ABI sceKernelReadTsc() {
LARGE_INTEGER c;
QueryPerformanceCounter(&c);
return c.QuadPart;
}
void LibKernel_Register(SymbolsResolver* sym) { void LibKernel_Register(SymbolsResolver* sym) {
//obj //obj
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &HLE::Libs::LibKernel::g_stack_chk_guard); LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &HLE::Libs::LibKernel::g_stack_chk_guard);
@ -35,6 +40,8 @@ namespace HLE::Libs::LibKernel {
//misc //misc
LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", 1, 1, CPUManagement::sceKernelIsNeoMode); LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", 1, 1, CPUManagement::sceKernelIsNeoMode);
LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail); LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail);
//time
LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc);
} }
}; };

View File

@ -6,6 +6,6 @@ void LibKernel_Register(SymbolsResolver* sym);
// functions // functions
u64 PS4_SYSV_ABI sceKernelReadTsc();
int32_t PS4_SYSV_ABI sceKernelReleaseDirectMemory(off_t start, size_t len); int32_t PS4_SYSV_ABI sceKernelReleaseDirectMemory(off_t start, size_t len);
}; // namespace HLE::Libs::LibKernel }; // namespace HLE::Libs::LibKernel