diff --git a/nx/include/switch/gfx/nvgfx.h b/nx/include/switch/gfx/nvgfx.h index 8f1101b0..075f3425 100644 --- a/nx/include/switch/gfx/nvgfx.h +++ b/nx/include/switch/gfx/nvgfx.h @@ -1,4 +1,4 @@ Result nvgfxInitialize(void); void nvgfxExit(void); -Result nvgfxEventWait(u32 syncpt_id, u32 threshold); +Result nvgfxEventWait(u32 syncpt_id, u32 threshold, s32 timeout); Result nvgfxGetFramebuffer(u8 **buffer, size_t *size); diff --git a/nx/include/switch/gfx/nvioctl.h b/nx/include/switch/gfx/nvioctl.h index 6996839f..a109f9d6 100644 --- a/nx/include/switch/gfx/nvioctl.h +++ b/nx/include/switch/gfx/nvioctl.h @@ -78,7 +78,7 @@ enum nvioctl_channel_priority { }; Result nvioctlNvhostCtrl_EventSignal(u32 fd, u32 event_id); -Result nvioctlNvhostCtrl_EventWait(u32 fd, u32 unk0, u32 unk1, s32 timeout, u32 event_id, u32 *out); +Result nvioctlNvhostCtrl_EventWait(u32 fd, u32 syncpt_id, u32 threshold, s32 timeout, u32 event_id, u32 *out); Result nvioctlNvhostCtrl_EventRegister(u32 fd, u32 event_id); Result nvioctlNvhostCtrlGpu_ZCullGetCtxSize(u32 fd, u32 *out); diff --git a/nx/source/gfx/gfx.c b/nx/source/gfx/gfx.c index 8840be2d..08a691a3 100644 --- a/nx/source/gfx/gfx.c +++ b/nx/source/gfx/gfx.c @@ -66,17 +66,22 @@ static Result _gfxGetNativeWindowID(u8 *buf, u64 size, s32 *out_ID) { return 0; } -static Result _gfxDequeueBuffer(bufferProducerFence *fence) { +static Result _gfxDequeueBuffer(bool handle_fence) { Result rc=0; + bufferProducerFence *fence = &g_gfx_DequeueBuffer_fence; + nvioctl_fence original_fence; + bool async=0; if (!g_gfxDoubleBuf) { g_gfxCurrentProducerBuffer = -1; return 0; } - rc = bufferProducerDequeueBuffer(/*1*/0, 1280, 720, 0, 0x300, &g_gfxCurrentProducerBuffer, fence); + if (handle_fence) memcpy(&original_fence, &fence->nv_fences[0], sizeof(nvioctl_fence)); - //if (R_SUCCEEDED(rc) && fence && fence->is_valid) rc = nvgfxEventWait(fence->nv_fences[0].id, fence->nv_fences[0].value); + rc = bufferProducerDequeueBuffer(async, 1280, 720, 0, 0x300, &g_gfxCurrentProducerBuffer, fence); + + if (R_SUCCEEDED(rc) && async && handle_fence && fence->is_valid) rc = nvgfxEventWait(original_fence.id, original_fence.value, -1); if (R_SUCCEEDED(rc)) g_gfxCurrentBuffer = (g_gfxCurrentBuffer + 1) & (g_nvgfx_totalframebufs-1); @@ -151,7 +156,7 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L if (R_SUCCEEDED(rc)) { for(i=0; i<2; i++) { - rc = _gfxDequeueBuffer(NULL); + rc = _gfxDequeueBuffer(0); if (R_FAILED(rc)) break; rc = bufferProducerRequestBuffer(g_gfxCurrentProducerBuffer); @@ -171,7 +176,7 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L if (R_SUCCEEDED(rc)) svcSleepThread(3000000000); - if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer(&g_gfx_DequeueBuffer_fence); + if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer(0); /*if (R_SUCCEEDED(rc)) rc = _gfxGetDisplayResolution(&g_gfx_DisplayResolution_width, &g_gfx_DisplayResolution_height); @@ -301,7 +306,7 @@ void gfxSwapBuffers() { rc = _gfxQueueBuffer(g_gfxCurrentProducerBuffer); - if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer(&g_gfx_DequeueBuffer_fence); + if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer(1); #ifdef BUFFERSWAP_DELAY_HACK gfxWaitForVsync(); diff --git a/nx/source/gfx/ioctl/nvhost-ctrl.c b/nx/source/gfx/ioctl/nvhost-ctrl.c index a909a102..3cacc2a1 100644 --- a/nx/source/gfx/ioctl/nvhost-ctrl.c +++ b/nx/source/gfx/ioctl/nvhost-ctrl.c @@ -12,30 +12,27 @@ Result nvioctlNvhostCtrl_EventSignal(u32 fd, u32 event_id) { return nvIoctl(fd, _IOWR(0x00, 0x1C, data), &data); } -Result nvioctlNvhostCtrl_EventWait(u32 fd, u32 unk0, u32 unk1, s32 timeout, u32 event_id, u32 *out) +Result nvioctlNvhostCtrl_EventWait(u32 fd, u32 syncpt_id, u32 threshold, s32 timeout, u32 event_id, u32 *out) { Result rc = 0; struct { - __in u32 unk0; - __in u32 unk1; + __in u32 syncpt_id; + __in u32 threshold; __in s32 timeout; - union { - __in u32 event; - __out u32 result; - }; + __inout u32 value; } data; memset(&data, 0, sizeof(data)); - data.unk0 = unk0; - data.unk1 = unk1; + data.syncpt_id = syncpt_id; + data.threshold = threshold; data.timeout = timeout; - data.event = event_id; + data.value = event_id; rc = nvIoctl(fd, _IOWR(0x00, 0x1D, data), &data); if (R_SUCCEEDED(rc)) - *out = data.result; + *out = data.value; return rc; } diff --git a/nx/source/gfx/nvgfx.c b/nx/source/gfx/nvgfx.c index 558d7aff..5e53a3ed 100644 --- a/nx/source/gfx/nvgfx.c +++ b/nx/source/gfx/nvgfx.c @@ -442,18 +442,23 @@ void nvgfxExit(void) { g_nvgfxInitialized = 0; } -Result nvgfxEventWait(u32 syncpt_id, u32 threshold) { +Result nvgfxEventWait(u32 syncpt_id, u32 threshold, s32 timeout) { Result rc=0; if (R_SUCCEEDED(rc)) { do { - rc = nvioctlNvhostCtrl_EventWait(g_nvgfx_fd_nvhostctrl, /*0x42, 0x1ca7*/syncpt_id, threshold, 0x64, 0, &g_nvgfx_nvhostctrl_eventres); + rc = nvioctlNvhostCtrl_EventWait(g_nvgfx_fd_nvhostctrl, /*0x42, 0x1ca7*/syncpt_id, threshold, /*0x64*/timeout, 0, &g_nvgfx_nvhostctrl_eventres); } while(rc==5);//timeout error } //Currently broken. //if (R_SUCCEEDED(rc)) rc = nvQueryEvent(g_nvgfx_fd_nvhostctrl, g_nvgfx_nvhostctrl_eventres, &g_nvgfx_nvhostctrl_eventhandle); + /*if (R_SUCCEEDED(rc)) { + svcCloseHandle(g_nvgfx_nvhostctrl_eventhandle); + g_nvgfx_nvhostctrl_eventhandle = INVALID_HANDLE; + }*/ + //if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrl_EventSignal(g_nvgfx_fd_nvhostctrl, g_nvgfx_nvhostctrl_eventres); return rc;