mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-28 08:45:29 +03:00
Optimize NvDevice Function Lookup
This essentially optimizes NvDevice in the same way services were, refer to the last commit for details
This commit is contained in:
parent
5149b333d7
commit
711d4f8824
@ -51,7 +51,7 @@ namespace skyline::service {
|
|||||||
class DerivedService; //!< A placeholder derived class which is used for class function semantics
|
class DerivedService; //!< A placeholder derived class which is used for class function semantics
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A per-service-function descriptor with it's name and a function pointer to it
|
* @brief A per-function descriptor for HLE service functions
|
||||||
*/
|
*/
|
||||||
struct ServiceFunctionDescriptor {
|
struct ServiceFunctionDescriptor {
|
||||||
DerivedService *clazz; //!< A pointer to the class that this was derived from, it's used as the 'this' pointer for the function
|
DerivedService *clazz; //!< A pointer to the class that this was derived from, it's used as the 'this' pointer for the function
|
||||||
|
@ -30,18 +30,18 @@ namespace skyline::service::nvdrv::device {
|
|||||||
}
|
}
|
||||||
}()};
|
}()};
|
||||||
|
|
||||||
std::pair<std::function<NvStatus(IoctlType, span<u8>, span<u8>)>, std::string_view> function;
|
NvDeviceFunctionDescriptor function;
|
||||||
try {
|
try {
|
||||||
function = GetIoctlFunction(cmd);
|
function = GetIoctlFunction(cmd);
|
||||||
state.logger->DebugNoPrefix("{}: {} @ {}", typeString, GetName(), function.second);
|
state.logger->DebugNoPrefix("{}: {}", typeString, function.name);
|
||||||
} catch (std::out_of_range &) {
|
} catch (std::out_of_range &) {
|
||||||
state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", GetName(), cmd);
|
state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", GetName(), cmd);
|
||||||
return NvStatus::NotImplemented;
|
return NvStatus::NotImplemented;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return function.first(type, buffer, inlineBuffer);
|
return function(type, buffer, inlineBuffer);
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
throw exception("{} ({} @ {}: {})", e.what(), typeString, GetName(), function.second);
|
throw exception("{} ({}: {})", e.what(), typeString, function.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,18 @@
|
|||||||
#include <kernel/ipc.h>
|
#include <kernel/ipc.h>
|
||||||
#include <kernel/types/KEvent.h>
|
#include <kernel/types/KEvent.h>
|
||||||
|
|
||||||
#define NVFUNC(id, Class, Function) std::pair<u32, std::pair<std::function<NvStatus(Class*, IoctlType, span<u8>, span<u8>)>, std::string_view>>{id, {&Class::Function, #Function}}
|
#define NV_STRINGIFY(string) #string
|
||||||
|
#define NVFUNC(id, Class, Function) std::pair<u32, std::pair<NvStatus(Class::*)(IoctlType, span<u8>, span<u8>), const char*>>{id, {&Class::Function, NV_STRINGIFY(Class::Function)}}
|
||||||
#define NVDEVICE_DECL_AUTO(name, value) decltype(value) name = value
|
#define NVDEVICE_DECL_AUTO(name, value) decltype(value) name = value
|
||||||
#define NVDEVICE_DECL(...) \
|
#define NVDEVICE_DECL(...) \
|
||||||
NVDEVICE_DECL_AUTO(functions, frz::make_unordered_map({__VA_ARGS__})); \
|
NVDEVICE_DECL_AUTO(functions, frz::make_unordered_map({__VA_ARGS__})); \
|
||||||
std::pair<std::function<NvStatus(IoctlType, span<u8>, span<u8>)>, std::string_view> GetIoctlFunction(u32 id) override { \
|
NvDeviceFunctionDescriptor GetIoctlFunction(u32 id) override { \
|
||||||
auto& function{functions.at(id)}; \
|
auto& function{functions.at(id)}; \
|
||||||
return std::make_pair(std::bind(function.first, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), function.second); \
|
return NvDeviceFunctionDescriptor{ \
|
||||||
|
reinterpret_cast<DerivedDevice*>(this), \
|
||||||
|
reinterpret_cast<decltype(NvDeviceFunctionDescriptor::function)>(function.first), \
|
||||||
|
function.second \
|
||||||
|
}; \
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace skyline::service::nvdrv::device {
|
namespace skyline::service::nvdrv::device {
|
||||||
@ -67,12 +72,27 @@ namespace skyline::service::nvdrv::device {
|
|||||||
protected:
|
protected:
|
||||||
const DeviceState &state;
|
const DeviceState &state;
|
||||||
|
|
||||||
|
class DerivedDevice; //!< A placeholder derived class which is used for class function semantics
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A per-function descriptor for NvDevice functions
|
||||||
|
*/
|
||||||
|
struct NvDeviceFunctionDescriptor {
|
||||||
|
DerivedDevice *clazz; //!< A pointer to the class that this was derived from, it's used as the 'this' pointer for the function
|
||||||
|
NvStatus (DerivedDevice::*function)(IoctlType, span<u8>, span<u8>); //!< A function pointer to the implementation of the function
|
||||||
|
const char *name; //!< A pointer to a static string in the format "Class::Function" for the specific device class/function
|
||||||
|
|
||||||
|
constexpr NvStatus operator()(IoctlType type, span<u8> buffer, span<u8> inlineBuffer) {
|
||||||
|
return (clazz->*function)(type, buffer, inlineBuffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NvDevice(const DeviceState &state) : state(state) {}
|
NvDevice(const DeviceState &state) : state(state) {}
|
||||||
|
|
||||||
virtual ~NvDevice() = default;
|
virtual ~NvDevice() = default;
|
||||||
|
|
||||||
virtual std::pair<std::function<NvStatus(IoctlType, span<u8>, span<u8>)>, std::string_view> GetIoctlFunction(u32 id) = 0;
|
virtual NvDeviceFunctionDescriptor GetIoctlFunction(u32 id) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The name of the class
|
* @return The name of the class
|
||||||
|
Loading…
Reference in New Issue
Block a user