diff --git a/nx/include/switch/services/nv.h b/nx/include/switch/services/nv.h index 32dcb2bb..c0c1c906 100644 --- a/nx/include/switch/services/nv.h +++ b/nx/include/switch/services/nv.h @@ -7,7 +7,7 @@ #pragma once #include "../types.h" -Result nvInitialize(size_t sharedmem_size); +Result nvInitialize(void); void nvExit(void); Result nvOpen(u32 *fd, const char *devicepath); diff --git a/nx/source/display/gfx.c b/nx/source/display/gfx.c index 494ce9ce..0199701c 100644 --- a/nx/source/display/gfx.c +++ b/nx/source/display/gfx.c @@ -165,7 +165,7 @@ static Result _gfxQueueBuffer(s32 buf) { return rc; } -static Result _gfxInit(ViServiceType servicetype, const char *DisplayName, u32 LayerFlags, u64 LayerId, size_t nv_transfermem_size) { +static Result _gfxInit(ViServiceType servicetype, const char *DisplayName, u32 LayerFlags, u64 LayerId) { Result rc=0; u32 i=0; @@ -239,7 +239,7 @@ static Result _gfxInit(ViServiceType servicetype, const char *DisplayName, u32 L rc = binderInitSession(&g_gfxBinderSession, 0x0f); } - if (R_SUCCEEDED(rc)) rc = nvInitialize(nv_transfermem_size); + if (R_SUCCEEDED(rc)) rc = nvInitialize(); if (R_SUCCEEDED(rc)) rc = bqInitialize(&g_gfxBinderSession); @@ -325,7 +325,7 @@ static Result _gfxInit(ViServiceType servicetype, const char *DisplayName, u32 L } Result gfxInitDefault(void) { - return _gfxInit(ViServiceType_Default, "Default", ViLayerFlags_Default, 0, 0x300000); + return _gfxInit(ViServiceType_Default, "Default", ViLayerFlags_Default, 0); } void gfxExit(void) diff --git a/nx/source/services/nv.c b/nx/source/services/nv.c index 53861963..d5fa7c72 100644 --- a/nx/source/services/nv.c +++ b/nx/source/services/nv.c @@ -1,22 +1,29 @@ #include #include "types.h" #include "result.h" +#include "arm/atomics.h" #include "kernel/ipc.h" +#include "kernel/tmem.h" #include "services/applet.h" #include "nvidia/ioctl.h" #include "services/nv.h" #include "services/sm.h" -#include "kernel/tmem.h" + +__attribute__((weak)) u32 __nx_nv_transfermem_size = 0x300000; static Service g_nvSrv; +static u64 g_refCnt; + static size_t g_nvIpcBufferSize = 0; static TransferMemory g_nvTransfermem; static Result _nvInitialize(Handle proc, Handle sharedmem, u32 transfermem_size); static Result _nvSetClientPID(u64 AppletResourceUserId); -Result nvInitialize(size_t transfermem_size) +Result nvInitialize(void) { + atomicIncrement64(&g_refCnt); + if (serviceIsActive(&g_nvSrv)) return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); @@ -46,10 +53,10 @@ Result nvInitialize(size_t transfermem_size) rc = ipcQueryPointerBufferSize(g_nvSrv.handle, &g_nvIpcBufferSize); if (R_SUCCEEDED(rc)) - rc = tmemCreate(&g_nvTransfermem, transfermem_size, Perm_None); + rc = tmemCreate(&g_nvTransfermem, __nx_nv_transfermem_size, Perm_None); if (R_SUCCEEDED(rc)) - rc = _nvInitialize(CUR_PROCESS_HANDLE, g_nvTransfermem.handle, transfermem_size); + rc = _nvInitialize(CUR_PROCESS_HANDLE, g_nvTransfermem.handle, __nx_nv_transfermem_size); // Officially ipc control DuplicateSessionEx would be used here. @@ -62,7 +69,6 @@ Result nvInitialize(size_t transfermem_size) } if (R_FAILED(rc)) { - appletExit(); nvExit(); } @@ -71,9 +77,11 @@ Result nvInitialize(size_t transfermem_size) void nvExit(void) { - appletExit(); - serviceClose(&g_nvSrv); - tmemClose(&g_nvTransfermem); + if (atomicDecrement64(&g_refCnt) == 0) { + appletExit(); + serviceClose(&g_nvSrv); + tmemClose(&g_nvTransfermem); + } } static Result _nvInitialize(Handle proc, Handle sharedmem, u32 transfermem_size) {