diff --git a/nx/include/switch/gfx/nvioctl.h b/nx/include/switch/gfx/nvioctl.h index 8fa7e3da..375f976b 100644 --- a/nx/include/switch/gfx/nvioctl.h +++ b/nx/include/switch/gfx/nvioctl.h @@ -87,6 +87,7 @@ Result nvioctlNvmap_Alloc(u32 fd, u32 nvmap_handle, u32 heapmask, u32 flags, u32 Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd); Result nvioctlChannel_AllocObjCtx(u32 fd, u32 class_num, u32 flags); +Result nvioctlChannel_ZCullBind(u32 fd, u32 in[4]); Result nvioctlChannel_SetErrorNotifier(u32 fd, u64 offset, u64 size, u32 nvmap_handle); Result nvioctlChannel_SetPriority(u32 fd, u32 priority); Result nvioctlChannel_AllocGPFIFOEx2(u32 fd, u32 num_entries, u32 flags, u32 unk0, u32 unk1, u32 unk2, u32 unk3, nvioctl_fence *fence_out); diff --git a/nx/source/gfx/nvgfx.c b/nx/source/gfx/nvgfx.c index 32f26691..b868403f 100644 --- a/nx/source/gfx/nvgfx.c +++ b/nx/source/gfx/nvgfx.c @@ -26,7 +26,7 @@ static nvioctl_fence g_nvgfx_nvhost_fence; static u8 *g_nvgfx_nvhost_userdata; static size_t g_nvgfx_nvhost_userdata_size; -static nvmapobj nvmap_objs[3]; +static nvmapobj nvmap_objs[5]; Result nvmapobjInitialize(nvmapobj *obj, size_t size) { Result rc=0; @@ -76,6 +76,8 @@ Result nvgfxInitialize(void) { Result rc=0; if(g_nvgfxInitialized)return 0; + u32 zcullbind_data[4] = {0x58000, 0x5, 0x2, 0x0}; + g_nvgfx_fd_nvhostctrlgpu = 0; g_nvgfx_fd_nvhostasgpu = 0; g_nvgfx_fd_nvmap = 0; @@ -95,6 +97,8 @@ Result nvgfxInitialize(void) { if (R_SUCCEEDED(rc)) rc = nvmapobjInitialize(&nvmap_objs[0], 0x1000); if (R_SUCCEEDED(rc)) rc = nvmapobjInitialize(&nvmap_objs[1], 0x10000); if (R_SUCCEEDED(rc)) rc = nvmapobjInitialize(&nvmap_objs[2], 0x1000); + if (R_SUCCEEDED(rc)) rc = nvmapobjInitialize(&nvmap_objs[3], 0x10000); + if (R_SUCCEEDED(rc)) rc = nvmapobjInitialize(&nvmap_objs[4], 0x59000); if (R_SUCCEEDED(rc)) { //Unknown what size/etc is used officially. g_nvgfx_nvhost_userdata_size = 0x1000; @@ -155,6 +159,20 @@ Result nvgfxInitialize(void) { if (R_SUCCEEDED(rc)) rc = nvioctlChannel_SetPriority(g_nvgfx_fd_nvhostgpu, NVIOCTL_CHANNEL_PRIORITY_medium); + if (R_SUCCEEDED(rc)) rc = nvmapobjSetup(&nvmap_objs[3], 0, 0, 0x20000, 0); + + if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 0, 0, nvmap_objs[3].handle, 0x10000, 0, 0, 0, NULL); + if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 0, 0xfe, nvmap_objs[3].handle, 0x10000, 0, 0, 0, NULL); + + if (R_SUCCEEDED(rc)) rc = nvmapobjSetup(&nvmap_objs[4], 0, 0x1, 0x20000, 0); + + if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 4, 0, nvmap_objs[4].handle, 0x10000, 0, 0, 0, NULL); + if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 4, 0xfe, nvmap_objs[4].handle, 0x10000, 0, 0, 0, NULL); + + if (R_SUCCEEDED(rc)) rc = nvioctlChannel_ZCullBind(g_nvgfx_fd_nvhostgpu, zcullbind_data); + + //Officially, ipcQueryPointerBufferSize and NVGPU_IOCTL_CHANNEL_SUBMIT_GPFIFO are used here with the duplicate session setup during nv serv init. + //if (R_SUCCEEDED(rc)) rc = -1; if (R_FAILED(rc)) { diff --git a/nx/source/gfx/nvioctl.c b/nx/source/gfx/nvioctl.c index f2e1bb94..6deab847 100644 --- a/nx/source/gfx/nvioctl.c +++ b/nx/source/gfx/nvioctl.c @@ -266,6 +266,17 @@ Result nvioctlChannel_AllocObjCtx(u32 fd, u32 class_num, u32 flags) { return nvIoctl(fd, _IOWR(0x48, 0x09, data), &data); } +Result nvioctlChannel_ZCullBind(u32 fd, u32 in[4]) { + struct { + u32 in[4]; + } data; + + memset(&data, 0, sizeof(data)); + memcpy(data.in, in, sizeof(data.in)); + + return nvIoctl(fd, _IOWR(0x48, 0x0B, data), &data); +} + Result nvioctlChannel_SetErrorNotifier(u32 fd, u64 offset, u64 size, u32 nvmap_handle) { struct { u64 offset;//in