diff --git a/nx/include/switch/gfx/gfx.h b/nx/include/switch/gfx/gfx.h index 7c431aab..a715edea 100644 --- a/nx/include/switch/gfx/gfx.h +++ b/nx/include/switch/gfx/gfx.h @@ -1,5 +1,8 @@ /// Do not use viInitialize/viExit when using these. void gfxInitDefault(void); void gfxExit(void); + void gfxWaitForVsync(); void gfxSwapBuffers(); +u8* gfxGetFramebuffer(u16* width, u16* height); +void gfxFlushBuffers(void); diff --git a/nx/include/switch/gfx/nvgfx.h b/nx/include/switch/gfx/nvgfx.h index aa0a0873..4b17b123 100644 --- a/nx/include/switch/gfx/nvgfx.h +++ b/nx/include/switch/gfx/nvgfx.h @@ -1,3 +1,4 @@ Result nvgfxInitialize(void); void nvgfxExit(void); Result nvgfxEventInit(void); +Result nvgfxGetFramebuffer(u8 **buffer, size_t *size); diff --git a/nx/source/gfx/gfx.c b/nx/source/gfx/gfx.c index bcf877eb..2b98383d 100644 --- a/nx/source/gfx/gfx.c +++ b/nx/source/gfx/gfx.c @@ -10,6 +10,9 @@ static u64 g_gfxNativeWindow_Size; static s32 g_gfxNativeWindow_ID; static binderSession g_gfxBinderSession; static s32 g_gfxCurrentBuffer = 0; +static u8 *g_gfxFramebuf; +static size_t g_gfxFramebufSize; +static size_t g_gfxFramebufSingleSize = 0x3c0000; extern u32 __nx_applet_type; @@ -69,6 +72,8 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L g_gfxNativeWindow_ID = 0; g_gfxDisplayVsyncEvent = INVALID_HANDLE; g_gfxCurrentBuffer = 0; + g_gfxFramebuf = NULL; + g_gfxFramebufSize = 0; rc = viInitialize(servicetype); if (R_FAILED(rc)) return rc; @@ -115,6 +120,10 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer(); + if (R_SUCCEEDED(rc)) rc = nvgfxGetFramebuffer(&g_gfxFramebuf, &g_gfxFramebufSize); + + if (R_SUCCEEDED(rc)) gfxFlushBuffers(); + if (R_FAILED(rc)) { nvgfxExit(); gfxproducerExit(); @@ -123,6 +132,16 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L viCloseLayer(&g_gfxLayer); viCloseDisplay(&g_gfxDisplay); viExit(); + + if(g_gfxDisplayVsyncEvent != INVALID_HANDLE) { + svcCloseHandle(g_gfxDisplayVsyncEvent); + g_gfxDisplayVsyncEvent = INVALID_HANDLE; + } + + g_gfxNativeWindow_ID = 0; + g_gfxCurrentBuffer = 0; + g_gfxFramebuf = NULL; + g_gfxFramebufSize = 0; } if (R_SUCCEEDED(rc)) g_gfxInitialized = 1; @@ -176,6 +195,10 @@ void gfxExit(void) { g_gfxInitialized = 0; g_gfxNativeWindow_ID = 0; + + g_gfxCurrentBuffer = 0; + g_gfxFramebuf = NULL; + g_gfxFramebufSize = 0; } void gfxWaitForVsync() { @@ -195,3 +218,14 @@ void gfxSwapBuffers() { if (R_FAILED(rc)) fatalSimple(rc); } +u8* gfxGetFramebuffer(u16* width, u16* height) { + if(width) *width = 1280; + if(height) *height = 720; + + return &g_gfxFramebuf[g_gfxCurrentBuffer*g_gfxFramebufSingleSize]; +} + +void gfxFlushBuffers(void) { + armDCacheFlush(&g_gfxFramebuf[g_gfxCurrentBuffer*g_gfxFramebufSingleSize], g_gfxFramebufSingleSize); +} + diff --git a/nx/source/gfx/nvgfx.c b/nx/source/gfx/nvgfx.c index c3cddbb1..c431837f 100644 --- a/nx/source/gfx/nvgfx.c +++ b/nx/source/gfx/nvgfx.c @@ -169,8 +169,6 @@ Result nvgfxInitialize(void) { if (R_SUCCEEDED(rc)) rc = nvmapobjInitialize(&nvmap_objs[15], 0x6000); if (R_SUCCEEDED(rc)) rc = nvmapobjInitialize(&nvmap_objs[16], 0x1000); - if (R_SUCCEEDED(rc)) memset(nvmap_objs[6].mem, 0x77, nvmap_objs[6].mem_size); - if (R_SUCCEEDED(rc)) { //Unknown what size/etc is used officially. g_nvgfx_nvhost_userdata_size = 0x1000; g_nvgfx_nvhost_userdata = memalign(0x1000, g_nvgfx_nvhost_userdata_size); @@ -454,3 +452,12 @@ Result nvgfxEventInit(void) { return rc; } +Result nvgfxGetFramebuffer(u8 **buffer, size_t *size) { + if(!g_nvgfxInitialized)return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED); + + if(buffer) *buffer = nvmap_objs[6].mem; + if(size) *size = nvmap_objs[6].mem_size; + + return 0; +} +