Compare commits

..

2 Commits

Author SHA1 Message Date
lizzie 2a14f37ed8 2026-09-11 20:06:05
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-11 20:06:05 +00:00
lizzie 5fcfa46ca8 2026-09-11 18:26:30
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-11 18:26:30 +00:00
4 changed files with 56 additions and 12 deletions
@@ -298,7 +298,7 @@ NvResult nvhost_gpu::AllocateObjectContext(IoctlAllocObjCtx& params) {
return NvResult::Success;
}
static boost::container::small_vector<Tegra::CommandHeader, 512> BuildWaitCommandList(
static std::vector<Tegra::CommandHeader> BuildWaitCommandList(
NvFence fence) {
return {
Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1,
@@ -310,9 +310,9 @@ static boost::container::small_vector<Tegra::CommandHeader, 512> BuildWaitComman
};
}
static boost::container::small_vector<Tegra::CommandHeader, 512> BuildIncrementCommandList(
static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(
NvFence fence) {
boost::container::small_vector<Tegra::CommandHeader, 512> result{
std::vector<Tegra::CommandHeader> result{
Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1,
Tegra::SubmissionMode::Increasing),
{}};
@@ -327,9 +327,9 @@ static boost::container::small_vector<Tegra::CommandHeader, 512> BuildIncrementC
return result;
}
static boost::container::small_vector<Tegra::CommandHeader, 512> BuildIncrementWithWfiCommandList(
static std::vector<Tegra::CommandHeader> BuildIncrementWithWfiCommandList(
NvFence fence) {
boost::container::small_vector<Tegra::CommandHeader, 512> result{
std::vector<Tegra::CommandHeader> result{
Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForIdle, 1,
Tegra::SubmissionMode::Increasing),
{}};
+40 -1
View File
@@ -697,6 +697,16 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
SDL_AddEventWatch(&SDLEventWatcher, this);
initialized = true;
if (start_thread) {
vibration_thread = std::thread([this] {
Common::SetCurrentThreadName("SDL_Vibration");
using namespace std::chrono_literals;
while (initialized) {
SendVibrations();
std::this_thread::sleep_for(250ms); // 4 TPS
}
});
}
// Because the events for joystick connection happens before we have our event watcher added, we
// can just open all the joysticks right here
int joystick_count = 0;
@@ -715,6 +725,7 @@ SDLDriver::~SDLDriver() {
initialized = false;
if (start_thread) {
vibration_thread.join();
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD);
}
}
@@ -794,7 +805,10 @@ Common::Input::DriverResult SDLDriver::SetVibration(
.type = Common::Input::VibrationAmplificationType::Exponential,
};
joystick->RumblePlay(new_vibration);
vibration_queue.Push(VibrationRequest{
.identifier = identifier,
.vibration = new_vibration,
});
return Common::Input::DriverResult::Success;
}
@@ -838,6 +852,31 @@ bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) {
return true;
}
void SDLDriver::SendVibrations() {
std::vector<VibrationRequest> filtered_vibrations{};
while (!vibration_queue.Empty()) {
VibrationRequest request;
vibration_queue.Pop(request);
const auto joystick = GetSDLJoystickByGUID(request.identifier.guid.RawString(),
static_cast<int>(request.identifier.port));
const auto it = std::find_if(filtered_vibrations.begin(), filtered_vibrations.end(),
[request](VibrationRequest vibration) {
return vibration.identifier == request.identifier;
});
if (it == filtered_vibrations.end()) {
filtered_vibrations.push_back(std::move(request));
continue;
}
*it = request;
}
for (const auto& vibration : filtered_vibrations) {
const auto joystick = GetSDLJoystickByGUID(vibration.identifier.guid.RawString(),
static_cast<int>(vibration.identifier.port));
joystick->RumblePlay(vibration.vibration);
}
}
Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, const Common::UUID& guid,
s32 axis, float value) const {
Common::ParamPackage params{};
+6 -1
View File
@@ -113,11 +113,16 @@ private:
/// Returns true if the button is on the left joycon
bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const;
/// Queue of vibration request to controllers
Common::SPSCQueue<VibrationRequest> vibration_queue;
/// Map of GUID of a list of corresponding virtual Joysticks
::Common::unordered_map<Common::UUID, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map;
std::mutex joystick_map_mutex;
bool start_thread = false;
std::atomic<bool> initialized = false;
bool start_thread;
std::thread vibration_thread;
};
} // namespace InputCommon
+5 -5
View File
@@ -109,11 +109,11 @@ inline CommandHeader BuildCommandHeader(BufferMethods method, u32 arg_count, Sub
struct CommandList final {
CommandList() = default;
explicit CommandList(std::size_t size) : command_lists(size) {}
explicit CommandList(boost::container::small_vector<CommandHeader, 512>&& prefetch_command_list_)
: prefetch_command_list{std::move(prefetch_command_list_)} {}
boost::container::small_vector<CommandListHeader, 512> command_lists;
boost::container::small_vector<CommandHeader, 512> prefetch_command_list;
explicit CommandList(std::vector<CommandHeader>&& prefetch_command_list_)
: prefetch_command_list{std::move(prefetch_command_list_)}
{}
std::vector<CommandListHeader> command_lists;
std::vector<CommandHeader> prefetch_command_list;
};
/// @brief The DmaPusher class implements DMA submission to FIFOs, providing an area of memory that the