eden/src/core/hle/service/nvdrv/nvdrv.h
lizzie a8093c2a3c
[*] change all std::unordered_map and std::unordered_set into ankerl::unordered_dense::map/set variants (#3442)
mainly doing this to reduce memory footprint; we all know how nice ankerl::unordered_dense is

in theory 4x faster - in practice these maps arent that "hot" anyways so not likely to have much perf gained

i just want to reduce mem fragmentation to ease my porting process, plus it helps other platforms as well (ahem weak Mediatek devices) :)

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3442
Reviewed-by: DraVee <dravee@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2026-02-10 03:34:07 +01:00

120 lines
3.1 KiB
C++

// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <functional>
#include <list>
#include <memory>
#include <span>
#include <string>
#include <ankerl/unordered_dense.h>
#include "common/common_types.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/nvdata.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Kernel {
class KEvent;
}
namespace Service::Nvidia {
namespace NvCore {
class Container;
class SyncpointManager;
} // namespace NvCore
namespace Devices {
class nvdevice;
class nvhost_ctrl;
} // namespace Devices
class Module;
class EventInterface {
public:
explicit EventInterface(Module& module_);
~EventInterface();
Kernel::KEvent* CreateEvent(std::string name);
void FreeEvent(Kernel::KEvent* event);
private:
Module& module;
std::mutex guard;
std::list<Devices::nvhost_ctrl*> on_signal;
};
class Module final {
public:
explicit Module(Core::System& system_);
~Module();
/// Returns a pointer to one of the available devices, identified by its name.
template <typename T>
std::shared_ptr<T> GetDevice(DeviceFD fd) {
auto itr = open_files.find(fd);
if (itr == open_files.end())
return nullptr;
return std::static_pointer_cast<T>(itr->second);
}
NvResult VerifyFD(DeviceFD fd) const;
/// Opens a device node and returns a file descriptor to it.
DeviceFD Open(const std::string& device_name, NvCore::SessionId session_id);
/// Sends an ioctl command to the specified file descriptor.
NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output);
NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::span<const u8> inline_input, std::span<u8> output);
NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
std::span<u8> inline_output);
/// Closes a device file descriptor and returns operation success.
NvResult Close(DeviceFD fd);
NvResult QueryEvent(DeviceFD fd, u32 event_id, Kernel::KEvent*& event);
NvCore::Container& GetContainer() {
return container;
}
private:
friend class EventInterface;
/// Manages syncpoints on the host
NvCore::Container container;
/// Id to use for the next open file descriptor.
DeviceFD next_fd = 1;
using FilesContainerType = ankerl::unordered_dense::map<DeviceFD, std::shared_ptr<Devices::nvdevice>>;
/// Mapping of file descriptors to the devices they reference.
FilesContainerType open_files;
KernelHelpers::ServiceContext service_context;
EventInterface events_interface;
ankerl::unordered_dense::map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders;
};
void LoopProcess(Core::System& system);
} // namespace Service::Nvidia