diff --git a/nx/include/switch/nvidia/address_space.h b/nx/include/switch/nvidia/address_space.h index 49e6fcfc..49bfe2e2 100644 --- a/nx/include/switch/nvidia/address_space.h +++ b/nx/include/switch/nvidia/address_space.h @@ -1,6 +1,6 @@ #pragma once -typedef struct { +typedef struct NvAddressSpace { u32 fd; bool has_init; } NvAddressSpace; @@ -10,9 +10,6 @@ typedef enum { NvPageSize_64K = 0x10000 } NvPageSize; -typedef u64 iova_t; - - Result nvAddressSpaceCreate(NvAddressSpace* a); void nvAddressSpaceClose(NvAddressSpace* a); diff --git a/nx/include/switch/nvidia/buffer.h b/nx/include/switch/nvidia/buffer.h index 1386785c..29d17835 100644 --- a/nx/include/switch/nvidia/buffer.h +++ b/nx/include/switch/nvidia/buffer.h @@ -20,7 +20,7 @@ typedef enum { NvBufferKind_Z16_MS4_2Z=0x9, NvBufferKind_Z16_MS8_2Z=0xa, NvBufferKind_Z16_MS16_2Z=0xb, - NvBufferKind_Z16_4CZ=0xC, + NvBufferKind_Z16_4CZ=0xc, NvBufferKind_Z16_MS2_4CZ=0xd, NvBufferKind_Z16_MS4_4CZ=0xe, NvBufferKind_Z16_MS8_4CZ=0xf, @@ -62,7 +62,7 @@ typedef enum { NvBufferKind_V8Z24_MS8_VC24_2CS=0x35, NvBufferKind_V8Z24_MS4_VC12_2CZV=0x3a, NvBufferKind_V8Z24_MS4_VC4_2CZV=0x3b, - NvBufferKind_V8Z24_MS8_VC8_2CZV=0x3C, + NvBufferKind_V8Z24_MS8_VC8_2CZV=0x3c, NvBufferKind_V8Z24_MS8_VC24_2CZV=0x3d, NvBufferKind_V8Z24_MS4_VC12_2ZV=0x3e, NvBufferKind_V8Z24_MS4_VC4_2ZV=0x3f, @@ -78,7 +78,7 @@ typedef enum { NvBufferKind_Z24S8_MS4_1Z=0x49, NvBufferKind_Z24S8_MS8_1Z=0x4a, NvBufferKind_Z24S8_MS16_1Z=0x4b, - NvBufferKind_Z24S8_2CS=0x4C, + NvBufferKind_Z24S8_2CS=0x4c, NvBufferKind_Z24S8_MS2_2CS=0x4d, NvBufferKind_Z24S8_MS4_2CS=0x4e, NvBufferKind_Z24S8_MS8_2CS=0x4f, @@ -134,7 +134,7 @@ typedef enum { NvBufferKind_ZF32_MS8_2CZ=0x89, NvBufferKind_ZF32_MS16_2CZ=0x8a, NvBufferKind_X8Z24_X16V8S8_MS4_VC12=0x8b, - NvBufferKind_X8Z24_X16V8S8_MS4_VC4=0x8C, + NvBufferKind_X8Z24_X16V8S8_MS4_VC4=0x8c, NvBufferKind_X8Z24_X16V8S8_MS8_VC8=0x8d, NvBufferKind_X8Z24_X16V8S8_MS8_VC24=0x8e, NvBufferKind_X8Z24_X16V8S8_MS4_VC12_1CS=0x8f, @@ -146,7 +146,7 @@ typedef enum { NvBufferKind_X8Z24_X16V8S8_MS8_VC8_1ZV=0x99, NvBufferKind_X8Z24_X16V8S8_MS8_VC24_1ZV=0x9a, NvBufferKind_X8Z24_X16V8S8_MS4_VC12_1CZV=0x9b, - NvBufferKind_X8Z24_X16V8S8_MS4_VC4_1CZV=0x9C, + NvBufferKind_X8Z24_X16V8S8_MS4_VC4_1CZV=0x9c, NvBufferKind_X8Z24_X16V8S8_MS8_VC8_1CZV=0x9d, NvBufferKind_X8Z24_X16V8S8_MS8_VC24_1CZV=0x9e, NvBufferKind_X8Z24_X16V8S8_MS4_VC12_2CS=0x9f, @@ -162,7 +162,7 @@ typedef enum { NvBufferKind_ZF32_X16V8S8_MS8_VC8=0xa9, NvBufferKind_ZF32_X16V8S8_MS8_VC24=0xaa, NvBufferKind_ZF32_X16V8S8_MS4_VC12_1CS=0xab, - NvBufferKind_ZF32_X16V8S8_MS4_VC4_1CS=0xaC, + NvBufferKind_ZF32_X16V8S8_MS4_VC4_1CS=0xac, NvBufferKind_ZF32_X16V8S8_MS8_VC8_1CS=0xad, NvBufferKind_ZF32_X16V8S8_MS8_VC24_1CS=0xae, NvBufferKind_ZF32_X16V8S8_MS4_VC12_1ZV=0xb3, @@ -174,24 +174,24 @@ typedef enum { NvBufferKind_ZF32_X16V8S8_MS8_VC8_1CZV=0xb9, NvBufferKind_ZF32_X16V8S8_MS8_VC24_1CZV=0xba, NvBufferKind_ZF32_X16V8S8_MS4_VC12_2CS=0xbb, - NvBufferKind_ZF32_X16V8S8_MS4_VC4_2CS=0xbC, + NvBufferKind_ZF32_X16V8S8_MS4_VC4_2CS=0xbc, NvBufferKind_ZF32_X16V8S8_MS8_VC8_2CS=0xbd, NvBufferKind_ZF32_X16V8S8_MS8_VC24_2CS=0xbe, NvBufferKind_ZF32_X16V8S8_MS4_VC12_2CSZV=0xbf, - NvBufferKind_ZF32_X16V8S8_MS4_VC4_2CSZV=0xC0, - NvBufferKind_ZF32_X16V8S8_MS8_VC8_2CSZV=0xC1, - NvBufferKind_ZF32_X16V8S8_MS8_VC24_2CSZV=0xC2, - NvBufferKind_ZF32_X24S8=0xC3, - NvBufferKind_ZF32_X24S8_1CS=0xC4, - NvBufferKind_ZF32_X24S8_MS2_1CS=0xC5, - NvBufferKind_ZF32_X24S8_MS4_1CS=0xC6, - NvBufferKind_ZF32_X24S8_MS8_1CS=0xC7, - NvBufferKind_ZF32_X24S8_MS16_1CS=0xC8, - NvBufferKind_SmskedMessage=0xCa, - NvBufferKind_SmhostMessage=0xCb, - NvBufferKind_C64_MS2_2CRA=0xCd, - NvBufferKind_ZF32_X24S8_2CSZV=0xCe, - NvBufferKind_ZF32_X24S8_MS2_2CSZV=0xCf, + NvBufferKind_ZF32_X16V8S8_MS4_VC4_2CSZV=0xc0, + NvBufferKind_ZF32_X16V8S8_MS8_VC8_2CSZV=0xc1, + NvBufferKind_ZF32_X16V8S8_MS8_VC24_2CSZV=0xc2, + NvBufferKind_ZF32_X24S8=0xc3, + NvBufferKind_ZF32_X24S8_1CS=0xc4, + NvBufferKind_ZF32_X24S8_MS2_1CS=0xc5, + NvBufferKind_ZF32_X24S8_MS4_1CS=0xc6, + NvBufferKind_ZF32_X24S8_MS8_1CS=0xc7, + NvBufferKind_ZF32_X24S8_MS16_1CS=0xc8, + NvBufferKind_SmskedMessage=0xca, + NvBufferKind_SmhostMessage=0xcb, + NvBufferKind_C64_MS2_2CRA=0xcd, + NvBufferKind_ZF32_X24S8_2CSZV=0xce, + NvBufferKind_ZF32_X24S8_MS2_2CSZV=0xcf, NvBufferKind_ZF32_X24S8_MS4_2CSZV=0xd0, NvBufferKind_ZF32_X24S8_MS8_2CSZV=0xd1, NvBufferKind_ZF32_X24S8_MS16_2CSZV=0xd2, @@ -204,10 +204,10 @@ typedef enum { NvBufferKind_C32_2CBR=0xd9, NvBufferKind_C32_2CBA=0xda, NvBufferKind_C32_2CRA=0xdb, - NvBufferKind_C32_2BRA=0xdC, + NvBufferKind_C32_2BRA=0xdc, NvBufferKind_C32_MS2_2C=0xdd, NvBufferKind_C32_MS2_2CBR=0xde, - NvBufferKind_C32_MS2_2CRA=0xCC, + NvBufferKind_C32_MS2_2CRA=0xcc, NvBufferKind_C32_MS4_2C=0xdf, NvBufferKind_C32_MS4_2CBR=0xe0, NvBufferKind_C32_MS4_2CBA=0xe1, @@ -221,7 +221,7 @@ typedef enum { NvBufferKind_C64_2CRA=0xe9, NvBufferKind_C64_2BRA=0xea, NvBufferKind_C64_MS2_2C=0xeb, - NvBufferKind_C64_MS2_2CBR=0xeC, + NvBufferKind_C64_MS2_2CBR=0xec, NvBufferKind_C64_MS4_2C=0xed, NvBufferKind_C64_MS4_2CBR=0xee, NvBufferKind_C64_MS4_2CBA=0xef, @@ -237,28 +237,38 @@ typedef enum { NvBufferKind_C128_MS4_2CR=0xf9, NvBufferKind_C128_MS8_MS16_2C=0xfa, NvBufferKind_C128_MS8_MS16_2CR=0xfb, - NvBufferKind_X8C24=0xfC, + NvBufferKind_X8C24=0xfc, NvBufferKind_PitchNoSwizzle=0xfd, NvBufferKind_Generic_16BX2=0xfe, NvBufferKind_Invalid=0xff, } NvBufferKind; -typedef struct { - u32 fd; - u32 size; - void* ptr; +typedef struct NvAddressSpace NvAddressSpace; + +typedef struct NvBuffer { + u32 fd; + u32 size; + void* cpu_addr; + iova_t gpu_addr; + iova_t gpu_addr_texture; + NvAddressSpace* addr_space; NvBufferKind kind; - bool has_init; + bool has_init; } NvBuffer; Result nvBufferInit(void); u32 nvBufferGetNvmapFd(void); void nvBufferExit(void); -Result nvBufferCreate(NvBuffer* m, size_t size, u32 align, NvBufferKind kind); -Result nvBufferCreateRw(NvBuffer* m, size_t size, u32 align, NvBufferKind kind); +Result nvBufferCreate(NvBuffer* m, size_t size, u32 align, NvBufferKind kind, NvAddressSpace* as); +Result nvBufferCreateRw(NvBuffer* m, size_t size, u32 align, NvBufferKind kind, NvAddressSpace* as); void nvBufferFree(NvBuffer* m); -void* nvBufferGetAddr(NvBuffer* m); + +void* nvBufferGetCpuAddr(NvBuffer* m); +iova_t nvBufferGetGpuAddr(NvBuffer* m); + +Result nvBufferMapAsTexture(NvBuffer* m, NvBufferKind kind); +iova_t nvBufferGetGpuAddrTexture(NvBuffer* m); Result nvBufferMakeCpuUncached(NvBuffer* m); Result nvBufferMakeCpuCached(NvBuffer* m); diff --git a/nx/include/switch/nvidia/gpu/cmd_list.h b/nx/include/switch/nvidia/gpu/cmd_list.h index b2bbb252..0a7e054b 100644 --- a/nx/include/switch/nvidia/gpu/cmd_list.h +++ b/nx/include/switch/nvidia/gpu/cmd_list.h @@ -7,7 +7,6 @@ typedef struct { size_t num_cmds; size_t max_cmds; NvGpu* parent; - iova_t gpu_addr; } NvCmdList; Result nvCmdListCreate(NvCmdList* c, NvGpu* parent, size_t max_cmds); diff --git a/nx/include/switch/nvidia/ioctl.h b/nx/include/switch/nvidia/ioctl.h index 32a02e20..ee090781 100644 --- a/nx/include/switch/nvidia/ioctl.h +++ b/nx/include/switch/nvidia/ioctl.h @@ -100,7 +100,10 @@ typedef struct { } nvioctl_fence; typedef struct { - u64 desc; + union { + u64 desc; + u32 desc32[2]; + }; } nvioctl_gpfifo_entry; // Used with nvioctlChannel_AllocObjCtx(). @@ -130,7 +133,7 @@ typedef enum { // Used with nvioctlNvhostAsGpu_MapBufferEx(). typedef enum { - NvMapBufferFlags_FixedOffset = 0, + NvMapBufferFlags_FixedOffset = 1, NvMapBufferFlags_IsCachable = 4, } NvMapBufferFlags; @@ -183,3 +186,4 @@ 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); Result nvioctlChannel_SetUserData(u32 fd, void* addr); +typedef u64 iova_t; diff --git a/nx/source/nvidia/address_space.c b/nx/source/nvidia/address_space.c index cd5ddb13..f0724dd8 100644 --- a/nx/source/nvidia/address_space.c +++ b/nx/source/nvidia/address_space.c @@ -31,11 +31,14 @@ void nvAddressSpaceClose(NvAddressSpace* a) a->fd = -1; } -Result nvAddressSpaceReserveAlign(NvAddressSpace* a, NvPageSize align, u32 pages, NvPageSize page_sz, iova_t* iova_out) { +Result nvAddressSpaceReserveAlign( + NvAddressSpace* a, NvPageSize align, u32 pages, NvPageSize page_sz, + iova_t* iova_out) { return nvioctlNvhostAsGpu_AllocSpace(a->fd, pages, page_sz, 0, align, iova_out); } -Result nvAddressSpaceReserveAtFixedAddr(NvAddressSpace* a, iova_t addr, u32 pages, NvPageSize page_sz) { +Result nvAddressSpaceReserveAtFixedAddr( + NvAddressSpace* a, iova_t addr, u32 pages, NvPageSize page_sz) { return nvioctlNvhostAsGpu_AllocSpace(a->fd, pages, page_sz, 1, addr, NULL); } @@ -43,7 +46,9 @@ Result nvAddressSpaceReserveFull(NvAddressSpace* a) { return nvAddressSpaceReserveAlign(a, NvPageSize_64K, 0x10000, NvPageSize_64K, NULL); } -Result nvAddressSpaceMapBuffer(NvAddressSpace* a, NvBuffer* buffer, NvBufferKind kind, iova_t* iova_out) { +Result nvAddressSpaceMapBuffer( + NvAddressSpace* a, NvBuffer* buffer, NvBufferKind kind, + iova_t* iova_out) { return nvioctlNvhostAsGpu_MapBufferEx( a->fd, NvMapBufferFlags_IsCachable, kind, buffer->fd, 0x10000, 0, 0, 0, iova_out); } diff --git a/nx/source/nvidia/buffer.c b/nx/source/nvidia/buffer.c index 6d0e6434..8766ae02 100644 --- a/nx/source/nvidia/buffer.c +++ b/nx/source/nvidia/buffer.c @@ -6,6 +6,7 @@ #include "services/nv.h" #include "nvidia/ioctl.h" #include "nvidia/buffer.h" +#include "nvidia/address_space.h" static u32 g_nvmap_fd = -1; static u64 g_refCnt; @@ -40,7 +41,9 @@ u32 nvBufferGetNvmapFd(void) { return g_nvmap_fd; } -static Result _nvBufferCreate(NvBuffer* m, size_t size, u32 flags, u32 align, NvBufferKind kind) +static Result _nvBufferCreate( + NvBuffer* m, size_t size, u32 flags, u32 align, NvBufferKind kind, + NvAddressSpace* as) { Result rc; @@ -49,10 +52,13 @@ static Result _nvBufferCreate(NvBuffer* m, size_t size, u32 flags, u32 align, Nv m->has_init = true; m->size = size; m->fd = -1; - m->ptr = memalign(size, align); + m->cpu_addr = memalign(size, align); + m->gpu_addr = 0; + m->gpu_addr_texture = 0; + m->addr_space = as; m->kind = kind; - if (m->ptr == NULL) + if (m->cpu_addr == NULL) return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); rc = nvioctlNvmap_Create(g_nvmap_fd, size, &m->fd); @@ -62,7 +68,10 @@ static Result _nvBufferCreate(NvBuffer* m, size_t size, u32 flags, u32 align, Nv if (R_SUCCEEDED(rc)) rc = nvioctlNvmap_Alloc( - g_nvmap_fd, m->fd, 0, flags | NvBufferFlags_Nintendo, align, kind, m->ptr); + g_nvmap_fd, m->fd, 0, flags | NvBufferFlags_Nintendo, align, kind, m->cpu_addr); + + if (R_SUCCEEDED(rc)) + rc = nvAddressSpaceMapBuffer(as, m, 0, &m->gpu_addr); if (R_FAILED(rc)) nvBufferFree(m); @@ -70,20 +79,22 @@ static Result _nvBufferCreate(NvBuffer* m, size_t size, u32 flags, u32 align, Nv return rc; } -Result nvBufferCreate(NvBuffer* m, size_t size, u32 align, NvBufferKind kind) { - return _nvBufferCreate(m, size, 0, align, kind); +Result nvBufferCreate( + NvBuffer* m, size_t size, u32 align, NvBufferKind kind, NvAddressSpace* as) { + return _nvBufferCreate(m, size, 0, align, kind, as); } -Result nvBufferCreateRw(NvBuffer* m, size_t size, u32 align, NvBufferKind kind) { - return _nvBufferCreate(m, size, NvBufferFlags_Writable, align, kind); +Result nvBufferCreateRw( + NvBuffer* m, size_t size, u32 align, NvBufferKind kind, NvAddressSpace* as) { + return _nvBufferCreate(m, size, NvBufferFlags_Writable, align, kind, as); } Result nvBufferMakeCpuUncached(NvBuffer* m) { - return svcSetMemoryAttribute(m->ptr, m->size, 8, 8); + return svcSetMemoryAttribute(m->cpu_addr, m->size, 8, 8); } Result nvBufferMakeCpuCached(NvBuffer* m) { - return svcSetMemoryAttribute(m->ptr, m->size, 8, 0); + return svcSetMemoryAttribute(m->cpu_addr, m->size, 8, 0); } void nvBufferFree(NvBuffer* m) @@ -91,8 +102,12 @@ void nvBufferFree(NvBuffer* m) if (!m->has_init) return; - free(m->ptr); - m->ptr = NULL; + // todo: nvAddressSpaceUnmapBuffer(m->gpu_addr) + // todo: nvAddressSpaceUnmapBuffer(m->gpu_addr_texture) + nvBufferMakeCpuCached(m); + + free(m->cpu_addr); + m->cpu_addr = NULL; if (m->fd != -1) nvClose(m->fd); @@ -100,6 +115,18 @@ void nvBufferFree(NvBuffer* m) m->fd = -1; } -void* nvBufferGetAddr(NvBuffer* m) { - return m->ptr; +void* nvBufferGetCpuAddr(NvBuffer* m) { + return m->cpu_addr; +} + +iova_t nvBufferGetGpuAddr(NvBuffer* m) { + return m->gpu_addr; +} + +Result nvBufferMapAsTexture(NvBuffer* m, NvBufferKind kind) { + return nvAddressSpaceMapBuffer(m->addr_space, m, kind, &m->gpu_addr_texture); +} + +iova_t nvBufferGetGpuAddrTexture(NvBuffer* m) { + return m->gpu_addr_texture; } diff --git a/nx/source/nvidia/gpu/3d_ctx.c b/nx/source/nvidia/gpu/3d_ctx.c index c7bb5c45..cc728c21 100644 --- a/nx/source/nvidia/gpu/3d_ctx.c +++ b/nx/source/nvidia/gpu/3d_ctx.c @@ -3,7 +3,9 @@ Result nv3DContextCreate(Nv3DContext* t, NvGpu* parent) { t->parent = parent; - return nvioctlChannel_AllocObjCtx(parent->gpu_channel.fd, NvClassNumber_3D, 0, &t->obj_id); + + return nvioctlChannel_AllocObjCtx( + parent->gpu_channel.fd, NvClassNumber_3D, 0, &t->obj_id); } void nv3DContextClose(Nv3DContext* t) { diff --git a/nx/source/nvidia/gpu/cmd_list.c b/nx/source/nvidia/gpu/cmd_list.c index 33d84537..a4541357 100644 --- a/nx/source/nvidia/gpu/cmd_list.c +++ b/nx/source/nvidia/gpu/cmd_list.c @@ -4,14 +4,13 @@ Result nvCmdListCreate(NvCmdList* c, NvGpu* parent, size_t max_cmds) { Result rc; - rc = nvBufferCreate(&c->buffer, max_cmds * 4, 0x1000, NvBufferKind_Pitch); + rc = nvBufferCreate( + &c->buffer, max_cmds * 4, 0x1000, NvBufferKind_Pitch, + &parent->addr_space); if (R_SUCCEEDED(rc)) { nvBufferMakeCpuUncached(&c->buffer); - rc = nvAddressSpaceMapBuffer( - &parent->addr_space, &c->buffer, NvBufferKind_Pitch, &c->gpu_addr); - c->num_cmds = 0; c->max_cmds = max_cmds; c->parent = parent; @@ -20,15 +19,12 @@ Result nvCmdListCreate(NvCmdList* c, NvGpu* parent, size_t max_cmds) return rc; } -void nvCmdListClose(NvCmdList* c) -{ - // TODO: nvAddressSpaceUnmapBuffer? - nvBufferMakeCpuCached(&c->buffer); +void nvCmdListClose(NvCmdList* c) { nvBufferFree(&c->buffer); } iova_t nvCmdListGetGpuAddr(NvCmdList* c) { - return c->gpu_addr; + return nvBufferGetGpuAddr(&c->buffer); } u64 nvCmdListGetListSize(NvCmdList* c) { @@ -41,9 +37,8 @@ u32* nvCmdListInsert(NvCmdList* c, size_t num_cmds) if ((c->num_cmds + num_cmds) > c->max_cmds) return NULL; - u32* ptr = (u32*) nvBufferGetAddr(&c->buffer); - ptr += c->num_cmds; - c->num_cmds += num_cmds; - return ptr; + + u32* list = (u32*) nvBufferGetCpuAddr(&c->buffer); + return &list[c->num_cmds - num_cmds]; } diff --git a/nx/source/nvidia/gpu/error_notifier.c b/nx/source/nvidia/gpu/error_notifier.c index e3e87ce1..951aa2e2 100644 --- a/nx/source/nvidia/gpu/error_notifier.c +++ b/nx/source/nvidia/gpu/error_notifier.c @@ -5,7 +5,8 @@ Result nvErrorNotifierCreate(NvErrorNotifier* t, NvGpu* parent) Result rc; Handle handle; - rc = nvQueryEvent(parent->gpu_channel.fd, NvEventId_Gpu_ErrorNotifier, &handle); + rc = nvQueryEvent( + parent->gpu_channel.fd, NvEventId_Gpu_ErrorNotifier, &handle); if (R_SUCCEEDED(rc)) { eventLoadRemote(&t->event, handle); diff --git a/nx/source/nvidia/gpu/gpfifo.c b/nx/source/nvidia/gpu/gpfifo.c index d27cae47..7940c76b 100644 --- a/nx/source/nvidia/gpu/gpfifo.c +++ b/nx/source/nvidia/gpu/gpfifo.c @@ -20,10 +20,17 @@ Result nvGpfifoSubmit(NvGpfifo* f, NvCmdList* cmd_list, NvFence* fence_out) nvioctl_gpfifo_entry ent; nvioctl_fence fence; - ent.desc = nvCmdListGetGpuAddr(cmd_list) | (nvCmdListGetListSize(cmd_list) << 42); + u64 a = + nvCmdListGetGpuAddr(cmd_list) | (nvCmdListGetListSize(cmd_list) << 42); + + ent.desc32[0] = a; + ent.desc32[1] = a >> 32; + + fence.id = 0; + fence.value = 1; rc = nvioctlChannel_SubmitGpfifo( - f->parent->fd, &ent, 1, 0/*flags*/, &fence); + f->parent->fd, &ent, 1, /*0x104*/0x104/*flags*/, &fence); if (R_SUCCEEDED(rc)) { nvfenceCreate(fence_out, &fence); diff --git a/nx/source/nvidia/gpu/zcull_ctx.c b/nx/source/nvidia/gpu/zcull_ctx.c index 82fd3fb6..6b109325 100644 --- a/nx/source/nvidia/gpu/zcull_ctx.c +++ b/nx/source/nvidia/gpu/zcull_ctx.c @@ -5,19 +5,18 @@ Result nvZcullContextCreate(NvZcullContext* z, NvGpu* parent) Result rc; z->parent = parent; - rc = nvBufferCreateRw(&z->ctx_buf, nvInfoGetZcullCtxSize(), 0x20000, NvBufferKind_Pitch); - iova_t iova_out; + rc = nvBufferCreateRw( + &z->ctx_buf, nvInfoGetZcullCtxSize(), 0x20000, NvBufferKind_Pitch, + &parent->addr_space); if (R_SUCCEEDED(rc)) - rc = nvAddressSpaceMapBuffer(&parent->addr_space, &z->ctx_buf, NvBufferKind_Pitch, &iova_out); + rc = nvBufferMapAsTexture(&z->ctx_buf, NvBufferKind_Generic_16BX2); if (R_SUCCEEDED(rc)) - - rc = nvAddressSpaceMapBuffer(&parent->addr_space, &z->ctx_buf, NvBufferKind_Generic_16BX2, /*&iova_out*/ NULL); - - if (R_SUCCEEDED(rc)) - rc = nvioctlChannel_ZCullBind(parent->gpu_channel.fd, iova_out, NvZcullConfig_SeparateBuffer); + rc = nvioctlChannel_ZCullBind( + parent->gpu_channel.fd, nvBufferGetGpuAddr(&z->ctx_buf), + NvZcullConfig_SeparateBuffer); return rc; } diff --git a/nx/source/nvidia/ioctl/nvchannel.c b/nx/source/nvidia/ioctl/nvchannel.c index 554c08e0..cddaf893 100644 --- a/nx/source/nvidia/ioctl/nvchannel.c +++ b/nx/source/nvidia/ioctl/nvchannel.c @@ -15,7 +15,7 @@ Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd) { return nvIoctl(fd, _NV_IOW(0x48, 0x01, data), &data); } -Result nvioctlChannel_SubmitGpfifo(u32 fd, nvioctl_gpfifo_entry *entries, u32 num_entries, u32 flags, nvioctl_fence *fence_out) { +Result nvioctlChannel_SubmitGpfifo(u32 fd, nvioctl_gpfifo_entry *entries, u32 num_entries, u32 flags, nvioctl_fence *fence_inout) { Result rc=0; // Make sure stack data doesn't get very large. @@ -23,11 +23,11 @@ Result nvioctlChannel_SubmitGpfifo(u32 fd, nvioctl_gpfifo_entry *entries, u32 nu return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); struct { - __nv_in u64 gpfifo; // (ignored) pointer to gpfifo entry structs - __nv_in u32 num_entries; // number of entries being submitted - __nv_in u32 flags; - __nv_out nvioctl_fence fence_out; // returned new fence object for others to wait on - __nv_in nvioctl_gpfifo_entry entries[num_entries]; // depends on num_entries + __nv_in u64 gpfifo; // (ignored) pointer to gpfifo entry structs + __nv_in u32 num_entries; // number of entries being submitted + __nv_in u32 flags; + __nv_inout nvioctl_fence fence; // returned new fence object for others to wait on + __nv_in nvioctl_gpfifo_entry entries[num_entries]; // depends on num_entries } data; @@ -35,12 +35,13 @@ Result nvioctlChannel_SubmitGpfifo(u32 fd, nvioctl_gpfifo_entry *entries, u32 nu data.gpfifo = 1; data.num_entries = num_entries; data.flags = flags; + data.fence = *fence_inout; memcpy(data.entries, entries, sizeof(data.entries)); rc = nvIoctl(fd, _NV_IOWR(0x48, 0x08, data), &data); - if (R_SUCCEEDED(rc) && fence_out) { - memcpy(fence_out, &data.fence_out, sizeof(data.fence_out)); + if (R_SUCCEEDED(rc)) { + *fence_inout = data.fence; } return rc; diff --git a/nx/source/nvidia/ioctl/nvhost-ctrl.c b/nx/source/nvidia/ioctl/nvhost-ctrl.c index 77be6d36..5f8df261 100644 --- a/nx/source/nvidia/ioctl/nvhost-ctrl.c +++ b/nx/source/nvidia/ioctl/nvhost-ctrl.c @@ -4,6 +4,54 @@ #include "services/nv.h" #include "nvidia/ioctl.h" +Result nvioctlNvhostCtrl_SyncptRead(u32 fd, u32 id, u32* out) +{ + struct { + __nv_in u32 syncpt_id; + __nv_out u32 value; + } data; + + memset(&data, 0, sizeof(data)); + data.syncpt_id = id; + + rc = nvIoctl(fd, _NV_IOWR(0x00, 0x14, data), &data); + + if (R_SUCCEEDED(rc)) { + *out = value; + } + + return rc; +} + +Result nvioctlNvhostCtrl_SyncptIncr(u32 fd, u32 id) +{ + struct { + __nv_in u32 syncpt_id; + } data; + + memset(&data, 0, sizeof(data)); + data.syncpt_id = id; + + return nvIoctl(fd, _NV_IOWR(0x00, 0x15, data), &data); +} + +Result nvioctlNvhostCtrl_SyncptWait(u32 fd, u32 id, u32 threshold, u32 timeout) +{ + struct { + __nv_in u32 syncpt_id; + __nv_in u32 threshold; + __nv_in u32 timeout; + } data; + + // TODO: Which field is out? + memset(&data, 0, sizeof(data)); + data.syncpt_id = id; + data.threshold = threshold; + data.timeout = timeout; + + return nvIoctl(fd, _NV_IOWR(0x00, 0x16, data), &data); +} + Result nvioctlNvhostCtrl_EventSignal(u32 fd, u32 event_id) { struct { __nv_in u32 event_id;