diff options
Diffstat (limited to 'src/core/hle/service/nvdrv/devices/nvhost_gpu.h')
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_gpu.h | 169 |
1 files changed, 80 insertions, 89 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index 2ac74743f..e0298b4fe 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -11,46 +11,28 @@ #include "common/swap.h" #include "core/hle/service/nvdrv/devices/nvdevice.h" #include "core/hle/service/nvdrv/nvdata.h" +#include "video_core/dma_pusher.h" + +namespace Service::Nvidia { +class SyncpointManager; +} namespace Service::Nvidia::Devices { class nvmap; -constexpr u32 NVGPU_IOCTL_MAGIC('H'); -constexpr u32 NVGPU_IOCTL_CHANNEL_SUBMIT_GPFIFO(0x8); -constexpr u32 NVGPU_IOCTL_CHANNEL_KICKOFF_PB(0x1b); - class nvhost_gpu final : public nvdevice { public: - explicit nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); + explicit nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev, + SyncpointManager& syncpoint_manager); ~nvhost_gpu() override; - u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, - std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, - IoctlVersion version) override; + NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; + NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, + const std::vector<u8>& inline_input, std::vector<u8>& output) override; + NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, + std::vector<u8>& inline_output) override; private: - enum class IoctlCommand : u32_le { - IocSetNVMAPfdCommand = 0x40044801, - IocAllocGPFIFOCommand = 0x40084805, - IocSetClientDataCommand = 0x40084714, - IocGetClientDataCommand = 0x80084715, - IocZCullBind = 0xc010480b, - IocSetErrorNotifierCommand = 0xC018480C, - IocChannelSetPriorityCommand = 0x4004480D, - IocEnableCommand = 0x0000480E, - IocDisableCommand = 0x0000480F, - IocPreemptCommand = 0x00004810, - IocForceResetCommand = 0x00004811, - IocEventIdControlCommand = 0x40084812, - IocGetErrorNotificationCommand = 0xC0104817, - IocAllocGPFIFOExCommand = 0x40204818, - IocAllocGPFIFOEx2Command = 0xC020481A, - IocAllocObjCtxCommand = 0xC0104809, - IocChannelGetWaitbaseCommand = 0xC0080003, - IocChannelSetTimeoutCommand = 0x40044803, - IocChannelSetTimeslice = 0xC004481D, - }; - enum class CtxObjects : u32_le { Ctx2D = 0x902D, Ctx3D = 0xB197, @@ -61,63 +43,63 @@ private: }; struct IoctlSetNvmapFD { - u32_le nvmap_fd; + s32_le nvmap_fd{}; }; static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); struct IoctlChannelSetTimeout { - u32_le timeout; + u32_le timeout{}; }; static_assert(sizeof(IoctlChannelSetTimeout) == 4, "IoctlChannelSetTimeout is incorrect size"); struct IoctlAllocGPFIFO { - u32_le num_entries; - u32_le flags; + u32_le num_entries{}; + u32_le flags{}; }; static_assert(sizeof(IoctlAllocGPFIFO) == 8, "IoctlAllocGPFIFO is incorrect size"); struct IoctlClientData { - u64_le data; + u64_le data{}; }; static_assert(sizeof(IoctlClientData) == 8, "IoctlClientData is incorrect size"); struct IoctlZCullBind { - u64_le gpu_va; - u32_le mode; // 0=global, 1=no_ctxsw, 2=separate_buffer, 3=part_of_regular_buf + u64_le gpu_va{}; + u32_le mode{}; // 0=global, 1=no_ctxsw, 2=separate_buffer, 3=part_of_regular_buf INSERT_PADDING_WORDS(1); }; static_assert(sizeof(IoctlZCullBind) == 16, "IoctlZCullBind is incorrect size"); struct IoctlSetErrorNotifier { - u64_le offset; - u64_le size; - u32_le mem; // nvmap object handle + u64_le offset{}; + u64_le size{}; + u32_le mem{}; // nvmap object handle INSERT_PADDING_WORDS(1); }; static_assert(sizeof(IoctlSetErrorNotifier) == 24, "IoctlSetErrorNotifier is incorrect size"); struct IoctlChannelSetPriority { - u32_le priority; + u32_le priority{}; }; static_assert(sizeof(IoctlChannelSetPriority) == 4, "IoctlChannelSetPriority is incorrect size"); struct IoctlSetTimeslice { - u32_le timeslice; + u32_le timeslice{}; }; static_assert(sizeof(IoctlSetTimeslice) == 4, "IoctlSetTimeslice is incorrect size"); struct IoctlEventIdControl { - u32_le cmd; // 0=disable, 1=enable, 2=clear - u32_le id; + u32_le cmd{}; // 0=disable, 1=enable, 2=clear + u32_le id{}; }; static_assert(sizeof(IoctlEventIdControl) == 8, "IoctlEventIdControl is incorrect size"); struct IoctlGetErrorNotification { - u64_le timestamp; - u32_le info32; - u16_le info16; - u16_le status; // always 0xFFFF + u64_le timestamp{}; + u32_le info32{}; + u16_le info16{}; + u16_le status{}; // always 0xFFFF }; static_assert(sizeof(IoctlGetErrorNotification) == 16, "IoctlGetErrorNotification is incorrect size"); @@ -125,80 +107,89 @@ private: static_assert(sizeof(Fence) == 8, "Fence is incorrect size"); struct IoctlAllocGpfifoEx { - u32_le num_entries; - u32_le flags; - u32_le unk0; - u32_le unk1; - u32_le unk2; - u32_le unk3; - u32_le unk4; - u32_le unk5; + u32_le num_entries{}; + u32_le flags{}; + u32_le unk0{}; + u32_le unk1{}; + u32_le unk2{}; + u32_le unk3{}; + u32_le unk4{}; + u32_le unk5{}; }; static_assert(sizeof(IoctlAllocGpfifoEx) == 32, "IoctlAllocGpfifoEx is incorrect size"); struct IoctlAllocGpfifoEx2 { - u32_le num_entries; // in - u32_le flags; // in - u32_le unk0; // in (1 works) - Fence fence_out; // out - u32_le unk1; // in - u32_le unk2; // in - u32_le unk3; // in + u32_le num_entries{}; // in + u32_le flags{}; // in + u32_le unk0{}; // in (1 works) + Fence fence_out{}; // out + u32_le unk1{}; // in + u32_le unk2{}; // in + u32_le unk3{}; // in }; static_assert(sizeof(IoctlAllocGpfifoEx2) == 32, "IoctlAllocGpfifoEx2 is incorrect size"); struct IoctlAllocObjCtx { - u32_le class_num; // 0x902D=2d, 0xB197=3d, 0xB1C0=compute, 0xA140=kepler, 0xB0B5=DMA, - // 0xB06F=channel_gpfifo - u32_le flags; - u64_le obj_id; // (ignored) used for FREE_OBJ_CTX ioctl, which is not supported + u32_le class_num{}; // 0x902D=2d, 0xB197=3d, 0xB1C0=compute, 0xA140=kepler, 0xB0B5=DMA, + // 0xB06F=channel_gpfifo + u32_le flags{}; + u64_le obj_id{}; // (ignored) used for FREE_OBJ_CTX ioctl, which is not supported }; static_assert(sizeof(IoctlAllocObjCtx) == 16, "IoctlAllocObjCtx is incorrect size"); struct IoctlSubmitGpfifo { - u64_le address; // pointer to gpfifo entry structs - u32_le num_entries; // number of fence objects being submitted + u64_le address{}; // pointer to gpfifo entry structs + u32_le num_entries{}; // number of fence objects being submitted union { u32_le raw; BitField<0, 1, u32_le> add_wait; // append a wait sync_point to the list BitField<1, 1, u32_le> add_increment; // append an increment to the list - BitField<2, 1, u32_le> new_hw_format; // Mostly ignored + BitField<2, 1, u32_le> new_hw_format; // mostly ignored + BitField<4, 1, u32_le> suppress_wfi; // suppress wait for interrupt BitField<8, 1, u32_le> increment; // increment the returned fence } flags; - Fence fence_out; // returned new fence object for others to wait on + Fence fence_out{}; // returned new fence object for others to wait on + + u32 AddIncrementValue() const { + return flags.add_increment.Value() << 1; + } }; static_assert(sizeof(IoctlSubmitGpfifo) == 16 + sizeof(Fence), "IoctlSubmitGpfifo is incorrect size"); struct IoctlGetWaitbase { - u32 unknown; // seems to be ignored? Nintendo added this - u32 value; + u32 unknown{}; // seems to be ignored? Nintendo added this + u32 value{}; }; static_assert(sizeof(IoctlGetWaitbase) == 8, "IoctlGetWaitbase is incorrect size"); - u32_le nvmap_fd{}; + s32_le nvmap_fd{}; u64_le user_data{}; IoctlZCullBind zcull_params{}; u32_le channel_priority{}; u32_le channel_timeslice{}; - u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); - u32 SetClientData(const std::vector<u8>& input, std::vector<u8>& output); - u32 GetClientData(const std::vector<u8>& input, std::vector<u8>& output); - u32 ZCullBind(const std::vector<u8>& input, std::vector<u8>& output); - u32 SetErrorNotifier(const std::vector<u8>& input, std::vector<u8>& output); - u32 SetChannelPriority(const std::vector<u8>& input, std::vector<u8>& output); - u32 AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output); - u32 AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output); - u32 SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& output); - u32 KickoffPB(const std::vector<u8>& input, std::vector<u8>& output, - const std::vector<u8>& input2, IoctlVersion version); - u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); - u32 ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output); - u32 ChannelSetTimeslice(const std::vector<u8>& input, std::vector<u8>& output); + NvResult SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); + NvResult SetClientData(const std::vector<u8>& input, std::vector<u8>& output); + NvResult GetClientData(const std::vector<u8>& input, std::vector<u8>& output); + NvResult ZCullBind(const std::vector<u8>& input, std::vector<u8>& output); + NvResult SetErrorNotifier(const std::vector<u8>& input, std::vector<u8>& output); + NvResult SetChannelPriority(const std::vector<u8>& input, std::vector<u8>& output); + NvResult AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output); + NvResult AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output); + NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8>& output, + Tegra::CommandList&& entries); + NvResult SubmitGPFIFOBase(const std::vector<u8>& input, std::vector<u8>& output, + bool kickoff = false); + NvResult SubmitGPFIFOBase(const std::vector<u8>& input, const std::vector<u8>& input_inline, + std::vector<u8>& output); + NvResult GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); + NvResult ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output); + NvResult ChannelSetTimeslice(const std::vector<u8>& input, std::vector<u8>& output); std::shared_ptr<nvmap> nvmap_dev; - u32 assigned_syncpoints{}; + SyncpointManager& syncpoint_manager; + Fence channel_fence; }; } // namespace Service::Nvidia::Devices |