NvGpfifo: Redesign API to allow for submitting multiple entries at once

This commit is contained in:
fincs 2018-09-16 16:35:57 +02:00
parent 91fb381461
commit a50942509f
2 changed files with 51 additions and 20 deletions

View File

@ -1,13 +1,19 @@
#pragma once #pragma once
#define GPFIFO_QUEUE_SIZE 0x800
#define GPFIFO_ENTRY_NOT_MAIN BIT(9)
#define GPFIFO_ENTRY_NO_PREFETCH BIT(31)
typedef struct { typedef struct {
NvChannel* parent; NvChannel* parent;
u32 syncpt_id;
u32 num_entries;
nvioctl_gpfifo_entry entries[GPFIFO_QUEUE_SIZE];
} NvGpfifo; } NvGpfifo;
Result nvGpfifoCreate(NvGpfifo* f, NvChannel* parent); Result nvGpfifoCreate(NvGpfifo* f, NvChannel* parent);
void nvGpfifoClose(NvGpfifo* f); void nvGpfifoClose(NvGpfifo* f);
#define NV_MAKE_GPFIFO_ENTRY(iova, size) \ Result nvGpfifoAppendEntry(NvGpfifo* f, iova_t start, size_t num_cmds, u32 flags);
((iova) | (((u64)(size)) << 42)) Result nvGpfifoAppendCmdList(NvGpfifo* f, NvCmdList* cmd_list, u32 flags);
Result nvGpfifoFlush(NvGpfifo* f, u32 fence_incr, NvFence* fence_out);
Result nvGpfifoSubmitCmdList(NvGpfifo* f, NvCmdList* cmd_list, u32 fence_incr, NvFence* fence_out);

View File

@ -4,6 +4,7 @@
#include "arm/atomics.h" #include "arm/atomics.h"
#include "kernel/svc.h" #include "kernel/svc.h"
#include "kernel/event.h" #include "kernel/event.h"
#include "kernel/detect.h"
#include "services/nv.h" #include "services/nv.h"
#include "nvidia/ioctl.h" #include "nvidia/ioctl.h"
#include "nvidia/buffer.h" #include "nvidia/buffer.h"
@ -18,17 +19,14 @@
#include "nvidia/gpu/error_notifier.h" #include "nvidia/gpu/error_notifier.h"
#include "nvidia/gpu/gpu.h" #include "nvidia/gpu/gpu.h"
#define DEFAULT_FIFO_ENTRIES 0x800
Result nvGpfifoCreate(NvGpfifo* f, NvChannel* parent) Result nvGpfifoCreate(NvGpfifo* f, NvChannel* parent)
{ {
f->parent = parent; f->parent = parent;
NvFence fence; NvFence fence;
Result res = nvioctlChannel_AllocGpfifoEx2(parent->fd, DEFAULT_FIFO_ENTRIES, 1, 0, 0, 0, 0, &fence); Result res = nvioctlChannel_AllocGpfifoEx2(parent->fd, GPFIFO_QUEUE_SIZE, 1, 0, 0, 0, 0, &fence);
//__builtin_printf("nvGpfifoCreate initial fence: %d %u\n", (int)fence.id, fence.value); f->syncpt_id = fence.id;
//if (R_SUCCEEDED(res) && (s32)fence.id >= 0)
// nvFenceWait(&fence, -1);
return res; return res;
} }
@ -36,14 +34,39 @@ void nvGpfifoClose(NvGpfifo* f) {
/**/ /**/
} }
Result nvGpfifoSubmitCmdList(NvGpfifo* f, NvCmdList* cmd_list, u32 fence_incr, NvFence* fence_out) Result nvGpfifoAppendEntry(NvGpfifo* f, iova_t start, size_t num_cmds, u32 flags)
{
if (f->num_entries >= GPFIFO_QUEUE_SIZE)
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
nvioctl_gpfifo_entry* entry = &f->entries[f->num_entries++];
entry->desc = start;
entry->desc32[1] |= flags | (num_cmds << 10);
return 0;
}
Result nvGpfifoAppendCmdList(NvGpfifo* f, NvCmdList* cmd_list, u32 flags)
{
Result rc = nvGpfifoAppendEntry(f,
nvCmdListGetGpuAddr(cmd_list) + 4*cmd_list->offset,
cmd_list->num_cmds,
flags);
if (R_SUCCEEDED(rc)) {
cmd_list->offset += cmd_list->num_cmds;
cmd_list->num_cmds = 0;
}
return rc;
}
Result nvGpfifoFlush(NvGpfifo* f, u32 fence_incr, NvFence* fence_out)
{ {
Result rc; Result rc;
nvioctl_gpfifo_entry ent;
NvFence fence; NvFence fence;
ent.desc = nvCmdListGetGpuAddr(cmd_list) + 4*cmd_list->offset; if (!f->num_entries)
ent.desc32[1] |= (2 << 8) | (nvCmdListGetListSize(cmd_list) << 10); return MAKERESULT(Module_Libnx, LibnxError_NotFound);
fence.id = 0; fence.id = 0;
fence.value = fence_incr; fence.value = fence_incr;
@ -52,14 +75,16 @@ Result nvGpfifoSubmitCmdList(NvGpfifo* f, NvCmdList* cmd_list, u32 fence_incr, N
if (fence_incr) if (fence_incr)
flags |= BIT(8); flags |= BIT(8);
rc = nvioctlChannel_SubmitGpfifo( if (kernelAbove400())
f->parent->fd, &ent, 1, flags, &fence); rc = nvioctlChannel_KickoffPb(f->parent->fd, f->entries, f->num_entries, flags, &fence);
else
rc = nvioctlChannel_SubmitGpfifo(f->parent->fd, f->entries, f->num_entries, flags, &fence);
if (R_SUCCEEDED(rc) && fence_out) if (R_SUCCEEDED(rc)) {
*fence_out = fence; f->num_entries = 0;
if (fence_out)
cmd_list->offset += cmd_list->num_cmds; *fence_out = fence;
cmd_list->num_cmds = 0; }
return rc; return rc;
} }