NvFence: fix regression on 1.x

This commit is contained in:
fincs 2018-10-06 16:47:25 +02:00
parent 4fb364060c
commit 20204e3c48
2 changed files with 41 additions and 14 deletions

View File

@ -3,6 +3,7 @@
#include "arm/atomics.h"
#include "kernel/svc.h"
#include "kernel/event.h"
#include "kernel/detect.h"
#include "services/nv.h"
#include "nvidia/fence.h"
@ -91,7 +92,20 @@ void nvFenceExit(void)
}
}
Result nvFenceWait(NvFence* f, s32 timeout_us)
static Result _nvFenceEventWaitCommon(Event* event, u32 event_id, s32 timeout_us)
{
u64 timeout_ns = U64_MAX;
if (timeout_us >= 0)
timeout_ns = (u64)1000*timeout_us;
Result rc = eventWait(event, timeout_ns);
if ((rc & 0x3FFFFF) == 0xEA01) { // timeout
nvioctlNvhostCtrl_EventSignal(g_ctrl_fd, event_id);
rc = MAKERESULT(Module_LibnxNvidia, LibnxNvidiaError_Timeout);
}
return rc;
}
static Result _nvFenceWait_200(NvFence* f, s32 timeout_us)
{
Result rc = MAKERESULT(Module_LibnxNvidia, LibnxNvidiaError_InsufficientMemory);
int event_id = _nvGetEventSlot();
@ -99,22 +113,37 @@ Result nvFenceWait(NvFence* f, s32 timeout_us)
Event* event = _nvGetEvent(event_id);
if (event) {
rc = nvioctlNvhostCtrl_EventWaitAsync(g_ctrl_fd, f->id, f->value, timeout_us, event_id);
if (rc == MAKERESULT(Module_LibnxNvidia, LibnxNvidiaError_Timeout)) {
u64 timeout_ns = U64_MAX;
if (timeout_us >= 0)
timeout_ns = (u64)1000*timeout_us;
rc = eventWait(event, timeout_ns);
if ((rc & 0x3FFFFF) == 0xEA01) { // timeout
nvioctlNvhostCtrl_EventSignal(g_ctrl_fd, 0x10000000 | event_id);
rc = MAKERESULT(Module_LibnxNvidia, LibnxNvidiaError_Timeout);
}
}
if (rc == MAKERESULT(Module_LibnxNvidia, LibnxNvidiaError_Timeout))
rc = _nvFenceEventWaitCommon(event, 0x10000000 | event_id, timeout_us);
}
_nvFreeEventSlot(event_id);
}
return rc;
}
static Result _nvFenceWait_100(NvFence* f, s32 timeout_us)
{
u32 event_id;
Result rc = nvioctlNvhostCtrl_EventWait(g_ctrl_fd, f->id, f->value, timeout_us, 0, &event_id);
if (rc == MAKERESULT(Module_LibnxNvidia, LibnxNvidiaError_Timeout) && timeout_us) {
Event event;
rc = nvQueryEvent(g_ctrl_fd, event_id, &event);
if (R_SUCCEEDED(rc)) {
rc = _nvFenceEventWaitCommon(&event, event_id, timeout_us);
eventClose(&event);
}
}
return rc;
}
Result nvFenceWait(NvFence* f, s32 timeout_us)
{
if (kernelAbove200())
return _nvFenceWait_200(f, timeout_us);
else
return _nvFenceWait_100(f, timeout_us);
}
Result nvMultiFenceWait(NvMultiFence* mf, s32 timeout_us)
{
// TODO: properly respect timeout

View File

@ -84,9 +84,7 @@ Result nvioctlNvhostCtrl_EventWait(u32 fd, u32 syncpt_id, u32 threshold, s32 tim
data.value = event_id;
rc = nvIoctl(fd, _NV_IOWR(0x00, 0x1D, data), &data);
if (R_SUCCEEDED(rc))
*out = data.value;
*out = data.value;
return rc;
}