Added nvioctlChannel_SubmitGPFIFO().

This commit is contained in:
yellows8 2017-11-14 20:20:08 -05:00
parent eeb43bae97
commit 1908b29708
3 changed files with 42 additions and 1 deletions

View File

@ -53,6 +53,11 @@ typedef struct {
u32 value; u32 value;
} nvioctl_fence; } nvioctl_fence;
typedef struct {
u32 entry0;
u32 entry1;
} nvioctl_gpfifo_entry;
//Used with nvioctlChannel_AllocObjCtx(). //Used with nvioctlChannel_AllocObjCtx().
enum nvioctl_channel_obj_classnum { enum nvioctl_channel_obj_classnum {
NVIOCTL_CHANNEL_OBJ_CLASSNUM_2d = 0x902D, NVIOCTL_CHANNEL_OBJ_CLASSNUM_2d = 0x902D,
@ -86,6 +91,7 @@ Result nvioctlNvmap_Create(u32 fd, u32 size, u32 *nvmap_handle);
Result nvioctlNvmap_Alloc(u32 fd, u32 nvmap_handle, u32 heapmask, u32 flags, u32 align, u8 kind, void* addr); Result nvioctlNvmap_Alloc(u32 fd, u32 nvmap_handle, u32 heapmask, u32 flags, u32 align, u8 kind, void* addr);
Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd); Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd);
Result nvioctlChannel_SubmitGPFIFO(u32 fd, nvioctl_gpfifo_entry *entries, u32 num_entries, u32 flags, nvioctl_fence *fence_out);
Result nvioctlChannel_AllocObjCtx(u32 fd, u32 class_num, u32 flags); Result nvioctlChannel_AllocObjCtx(u32 fd, u32 class_num, u32 flags);
Result nvioctlChannel_ZCullBind(u32 fd, u32 in[4]); Result nvioctlChannel_ZCullBind(u32 fd, u32 in[4]);
Result nvioctlChannel_SetErrorNotifier(u32 fd, u64 offset, u64 size, u32 nvmap_handle); Result nvioctlChannel_SetErrorNotifier(u32 fd, u64 offset, u64 size, u32 nvmap_handle);

View File

@ -23,6 +23,7 @@ static u32 g_nvgfx_zcullinfo[40>>2];
static nvioctl_va_region g_nvgfx_nvhostasgpu_varegions[2]; static nvioctl_va_region g_nvgfx_nvhostasgpu_varegions[2];
static nvioctl_l2_state g_nvgfx_l2state; static nvioctl_l2_state g_nvgfx_l2state;
static nvioctl_fence g_nvgfx_nvhost_fence; static nvioctl_fence g_nvgfx_nvhost_fence;
static nvioctl_fence g_nvgfx_nvhostgpu_gpfifo_fence;
static u8 *g_nvgfx_nvhost_userdata; static u8 *g_nvgfx_nvhost_userdata;
static size_t g_nvgfx_nvhost_userdata_size; static size_t g_nvgfx_nvhost_userdata_size;
@ -78,6 +79,8 @@ Result nvgfxInitialize(void) {
u32 zcullbind_data[4] = {0x58000, 0x5, 0x2, 0x0}; u32 zcullbind_data[4] = {0x58000, 0x5, 0x2, 0x0};
nvioctl_gpfifo_entry gpfifo_entries[2] = {{0x00030000, 0x00177a05}, {0x00031778, 0x80002e05}};
g_nvgfx_fd_nvhostctrlgpu = 0; g_nvgfx_fd_nvhostctrlgpu = 0;
g_nvgfx_fd_nvhostasgpu = 0; g_nvgfx_fd_nvhostasgpu = 0;
g_nvgfx_fd_nvmap = 0; g_nvgfx_fd_nvmap = 0;
@ -91,6 +94,7 @@ Result nvgfxInitialize(void) {
memset(g_nvgfx_nvhostasgpu_varegions, 0, sizeof(g_nvgfx_nvhostasgpu_varegions)); memset(g_nvgfx_nvhostasgpu_varegions, 0, sizeof(g_nvgfx_nvhostasgpu_varegions));
memset(&g_nvgfx_l2state, 0, sizeof(nvioctl_l2_state)); memset(&g_nvgfx_l2state, 0, sizeof(nvioctl_l2_state));
memset(&g_nvgfx_nvhost_fence, 0, sizeof(g_nvgfx_nvhost_fence)); memset(&g_nvgfx_nvhost_fence, 0, sizeof(g_nvgfx_nvhost_fence));
memset(&g_nvgfx_nvhostgpu_gpfifo_fence, 0, sizeof(g_nvgfx_nvhostgpu_gpfifo_fence));
g_nvgfx_nvhostasgpu_allocspace_offset = 0; g_nvgfx_nvhostasgpu_allocspace_offset = 0;
g_nvgfx_zcullctxsize = 0; g_nvgfx_zcullctxsize = 0;
@ -171,7 +175,10 @@ Result nvgfxInitialize(void) {
if (R_SUCCEEDED(rc)) rc = nvioctlChannel_ZCullBind(g_nvgfx_fd_nvhostgpu, zcullbind_data); 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. //Officially, ipcQueryPointerBufferSize and NVGPU_IOCTL_CHANNEL_SUBMIT_GPFIFO(nvioctlChannel_SubmitGPFIFO) are used here with the duplicate service session setup during nv serv init.
//TODO: This is probably used for GPU rendering? Is this really needed when not doing actual GPU rendering?
//Skip this since this causes a white-screen hang.
//if (R_SUCCEEDED(rc)) rc = nvioctlChannel_SubmitGPFIFO(g_nvgfx_fd_nvhostgpu, gpfifo_entries, 2, 0x104, &g_nvgfx_nvhostgpu_gpfifo_fence);
//if (R_SUCCEEDED(rc)) rc = -1; //if (R_SUCCEEDED(rc)) rc = -1;

View File

@ -251,6 +251,34 @@ Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd) {
return nvIoctl(fd, _IOW(0x48, 0x01, data), &data); return nvIoctl(fd, _IOW(0x48, 0x01, data), &data);
} }
Result nvioctlChannel_SubmitGPFIFO(u32 fd, nvioctl_gpfifo_entry *entries, u32 num_entries, u32 flags, nvioctl_fence *fence_out) {
Result rc=0;
if(num_entries > 0x200) return MAKERESULT(MODULE_LIBNX, LIBNX_OUTOFMEM);//Make sure stack data doesn't get very large.
struct {
u64 gpfifo; // in (ignored) pointer to gpfifo fence structs
u32 num_entries; // in number of fence objects being submitted
u32 flags; // in
nvioctl_fence fence_out; // out returned new fence object for others to wait on
nvioctl_gpfifo_entry entries[num_entries]; // in depends on num_entries
} data;
memset(&data, 0, sizeof(data));
data.gpfifo = 1;
data.num_entries = num_entries;
data.flags = flags;
memcpy(data.entries, entries, sizeof(data.entries));
rc = nvIoctl(fd, _IOWR(0x48, 0x08, data), &data);
if (R_FAILED(rc)) return rc;
if(fence_out) memcpy(fence_out, &data.fence_out, sizeof(data.fence_out));
return rc;
}
Result nvioctlChannel_AllocObjCtx(u32 fd, u32 class_num, u32 flags) { Result nvioctlChannel_AllocObjCtx(u32 fd, u32 class_num, u32 flags) {
struct { struct {
u32 class_num; // 0x902D=2d, 0xB197=3d, 0xB1C0=compute, 0xA140=kepler, 0xB0B5=DMA, 0xB06F=channel_gpfifo u32 class_num; // 0x902D=2d, 0xB197=3d, 0xB1C0=compute, 0xA140=kepler, 0xB0B5=DMA, 0xB06F=channel_gpfifo