More updates to nvidia

This commit is contained in:
plutooo 2018-03-17 23:00:25 +01:00 committed by fincs
parent 1c88d99131
commit a3a2e57fc2
13 changed files with 185 additions and 90 deletions

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
typedef struct { typedef struct NvAddressSpace {
u32 fd; u32 fd;
bool has_init; bool has_init;
} NvAddressSpace; } NvAddressSpace;
@ -10,9 +10,6 @@ typedef enum {
NvPageSize_64K = 0x10000 NvPageSize_64K = 0x10000
} NvPageSize; } NvPageSize;
typedef u64 iova_t;
Result nvAddressSpaceCreate(NvAddressSpace* a); Result nvAddressSpaceCreate(NvAddressSpace* a);
void nvAddressSpaceClose(NvAddressSpace* a); void nvAddressSpaceClose(NvAddressSpace* a);

View File

@ -20,7 +20,7 @@ typedef enum {
NvBufferKind_Z16_MS4_2Z=0x9, NvBufferKind_Z16_MS4_2Z=0x9,
NvBufferKind_Z16_MS8_2Z=0xa, NvBufferKind_Z16_MS8_2Z=0xa,
NvBufferKind_Z16_MS16_2Z=0xb, NvBufferKind_Z16_MS16_2Z=0xb,
NvBufferKind_Z16_4CZ=0xC, NvBufferKind_Z16_4CZ=0xc,
NvBufferKind_Z16_MS2_4CZ=0xd, NvBufferKind_Z16_MS2_4CZ=0xd,
NvBufferKind_Z16_MS4_4CZ=0xe, NvBufferKind_Z16_MS4_4CZ=0xe,
NvBufferKind_Z16_MS8_4CZ=0xf, NvBufferKind_Z16_MS8_4CZ=0xf,
@ -62,7 +62,7 @@ typedef enum {
NvBufferKind_V8Z24_MS8_VC24_2CS=0x35, NvBufferKind_V8Z24_MS8_VC24_2CS=0x35,
NvBufferKind_V8Z24_MS4_VC12_2CZV=0x3a, NvBufferKind_V8Z24_MS4_VC12_2CZV=0x3a,
NvBufferKind_V8Z24_MS4_VC4_2CZV=0x3b, 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_MS8_VC24_2CZV=0x3d,
NvBufferKind_V8Z24_MS4_VC12_2ZV=0x3e, NvBufferKind_V8Z24_MS4_VC12_2ZV=0x3e,
NvBufferKind_V8Z24_MS4_VC4_2ZV=0x3f, NvBufferKind_V8Z24_MS4_VC4_2ZV=0x3f,
@ -78,7 +78,7 @@ typedef enum {
NvBufferKind_Z24S8_MS4_1Z=0x49, NvBufferKind_Z24S8_MS4_1Z=0x49,
NvBufferKind_Z24S8_MS8_1Z=0x4a, NvBufferKind_Z24S8_MS8_1Z=0x4a,
NvBufferKind_Z24S8_MS16_1Z=0x4b, NvBufferKind_Z24S8_MS16_1Z=0x4b,
NvBufferKind_Z24S8_2CS=0x4C, NvBufferKind_Z24S8_2CS=0x4c,
NvBufferKind_Z24S8_MS2_2CS=0x4d, NvBufferKind_Z24S8_MS2_2CS=0x4d,
NvBufferKind_Z24S8_MS4_2CS=0x4e, NvBufferKind_Z24S8_MS4_2CS=0x4e,
NvBufferKind_Z24S8_MS8_2CS=0x4f, NvBufferKind_Z24S8_MS8_2CS=0x4f,
@ -134,7 +134,7 @@ typedef enum {
NvBufferKind_ZF32_MS8_2CZ=0x89, NvBufferKind_ZF32_MS8_2CZ=0x89,
NvBufferKind_ZF32_MS16_2CZ=0x8a, NvBufferKind_ZF32_MS16_2CZ=0x8a,
NvBufferKind_X8Z24_X16V8S8_MS4_VC12=0x8b, 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_VC8=0x8d,
NvBufferKind_X8Z24_X16V8S8_MS8_VC24=0x8e, NvBufferKind_X8Z24_X16V8S8_MS8_VC24=0x8e,
NvBufferKind_X8Z24_X16V8S8_MS4_VC12_1CS=0x8f, NvBufferKind_X8Z24_X16V8S8_MS4_VC12_1CS=0x8f,
@ -146,7 +146,7 @@ typedef enum {
NvBufferKind_X8Z24_X16V8S8_MS8_VC8_1ZV=0x99, NvBufferKind_X8Z24_X16V8S8_MS8_VC8_1ZV=0x99,
NvBufferKind_X8Z24_X16V8S8_MS8_VC24_1ZV=0x9a, NvBufferKind_X8Z24_X16V8S8_MS8_VC24_1ZV=0x9a,
NvBufferKind_X8Z24_X16V8S8_MS4_VC12_1CZV=0x9b, 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_VC8_1CZV=0x9d,
NvBufferKind_X8Z24_X16V8S8_MS8_VC24_1CZV=0x9e, NvBufferKind_X8Z24_X16V8S8_MS8_VC24_1CZV=0x9e,
NvBufferKind_X8Z24_X16V8S8_MS4_VC12_2CS=0x9f, NvBufferKind_X8Z24_X16V8S8_MS4_VC12_2CS=0x9f,
@ -162,7 +162,7 @@ typedef enum {
NvBufferKind_ZF32_X16V8S8_MS8_VC8=0xa9, NvBufferKind_ZF32_X16V8S8_MS8_VC8=0xa9,
NvBufferKind_ZF32_X16V8S8_MS8_VC24=0xaa, NvBufferKind_ZF32_X16V8S8_MS8_VC24=0xaa,
NvBufferKind_ZF32_X16V8S8_MS4_VC12_1CS=0xab, 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_VC8_1CS=0xad,
NvBufferKind_ZF32_X16V8S8_MS8_VC24_1CS=0xae, NvBufferKind_ZF32_X16V8S8_MS8_VC24_1CS=0xae,
NvBufferKind_ZF32_X16V8S8_MS4_VC12_1ZV=0xb3, NvBufferKind_ZF32_X16V8S8_MS4_VC12_1ZV=0xb3,
@ -174,24 +174,24 @@ typedef enum {
NvBufferKind_ZF32_X16V8S8_MS8_VC8_1CZV=0xb9, NvBufferKind_ZF32_X16V8S8_MS8_VC8_1CZV=0xb9,
NvBufferKind_ZF32_X16V8S8_MS8_VC24_1CZV=0xba, NvBufferKind_ZF32_X16V8S8_MS8_VC24_1CZV=0xba,
NvBufferKind_ZF32_X16V8S8_MS4_VC12_2CS=0xbb, 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_VC8_2CS=0xbd,
NvBufferKind_ZF32_X16V8S8_MS8_VC24_2CS=0xbe, NvBufferKind_ZF32_X16V8S8_MS8_VC24_2CS=0xbe,
NvBufferKind_ZF32_X16V8S8_MS4_VC12_2CSZV=0xbf, NvBufferKind_ZF32_X16V8S8_MS4_VC12_2CSZV=0xbf,
NvBufferKind_ZF32_X16V8S8_MS4_VC4_2CSZV=0xC0, NvBufferKind_ZF32_X16V8S8_MS4_VC4_2CSZV=0xc0,
NvBufferKind_ZF32_X16V8S8_MS8_VC8_2CSZV=0xC1, NvBufferKind_ZF32_X16V8S8_MS8_VC8_2CSZV=0xc1,
NvBufferKind_ZF32_X16V8S8_MS8_VC24_2CSZV=0xC2, NvBufferKind_ZF32_X16V8S8_MS8_VC24_2CSZV=0xc2,
NvBufferKind_ZF32_X24S8=0xC3, NvBufferKind_ZF32_X24S8=0xc3,
NvBufferKind_ZF32_X24S8_1CS=0xC4, NvBufferKind_ZF32_X24S8_1CS=0xc4,
NvBufferKind_ZF32_X24S8_MS2_1CS=0xC5, NvBufferKind_ZF32_X24S8_MS2_1CS=0xc5,
NvBufferKind_ZF32_X24S8_MS4_1CS=0xC6, NvBufferKind_ZF32_X24S8_MS4_1CS=0xc6,
NvBufferKind_ZF32_X24S8_MS8_1CS=0xC7, NvBufferKind_ZF32_X24S8_MS8_1CS=0xc7,
NvBufferKind_ZF32_X24S8_MS16_1CS=0xC8, NvBufferKind_ZF32_X24S8_MS16_1CS=0xc8,
NvBufferKind_SmskedMessage=0xCa, NvBufferKind_SmskedMessage=0xca,
NvBufferKind_SmhostMessage=0xCb, NvBufferKind_SmhostMessage=0xcb,
NvBufferKind_C64_MS2_2CRA=0xCd, NvBufferKind_C64_MS2_2CRA=0xcd,
NvBufferKind_ZF32_X24S8_2CSZV=0xCe, NvBufferKind_ZF32_X24S8_2CSZV=0xce,
NvBufferKind_ZF32_X24S8_MS2_2CSZV=0xCf, NvBufferKind_ZF32_X24S8_MS2_2CSZV=0xcf,
NvBufferKind_ZF32_X24S8_MS4_2CSZV=0xd0, NvBufferKind_ZF32_X24S8_MS4_2CSZV=0xd0,
NvBufferKind_ZF32_X24S8_MS8_2CSZV=0xd1, NvBufferKind_ZF32_X24S8_MS8_2CSZV=0xd1,
NvBufferKind_ZF32_X24S8_MS16_2CSZV=0xd2, NvBufferKind_ZF32_X24S8_MS16_2CSZV=0xd2,
@ -204,10 +204,10 @@ typedef enum {
NvBufferKind_C32_2CBR=0xd9, NvBufferKind_C32_2CBR=0xd9,
NvBufferKind_C32_2CBA=0xda, NvBufferKind_C32_2CBA=0xda,
NvBufferKind_C32_2CRA=0xdb, NvBufferKind_C32_2CRA=0xdb,
NvBufferKind_C32_2BRA=0xdC, NvBufferKind_C32_2BRA=0xdc,
NvBufferKind_C32_MS2_2C=0xdd, NvBufferKind_C32_MS2_2C=0xdd,
NvBufferKind_C32_MS2_2CBR=0xde, NvBufferKind_C32_MS2_2CBR=0xde,
NvBufferKind_C32_MS2_2CRA=0xCC, NvBufferKind_C32_MS2_2CRA=0xcc,
NvBufferKind_C32_MS4_2C=0xdf, NvBufferKind_C32_MS4_2C=0xdf,
NvBufferKind_C32_MS4_2CBR=0xe0, NvBufferKind_C32_MS4_2CBR=0xe0,
NvBufferKind_C32_MS4_2CBA=0xe1, NvBufferKind_C32_MS4_2CBA=0xe1,
@ -221,7 +221,7 @@ typedef enum {
NvBufferKind_C64_2CRA=0xe9, NvBufferKind_C64_2CRA=0xe9,
NvBufferKind_C64_2BRA=0xea, NvBufferKind_C64_2BRA=0xea,
NvBufferKind_C64_MS2_2C=0xeb, NvBufferKind_C64_MS2_2C=0xeb,
NvBufferKind_C64_MS2_2CBR=0xeC, NvBufferKind_C64_MS2_2CBR=0xec,
NvBufferKind_C64_MS4_2C=0xed, NvBufferKind_C64_MS4_2C=0xed,
NvBufferKind_C64_MS4_2CBR=0xee, NvBufferKind_C64_MS4_2CBR=0xee,
NvBufferKind_C64_MS4_2CBA=0xef, NvBufferKind_C64_MS4_2CBA=0xef,
@ -237,28 +237,38 @@ typedef enum {
NvBufferKind_C128_MS4_2CR=0xf9, NvBufferKind_C128_MS4_2CR=0xf9,
NvBufferKind_C128_MS8_MS16_2C=0xfa, NvBufferKind_C128_MS8_MS16_2C=0xfa,
NvBufferKind_C128_MS8_MS16_2CR=0xfb, NvBufferKind_C128_MS8_MS16_2CR=0xfb,
NvBufferKind_X8C24=0xfC, NvBufferKind_X8C24=0xfc,
NvBufferKind_PitchNoSwizzle=0xfd, NvBufferKind_PitchNoSwizzle=0xfd,
NvBufferKind_Generic_16BX2=0xfe, NvBufferKind_Generic_16BX2=0xfe,
NvBufferKind_Invalid=0xff, NvBufferKind_Invalid=0xff,
} NvBufferKind; } NvBufferKind;
typedef struct { typedef struct NvAddressSpace NvAddressSpace;
u32 fd;
u32 size; typedef struct NvBuffer {
void* ptr; u32 fd;
u32 size;
void* cpu_addr;
iova_t gpu_addr;
iova_t gpu_addr_texture;
NvAddressSpace* addr_space;
NvBufferKind kind; NvBufferKind kind;
bool has_init; bool has_init;
} NvBuffer; } NvBuffer;
Result nvBufferInit(void); Result nvBufferInit(void);
u32 nvBufferGetNvmapFd(void); u32 nvBufferGetNvmapFd(void);
void nvBufferExit(void); void nvBufferExit(void);
Result nvBufferCreate(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); Result nvBufferCreateRw(NvBuffer* m, size_t size, u32 align, NvBufferKind kind, NvAddressSpace* as);
void nvBufferFree(NvBuffer* m); 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 nvBufferMakeCpuUncached(NvBuffer* m);
Result nvBufferMakeCpuCached(NvBuffer* m); Result nvBufferMakeCpuCached(NvBuffer* m);

View File

@ -7,7 +7,6 @@ typedef struct {
size_t num_cmds; size_t num_cmds;
size_t max_cmds; size_t max_cmds;
NvGpu* parent; NvGpu* parent;
iova_t gpu_addr;
} NvCmdList; } NvCmdList;
Result nvCmdListCreate(NvCmdList* c, NvGpu* parent, size_t max_cmds); Result nvCmdListCreate(NvCmdList* c, NvGpu* parent, size_t max_cmds);

View File

@ -100,7 +100,10 @@ typedef struct {
} nvioctl_fence; } nvioctl_fence;
typedef struct { typedef struct {
u64 desc; union {
u64 desc;
u32 desc32[2];
};
} nvioctl_gpfifo_entry; } nvioctl_gpfifo_entry;
// Used with nvioctlChannel_AllocObjCtx(). // Used with nvioctlChannel_AllocObjCtx().
@ -130,7 +133,7 @@ typedef enum {
// Used with nvioctlNvhostAsGpu_MapBufferEx(). // Used with nvioctlNvhostAsGpu_MapBufferEx().
typedef enum { typedef enum {
NvMapBufferFlags_FixedOffset = 0, NvMapBufferFlags_FixedOffset = 1,
NvMapBufferFlags_IsCachable = 4, NvMapBufferFlags_IsCachable = 4,
} NvMapBufferFlags; } 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_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); Result nvioctlChannel_SetUserData(u32 fd, void* addr);
typedef u64 iova_t;

View File

@ -31,11 +31,14 @@ void nvAddressSpaceClose(NvAddressSpace* a)
a->fd = -1; 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); 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); 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); 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( return nvioctlNvhostAsGpu_MapBufferEx(
a->fd, NvMapBufferFlags_IsCachable, kind, buffer->fd, 0x10000, 0, 0, 0, iova_out); a->fd, NvMapBufferFlags_IsCachable, kind, buffer->fd, 0x10000, 0, 0, 0, iova_out);
} }

View File

@ -6,6 +6,7 @@
#include "services/nv.h" #include "services/nv.h"
#include "nvidia/ioctl.h" #include "nvidia/ioctl.h"
#include "nvidia/buffer.h" #include "nvidia/buffer.h"
#include "nvidia/address_space.h"
static u32 g_nvmap_fd = -1; static u32 g_nvmap_fd = -1;
static u64 g_refCnt; static u64 g_refCnt;
@ -40,7 +41,9 @@ u32 nvBufferGetNvmapFd(void) {
return g_nvmap_fd; 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; Result rc;
@ -49,10 +52,13 @@ static Result _nvBufferCreate(NvBuffer* m, size_t size, u32 flags, u32 align, Nv
m->has_init = true; m->has_init = true;
m->size = size; m->size = size;
m->fd = -1; 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; m->kind = kind;
if (m->ptr == NULL) if (m->cpu_addr == NULL)
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
rc = nvioctlNvmap_Create(g_nvmap_fd, size, &m->fd); 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)) if (R_SUCCEEDED(rc))
rc = nvioctlNvmap_Alloc( 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)) if (R_FAILED(rc))
nvBufferFree(m); nvBufferFree(m);
@ -70,20 +79,22 @@ static Result _nvBufferCreate(NvBuffer* m, size_t size, u32 flags, u32 align, Nv
return rc; return rc;
} }
Result nvBufferCreate(NvBuffer* m, size_t size, u32 align, NvBufferKind kind) { Result nvBufferCreate(
return _nvBufferCreate(m, size, 0, align, kind); 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) { Result nvBufferCreateRw(
return _nvBufferCreate(m, size, NvBufferFlags_Writable, align, kind); NvBuffer* m, size_t size, u32 align, NvBufferKind kind, NvAddressSpace* as) {
return _nvBufferCreate(m, size, NvBufferFlags_Writable, align, kind, as);
} }
Result nvBufferMakeCpuUncached(NvBuffer* m) { 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) { 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) void nvBufferFree(NvBuffer* m)
@ -91,8 +102,12 @@ void nvBufferFree(NvBuffer* m)
if (!m->has_init) if (!m->has_init)
return; return;
free(m->ptr); // todo: nvAddressSpaceUnmapBuffer(m->gpu_addr)
m->ptr = NULL; // todo: nvAddressSpaceUnmapBuffer(m->gpu_addr_texture)
nvBufferMakeCpuCached(m);
free(m->cpu_addr);
m->cpu_addr = NULL;
if (m->fd != -1) if (m->fd != -1)
nvClose(m->fd); nvClose(m->fd);
@ -100,6 +115,18 @@ void nvBufferFree(NvBuffer* m)
m->fd = -1; m->fd = -1;
} }
void* nvBufferGetAddr(NvBuffer* m) { void* nvBufferGetCpuAddr(NvBuffer* m) {
return m->ptr; 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;
} }

View File

@ -3,7 +3,9 @@
Result nv3DContextCreate(Nv3DContext* t, NvGpu* parent) Result nv3DContextCreate(Nv3DContext* t, NvGpu* parent)
{ {
t->parent = 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) { void nv3DContextClose(Nv3DContext* t) {

View File

@ -4,14 +4,13 @@ Result nvCmdListCreate(NvCmdList* c, NvGpu* parent, size_t max_cmds)
{ {
Result rc; 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)) { if (R_SUCCEEDED(rc)) {
nvBufferMakeCpuUncached(&c->buffer); nvBufferMakeCpuUncached(&c->buffer);
rc = nvAddressSpaceMapBuffer(
&parent->addr_space, &c->buffer, NvBufferKind_Pitch, &c->gpu_addr);
c->num_cmds = 0; c->num_cmds = 0;
c->max_cmds = max_cmds; c->max_cmds = max_cmds;
c->parent = parent; c->parent = parent;
@ -20,15 +19,12 @@ Result nvCmdListCreate(NvCmdList* c, NvGpu* parent, size_t max_cmds)
return rc; return rc;
} }
void nvCmdListClose(NvCmdList* c) void nvCmdListClose(NvCmdList* c) {
{
// TODO: nvAddressSpaceUnmapBuffer?
nvBufferMakeCpuCached(&c->buffer);
nvBufferFree(&c->buffer); nvBufferFree(&c->buffer);
} }
iova_t nvCmdListGetGpuAddr(NvCmdList* c) { iova_t nvCmdListGetGpuAddr(NvCmdList* c) {
return c->gpu_addr; return nvBufferGetGpuAddr(&c->buffer);
} }
u64 nvCmdListGetListSize(NvCmdList* c) { 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) if ((c->num_cmds + num_cmds) > c->max_cmds)
return NULL; return NULL;
u32* ptr = (u32*) nvBufferGetAddr(&c->buffer);
ptr += c->num_cmds;
c->num_cmds += num_cmds; c->num_cmds += num_cmds;
return ptr;
u32* list = (u32*) nvBufferGetCpuAddr(&c->buffer);
return &list[c->num_cmds - num_cmds];
} }

View File

@ -5,7 +5,8 @@ Result nvErrorNotifierCreate(NvErrorNotifier* t, NvGpu* parent)
Result rc; Result rc;
Handle handle; 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)) { if (R_SUCCEEDED(rc)) {
eventLoadRemote(&t->event, handle); eventLoadRemote(&t->event, handle);

View File

@ -20,10 +20,17 @@ Result nvGpfifoSubmit(NvGpfifo* f, NvCmdList* cmd_list, NvFence* fence_out)
nvioctl_gpfifo_entry ent; nvioctl_gpfifo_entry ent;
nvioctl_fence fence; 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( rc = nvioctlChannel_SubmitGpfifo(
f->parent->fd, &ent, 1, 0/*flags*/, &fence); f->parent->fd, &ent, 1, /*0x104*/0x104/*flags*/, &fence);
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
nvfenceCreate(fence_out, &fence); nvfenceCreate(fence_out, &fence);

View File

@ -5,19 +5,18 @@ Result nvZcullContextCreate(NvZcullContext* z, NvGpu* parent)
Result rc; Result rc;
z->parent = parent; 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)) 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)) if (R_SUCCEEDED(rc))
rc = nvioctlChannel_ZCullBind(
rc = nvAddressSpaceMapBuffer(&parent->addr_space, &z->ctx_buf, NvBufferKind_Generic_16BX2, /*&iova_out*/ NULL); parent->gpu_channel.fd, nvBufferGetGpuAddr(&z->ctx_buf),
NvZcullConfig_SeparateBuffer);
if (R_SUCCEEDED(rc))
rc = nvioctlChannel_ZCullBind(parent->gpu_channel.fd, iova_out, NvZcullConfig_SeparateBuffer);
return rc; return rc;
} }

View File

@ -15,7 +15,7 @@ Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd) {
return nvIoctl(fd, _NV_IOW(0x48, 0x01, data), &data); 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; Result rc=0;
// Make sure stack data doesn't get very large. // 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); return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
struct { struct {
__nv_in u64 gpfifo; // (ignored) pointer to gpfifo entry structs __nv_in u64 gpfifo; // (ignored) pointer to gpfifo entry structs
__nv_in u32 num_entries; // number of entries being submitted __nv_in u32 num_entries; // number of entries being submitted
__nv_in u32 flags; __nv_in u32 flags;
__nv_out nvioctl_fence fence_out; // returned new fence object for others to wait on __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 __nv_in nvioctl_gpfifo_entry entries[num_entries]; // depends on num_entries
} data; } data;
@ -35,12 +35,13 @@ Result nvioctlChannel_SubmitGpfifo(u32 fd, nvioctl_gpfifo_entry *entries, u32 nu
data.gpfifo = 1; data.gpfifo = 1;
data.num_entries = num_entries; data.num_entries = num_entries;
data.flags = flags; data.flags = flags;
data.fence = *fence_inout;
memcpy(data.entries, entries, sizeof(data.entries)); memcpy(data.entries, entries, sizeof(data.entries));
rc = nvIoctl(fd, _NV_IOWR(0x48, 0x08, data), &data); rc = nvIoctl(fd, _NV_IOWR(0x48, 0x08, data), &data);
if (R_SUCCEEDED(rc) && fence_out) { if (R_SUCCEEDED(rc)) {
memcpy(fence_out, &data.fence_out, sizeof(data.fence_out)); *fence_inout = data.fence;
} }
return rc; return rc;

View File

@ -4,6 +4,54 @@
#include "services/nv.h" #include "services/nv.h"
#include "nvidia/ioctl.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) { Result nvioctlNvhostCtrl_EventSignal(u32 fd, u32 event_id) {
struct { struct {
__nv_in u32 event_id; __nv_in u32 event_id;