sceVideoOutSubmitFlip implementation
This commit is contained in:
parent
f1b1eacb67
commit
0c39b808bf
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
|
@ -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
|
Loading…
Reference in New Issue