mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
Implemented the ioctls which were skipped during nvgfx init. nvgfx init adjustments. Fixed ioctl direction define for nvioctlNvhostAsGpu_MapBufferEx, this now works properly.
This commit is contained in:
parent
704ead0d5f
commit
0cc65093e3
@ -36,10 +36,21 @@ typedef struct {
|
||||
u64 gr_compbit_store_base_hw; // 0x0 (not supported)
|
||||
} gpu_characteristics;
|
||||
|
||||
typedef struct {
|
||||
u64 offset;
|
||||
u32 page_size;
|
||||
u32 pad;
|
||||
u64 pages;
|
||||
} nvioctl_va_region;
|
||||
|
||||
Result nvioctlNvhostCtrlGpu_ZCullGetCtxSize(u32 fd, u32 *out);
|
||||
Result nvioctlNvhostCtrlGpu_ZCullGetInfo(u32 fd, u32 out[40>>2]);
|
||||
Result nvioctlNvhostCtrlGpu_GetCharacteristics(u32 fd, gpu_characteristics *out);
|
||||
Result nvioctlNvhostCtrlGpu_GetTpcMasks(u32 fd, u32 inval, u32 out[24>>2]);
|
||||
|
||||
Result nvioctlNvhostAsGpu_AllocSpace(u32 fd, u32 pages, u32 page_size, u32 flags, u64 align, u64 *offset);
|
||||
Result nvioctlNvhostAsGpu_MapBufferEx(u32 fd, u32 flags, u32 kind, u32 nvmap_handle, u32 page_size, u64 buffer_offset, u64 mapping_size, u64 *offset);
|
||||
Result nvioctlNvhostAsGpu_GetVARegions(u32 fd, nvioctl_va_region regions[2]);
|
||||
Result nvioctlNvhostAsGpu_InitializeEx(u32 fd, u32 big_page_size);
|
||||
|
||||
Result nvioctlNvmap_Create(u32 fd, u32 size, u32 *nvmap_handle);
|
||||
|
@ -6,10 +6,14 @@ static bool g_nvgfxInitialized = 0;
|
||||
static u32 g_nvgfx_fd_nvhostctrlgpu;
|
||||
static u32 g_nvgfx_fd_nvhostasgpu;
|
||||
static u32 g_nvgfx_fd_nvmap;
|
||||
static u32 g_nvgfx_nvmapobj;
|
||||
static u32 g_nvgfx_nvmapobj0;
|
||||
|
||||
static gpu_characteristics g_nvgfx_gpu_characteristics;
|
||||
static u64 g_nvgfx_nvhostasgpu_allocspace_offset;
|
||||
static u32 g_nvgfx_tpcmasks[24>>2];
|
||||
static u32 g_nvgfx_zcullctxsize;
|
||||
static u32 g_nvgfx_zcullinfo[40>>2];
|
||||
static nvioctl_va_region g_nvgfx_nvhostasgpu_varegions[2];
|
||||
|
||||
static u8 *g_nvgfx_nvmap_mem;
|
||||
size_t g_nvgfx_nvmap_mem_size;
|
||||
@ -21,16 +25,21 @@ Result nvgfxInitialize(void) {
|
||||
g_nvgfx_fd_nvhostctrlgpu = 0;
|
||||
g_nvgfx_fd_nvhostasgpu = 0;
|
||||
g_nvgfx_fd_nvmap = 0;
|
||||
g_nvgfx_nvmapobj = 0;
|
||||
g_nvgfx_nvmapobj0 = 0;
|
||||
|
||||
memset(&g_nvgfx_gpu_characteristics, 0, sizeof(gpu_characteristics));
|
||||
memset(g_nvgfx_tpcmasks, 0, sizeof(g_nvgfx_tpcmasks));
|
||||
memset(g_nvgfx_zcullinfo, 0, sizeof(g_nvgfx_zcullinfo));
|
||||
memset(g_nvgfx_nvhostasgpu_varegions, 0, sizeof(g_nvgfx_nvhostasgpu_varegions));
|
||||
g_nvgfx_nvhostasgpu_allocspace_offset = 0;
|
||||
g_nvgfx_zcullctxsize = 0;
|
||||
|
||||
g_nvgfx_nvmap_mem_size = 0x10000;
|
||||
g_nvgfx_nvmap_mem_size = 0x1000;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
g_nvgfx_nvmap_mem = memalign(0x1000, g_nvgfx_nvmap_mem_size);
|
||||
if (g_nvgfx_nvmap_mem==NULL) rc = MAKERESULT(MODULE_LIBNX, LIBNX_OUTOFMEM);
|
||||
if (R_SUCCEEDED(rc)) memset(g_nvgfx_nvmap_mem, 0, g_nvgfx_nvmap_mem_size);
|
||||
}
|
||||
|
||||
//Officially NVHOST_IOCTL_CTRL_GET_CONFIG is used a lot (here and later), skip that.
|
||||
@ -38,36 +47,38 @@ Result nvgfxInitialize(void) {
|
||||
if (R_SUCCEEDED(rc)) rc = nvOpen(&g_nvgfx_fd_nvhostctrlgpu, "/dev/nvhost-ctrl-gpu");
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_GetCharacteristics(g_nvgfx_fd_nvhostctrlgpu, &g_nvgfx_gpu_characteristics);
|
||||
|
||||
//Officially NVGPU_GPU_IOCTL_GET_TPC_MASKS is used here.
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_GetTpcMasks(g_nvgfx_fd_nvhostctrlgpu, 4, g_nvgfx_tpcmasks);
|
||||
|
||||
//Officially NVGPU_GPU_IOCTL_ZCULL_GET_CTX_SIZE and NVGPU_GPU_IOCTL_ZCULL_GET_INFO are used here.
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_ZCullGetCtxSize(g_nvgfx_fd_nvhostctrlgpu, &g_nvgfx_zcullctxsize);
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_ZCullGetInfo(g_nvgfx_fd_nvhostctrlgpu, g_nvgfx_zcullinfo);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvOpen(&g_nvgfx_fd_nvhostasgpu, "/dev/nvhost-as-gpu");
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_InitializeEx(g_nvgfx_fd_nvhostasgpu, 1);
|
||||
|
||||
//NVGPU_AS_IOCTL_GET_VA_REGIONS twice
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_AllocSpace(g_nvgfx_fd_nvhostasgpu, 0x10000, 0x1000, 0, 0x1000, &g_nvgfx_nvhostasgpu_allocspace_offset);
|
||||
//Officially this is used twice here - only use it once here.
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_GetVARegions(g_nvgfx_fd_nvhostasgpu, g_nvgfx_nvhostasgpu_varegions);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_AllocSpace(g_nvgfx_fd_nvhostasgpu, 0x10000, 0x20000, 0, 0x10000, &g_nvgfx_nvhostasgpu_allocspace_offset);
|
||||
if (R_SUCCEEDED(rc)) rc = nvOpen(&g_nvgfx_fd_nvmap, "/dev/nvmap");
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvmap_Create(g_nvgfx_fd_nvmap, g_nvgfx_nvmap_mem_size, &g_nvgfx_nvmapobj);
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvmap_Create(g_nvgfx_fd_nvmap, g_nvgfx_nvmap_mem_size, &g_nvgfx_nvmapobj0);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvmap_Alloc(g_nvgfx_fd_nvmap, g_nvgfx_nvmapobj, 0, 0, 0x20000, 0, g_nvgfx_nvmap_mem);
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvmap_Alloc(g_nvgfx_fd_nvmap, g_nvgfx_nvmapobj0, 0, 0, 0x20000, 0, g_nvgfx_nvmap_mem);
|
||||
|
||||
//Currently broken.
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 4, 0, g_nvgfx_nvmapobj, 0x1000, 0, g_nvgfx_nvmap_mem_size, NULL);
|
||||
if (R_SUCCEEDED(rc)) rc = -1;
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 4, 0xfe, g_nvgfx_nvmapobj, 0x1000, 0, g_nvgfx_nvmap_mem_size, NULL);
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 0, 0, g_nvgfx_nvmapobj0, 0x10000, 0, 0, NULL);
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 0, 0xfe, g_nvgfx_nvmapobj0, 0x10000, 0, 0, NULL);
|
||||
//if (R_SUCCEEDED(rc)) rc = -1;
|
||||
|
||||
if (R_FAILED(rc)) nvClose(g_nvgfx_fd_nvmap);
|
||||
if (R_FAILED(rc)) nvClose(g_nvgfx_fd_nvhostasgpu);
|
||||
if (R_FAILED(rc)) nvClose(g_nvgfx_fd_nvhostctrlgpu);
|
||||
if (R_FAILED(rc)) {
|
||||
nvClose(g_nvgfx_fd_nvmap);
|
||||
nvClose(g_nvgfx_fd_nvhostasgpu);
|
||||
nvClose(g_nvgfx_fd_nvhostctrlgpu);
|
||||
|
||||
if (g_nvgfx_nvmap_mem) {
|
||||
free(g_nvgfx_nvmap_mem);
|
||||
g_nvgfx_nvmap_mem = NULL;
|
||||
if (g_nvgfx_nvmap_mem) {
|
||||
free(g_nvgfx_nvmap_mem);
|
||||
g_nvgfx_nvmap_mem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc)) g_nvgfxInitialized = 1;
|
||||
|
@ -1,6 +1,40 @@
|
||||
#include <string.h>
|
||||
#include <switch.h>
|
||||
|
||||
Result nvioctlNvhostCtrlGpu_ZCullGetCtxSize(u32 fd, u32 *out) {
|
||||
Result rc = 0;
|
||||
|
||||
struct {
|
||||
u32 out;
|
||||
} data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
rc = nvIoctl(fd, _IOR(0x47, 0x01, data), &data);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
*out = data.out;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nvioctlNvhostCtrlGpu_ZCullGetInfo(u32 fd, u32 out[40>>2]) {
|
||||
Result rc = 0;
|
||||
|
||||
struct {
|
||||
u32 out[40>>2];
|
||||
} data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
rc = nvIoctl(fd, _IOR(0x47, 0x02, data), &data);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
memcpy(out, data.out, sizeof(data.out));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nvioctlNvhostCtrlGpu_GetCharacteristics(u32 fd, gpu_characteristics *out) {
|
||||
Result rc = 0;
|
||||
|
||||
@ -22,6 +56,25 @@ Result nvioctlNvhostCtrlGpu_GetCharacteristics(u32 fd, gpu_characteristics *out)
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nvioctlNvhostCtrlGpu_GetTpcMasks(u32 fd, u32 inval, u32 out[24>>2]) {
|
||||
Result rc = 0;
|
||||
|
||||
struct {
|
||||
u32 unk[24>>2];
|
||||
} data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.unk[0] = inval;
|
||||
data.unk[2] = 1;//addr?
|
||||
|
||||
rc = nvIoctl(fd, _IOWR(0x47, 0x06, data), &data);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
memcpy(out, &data.unk, sizeof(data.unk));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nvioctlNvhostAsGpu_AllocSpace(u32 fd, u32 pages, u32 page_size, u32 flags, u64 align, u64 *offset) {
|
||||
Result rc=0;
|
||||
|
||||
@ -71,7 +124,7 @@ Result nvioctlNvhostAsGpu_MapBufferEx(u32 fd, u32 flags, u32 kind, u32 nvmap_han
|
||||
data.buffer_offset = buffer_offset;
|
||||
data.mapping_size = mapping_size;
|
||||
|
||||
rc = nvIoctl(fd, _IOW(0x41, 0x06, data), &data);
|
||||
rc = nvIoctl(fd, _IOWR(0x41, 0x06, data), &data);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
if (offset) *offset = data.offset;
|
||||
@ -79,6 +132,27 @@ Result nvioctlNvhostAsGpu_MapBufferEx(u32 fd, u32 flags, u32 kind, u32 nvmap_han
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nvioctlNvhostAsGpu_GetVARegions(u32 fd, nvioctl_va_region regions[2]) {
|
||||
Result rc=0;
|
||||
|
||||
struct {
|
||||
u64 not_used; // (contained output user ptr on linux, ignored)
|
||||
u32 bufsize; //inout forced to 2*sizeof(struct va_region)
|
||||
u32 pad;
|
||||
nvioctl_va_region regions[2];//out
|
||||
} data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.bufsize = sizeof(data.regions);
|
||||
|
||||
rc = nvIoctl(fd, _IOWR(0x41, 0x08, data), &data);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
memcpy(regions, data.regions, sizeof(data.regions));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nvioctlNvhostAsGpu_InitializeEx(u32 fd, u32 big_page_size) {
|
||||
struct {
|
||||
u32 big_page_size; // depends on GPU's available_big_page_sizes; 0=default
|
||||
|
Loading…
Reference in New Issue
Block a user