summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/glue/glue.cpp4
-rw-r--r--src/core/hle/service/glue/notif.cpp44
-rw-r--r--src/core/hle/service/glue/notif.h25
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp165
-rw-r--r--src/core/hle/service/hid/controllers/npad.h8
-rw-r--r--src/core/hle/service/hid/hid.cpp26
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp13
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp10
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h3
12 files changed, 263 insertions, 46 deletions
diff --git a/src/core/hle/service/glue/glue.cpp b/src/core/hle/service/glue/glue.cpp
index a08dc9758..b24d469cf 100644
--- a/src/core/hle/service/glue/glue.cpp
+++ b/src/core/hle/service/glue/glue.cpp
@@ -8,6 +8,7 @@
#include "core/hle/service/glue/bgtc.h"
#include "core/hle/service/glue/ectx.h"
#include "core/hle/service/glue/glue.h"
+#include "core/hle/service/glue/notif.h"
namespace Service::Glue {
@@ -24,6 +25,9 @@ void InstallInterfaces(Core::System& system) {
// Error Context
std::make_shared<ECTX_AW>(system)->InstallAsService(system.ServiceManager());
+
+ // Notification Services for application
+ std::make_shared<NOTIF_A>(system)->InstallAsService(system.ServiceManager());
}
} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/notif.cpp b/src/core/hle/service/glue/notif.cpp
new file mode 100644
index 000000000..c559ec9df
--- /dev/null
+++ b/src/core/hle/service/glue/notif.cpp
@@ -0,0 +1,44 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/service/glue/notif.h"
+
+namespace Service::Glue {
+
+NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {500, nullptr, "RegisterAlarmSetting"},
+ {510, nullptr, "UpdateAlarmSetting"},
+ {520, &NOTIF_A::ListAlarmSettings, "ListAlarmSettings"},
+ {530, nullptr, "LoadApplicationParameter"},
+ {540, nullptr, "DeleteAlarmSetting"},
+ {1000, &NOTIF_A::Initialize, "Initialize"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+NOTIF_A::~NOTIF_A() = default;
+
+void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) {
+ // Returns an array of AlarmSetting
+ constexpr s32 alarm_count = 0;
+
+ LOG_WARNING(Service_NOTIF, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(alarm_count);
+}
+
+void NOTIF_A::Initialize(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_NOTIF, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/notif.h b/src/core/hle/service/glue/notif.h
new file mode 100644
index 000000000..6ecf2015c
--- /dev/null
+++ b/src/core/hle/service/glue/notif.h
@@ -0,0 +1,25 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Core {
+class System;
+}
+
+namespace Service::Glue {
+
+class NOTIF_A final : public ServiceFramework<NOTIF_A> {
+public:
+ explicit NOTIF_A(Core::System& system_);
+ ~NOTIF_A() override;
+
+private:
+ void ListAlarmSettings(Kernel::HLERequestContext& ctx);
+ void Initialize(Kernel::HLERequestContext& ctx);
+};
+
+} // namespace Service::Glue
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index ae56f10cf..2705e9dcb 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -110,7 +110,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
UpdateControllerAt(npad_type, npad_id, is_connected);
break;
case Core::HID::ControllerTriggerType::Battery: {
- if (!controller.is_connected) {
+ if (!controller.device->IsConnected()) {
return;
}
auto& shared_memory = controller.shared_memory_entry;
@@ -150,7 +150,6 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
shared_memory.system_properties.is_vertical.Assign(1);
shared_memory.system_properties.use_plus.Assign(1);
shared_memory.system_properties.use_minus.Assign(1);
- shared_memory.assignment_mode = NpadJoyAssignmentMode::Single;
shared_memory.applet_footer.type = AppletFooterUiType::SwitchProController;
break;
case Core::HID::NpadStyleIndex::Handheld:
@@ -166,21 +165,30 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
break;
case Core::HID::NpadStyleIndex::JoyconDual:
shared_memory.style_tag.joycon_dual.Assign(1);
- shared_memory.device_type.joycon_left.Assign(1);
- shared_memory.device_type.joycon_right.Assign(1);
- shared_memory.system_properties.is_vertical.Assign(1);
- shared_memory.system_properties.use_plus.Assign(1);
- shared_memory.system_properties.use_minus.Assign(1);
+ if (controller.is_dual_left_connected) {
+ shared_memory.device_type.joycon_left.Assign(1);
+ shared_memory.system_properties.use_minus.Assign(1);
+ }
+ if (controller.is_dual_right_connected) {
+ shared_memory.device_type.joycon_right.Assign(1);
+ shared_memory.system_properties.use_plus.Assign(1);
+ }
shared_memory.system_properties.use_directional_buttons.Assign(1);
+ shared_memory.system_properties.is_vertical.Assign(1);
shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual;
- shared_memory.applet_footer.type = AppletFooterUiType::JoyDual;
+ if (controller.is_dual_left_connected && controller.is_dual_right_connected) {
+ shared_memory.applet_footer.type = AppletFooterUiType::JoyDual;
+ } else if (controller.is_dual_left_connected) {
+ shared_memory.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly;
+ } else {
+ shared_memory.applet_footer.type = AppletFooterUiType::JoyDualRightOnly;
+ }
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
shared_memory.style_tag.joycon_left.Assign(1);
shared_memory.device_type.joycon_left.Assign(1);
shared_memory.system_properties.is_horizontal.Assign(1);
shared_memory.system_properties.use_minus.Assign(1);
- shared_memory.assignment_mode = NpadJoyAssignmentMode::Single;
shared_memory.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal;
break;
case Core::HID::NpadStyleIndex::JoyconRight:
@@ -188,7 +196,6 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
shared_memory.device_type.joycon_right.Assign(1);
shared_memory.system_properties.is_horizontal.Assign(1);
shared_memory.system_properties.use_plus.Assign(1);
- shared_memory.assignment_mode = NpadJoyAssignmentMode::Single;
shared_memory.applet_footer.type = AppletFooterUiType::JoyRightHorizontal;
break;
case Core::HID::NpadStyleIndex::GameCube:
@@ -200,7 +207,6 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
case Core::HID::NpadStyleIndex::Pokeball:
shared_memory.style_tag.palma.Assign(1);
shared_memory.device_type.palma.Assign(1);
- shared_memory.assignment_mode = NpadJoyAssignmentMode::Single;
break;
case Core::HID::NpadStyleIndex::NES:
shared_memory.style_tag.lark.Assign(1);
@@ -443,11 +449,15 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
case Core::HID::NpadStyleIndex::JoyconDual:
pad_state.connection_status.raw = 0;
pad_state.connection_status.is_connected.Assign(1);
- pad_state.connection_status.is_left_connected.Assign(1);
- pad_state.connection_status.is_right_connected.Assign(1);
+ if (controller.is_dual_left_connected) {
+ pad_state.connection_status.is_left_connected.Assign(1);
+ libnx_state.connection_status.is_left_connected.Assign(1);
+ }
+ if (controller.is_dual_right_connected) {
+ pad_state.connection_status.is_right_connected.Assign(1);
+ libnx_state.connection_status.is_right_connected.Assign(1);
+ }
- libnx_state.connection_status.is_left_connected.Assign(1);
- libnx_state.connection_status.is_right_connected.Assign(1);
pad_state.sampling_number =
npad.joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1;
npad.joy_dual_lifo.WriteNextEntry(pad_state);
@@ -687,7 +697,7 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode
return communication_mode;
}
-void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id,
+void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type,
NpadJoyAssignmentMode assignment_mode) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
@@ -698,6 +708,62 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id,
if (controller.shared_memory_entry.assignment_mode != assignment_mode) {
controller.shared_memory_entry.assignment_mode = assignment_mode;
}
+
+ if (!controller.device->IsConnected()) {
+ return;
+ }
+
+ if (assignment_mode == NpadJoyAssignmentMode::Dual) {
+ if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft) {
+ DisconnectNpad(npad_id);
+ controller.is_dual_left_connected = true;
+ controller.is_dual_right_connected = false;
+ UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
+ return;
+ }
+ if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) {
+ DisconnectNpad(npad_id);
+ controller.is_dual_left_connected = false;
+ controller.is_dual_right_connected = true;
+ UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
+ return;
+ }
+ return;
+ }
+
+ // This is for NpadJoyAssignmentMode::Single
+
+ // Only JoyconDual get affected by this function
+ if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) {
+ return;
+ }
+
+ if (controller.is_dual_left_connected && !controller.is_dual_right_connected) {
+ DisconnectNpad(npad_id);
+ UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
+ return;
+ }
+ if (!controller.is_dual_left_connected && controller.is_dual_right_connected) {
+ DisconnectNpad(npad_id);
+ UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
+ return;
+ }
+
+ // We have two controllers connected to the same npad_id we need to split them
+ const auto npad_id_2 = hid_core.GetFirstDisconnectedNpadId();
+ auto& controller_2 = GetControllerFromNpadIdType(npad_id_2);
+ DisconnectNpad(npad_id);
+ if (npad_device_type == NpadJoyDeviceType::Left) {
+ UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
+ controller_2.is_dual_left_connected = false;
+ controller_2.is_dual_right_connected = true;
+ UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true);
+ } else {
+ UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
+ controller_2.is_dual_left_connected = true;
+ controller_2.is_dual_right_connected = false;
+ UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true);
+ }
}
bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
@@ -907,6 +973,7 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
}
auto& shared_memory_entry = controller.shared_memory_entry;
+ // Don't reset shared_memory_entry.assignment_mode this value is persistent
shared_memory_entry.style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out
shared_memory_entry.device_type.raw = 0;
shared_memory_entry.system_properties.raw = 0;
@@ -923,9 +990,10 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
.left = {},
.right = {},
};
- shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual;
shared_memory_entry.applet_footer.type = AppletFooterUiType::None;
+ controller.is_dual_left_connected = true;
+ controller.is_dual_right_connected = true;
controller.is_connected = false;
controller.device->Disconnect();
SignalStyleSetChangedEvent(npad_id);
@@ -1022,19 +1090,70 @@ void Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
npad_id_2);
return;
}
- auto& controller_1 = GetControllerFromNpadIdType(npad_id_1).device;
- auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device;
+ auto& controller_1 = GetControllerFromNpadIdType(npad_id_1);
+ auto& controller_2 = GetControllerFromNpadIdType(npad_id_2);
+ const auto controller_style_1 = controller_1.device->GetNpadStyleIndex();
+ const auto controller_style_2 = controller_2.device->GetNpadStyleIndex();
+ bool merge_controllers = false;
// If the controllers at both npad indices form a pair of left and right joycons, merge them.
// Otherwise, do nothing.
- if ((controller_1->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft &&
- controller_2->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) ||
- (controller_2->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft &&
- controller_1->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight)) {
+ if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft &&
+ controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) {
+ merge_controllers = true;
+ }
+ if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft &&
+ controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight) {
+ merge_controllers = true;
+ }
+ if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
+ controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight &&
+ controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) {
+ merge_controllers = true;
+ }
+ if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
+ controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft &&
+ !controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) {
+ merge_controllers = true;
+ }
+ if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
+ controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight &&
+ controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
+ merge_controllers = true;
+ }
+ if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
+ controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft &&
+ !controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
+ merge_controllers = true;
+ }
+ if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
+ controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
+ controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected &&
+ !controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
+ merge_controllers = true;
+ }
+ if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
+ controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
+ !controller_1.is_dual_left_connected && controller_1.is_dual_right_connected &&
+ controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
+ merge_controllers = true;
+ }
+
+ if (merge_controllers) {
// Disconnect the joycon at the second id and connect the dual joycon at the first index.
DisconnectNpad(npad_id_2);
+ controller_1.is_dual_left_connected = true;
+ controller_1.is_dual_right_connected = true;
AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1);
+ return;
}
+ LOG_WARNING(Service_HID,
+ "Controllers can't be merged npad_id_1:{}, npad_id_2:{}, type_1:{}, type_2:{}, "
+ "dual_1(left/right):{}/{}, dual_2(left/right):{}/{}",
+ npad_id_1, npad_id_2, controller_1.device->GetNpadStyleIndex(),
+ controller_2.device->GetNpadStyleIndex(), controller_1.is_dual_left_connected,
+ controller_1.is_dual_right_connected, controller_2.is_dual_left_connected,
+ controller_2.is_dual_right_connected);
}
void Controller_NPad::StartLRAssignmentMode() {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index de5fa5a64..63281cb35 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -113,7 +113,8 @@ public:
void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_);
NpadCommunicationMode GetNpadCommunicationMode() const;
- void SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyAssignmentMode assignment_mode);
+ void SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type,
+ NpadJoyAssignmentMode assignment_mode);
bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index,
const Core::HID::VibrationValue& vibration_value);
@@ -464,7 +465,10 @@ private:
std::array<VibrationData, 2> vibration{};
bool unintended_home_button_input_protection{};
bool is_connected{};
- Core::HID::NpadStyleIndex npad_type{Core::HID::NpadStyleIndex::None};
+
+ // Dual joycons can have only one side connected
+ bool is_dual_left_connected{true};
+ bool is_dual_right_connected{true};
// Motion parameters
bool sixaxis_at_rest{true};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 14f737d39..7163e1a4e 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -975,35 +975,35 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx
const auto parameters{rp.PopRaw<Parameters>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyAssignmentMode::Single);
+ .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left,
+ Controller_NPad::NpadJoyAssignmentMode::Single);
- LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
- parameters.npad_id, parameters.applet_resource_user_id);
+ LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
- // TODO: Check the differences between this and SetNpadJoyAssignmentModeSingleByDefault
IPC::RequestParser rp{ctx};
struct Parameters {
Core::HID::NpadIdType npad_id;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
- u64 npad_joy_device_type;
+ Controller_NPad::NpadJoyDeviceType npad_joy_device_type;
};
static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyAssignmentMode::Single);
+ .SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type,
+ Controller_NPad::NpadJoyAssignmentMode::Single);
- LOG_WARNING(Service_HID,
- "(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
- parameters.npad_id, parameters.applet_resource_user_id,
- parameters.npad_joy_device_type);
+ LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
+ parameters.npad_id, parameters.applet_resource_user_id,
+ parameters.npad_joy_device_type);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -1021,10 +1021,10 @@ void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyAssignmentMode::Dual);
+ .SetNpadMode(parameters.npad_id, {}, Controller_NPad::NpadJoyAssignmentMode::Dual);
- LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
- parameters.npad_id, parameters.applet_resource_user_id);
+ LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index 0d7d4ad03..8314d1ec2 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -20,8 +20,12 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
switch (command.group) {
case 0x0:
switch (command.cmd) {
- case 0x1:
- return Submit(input, output);
+ case 0x1: {
+ if (!fd_to_id.contains(fd)) {
+ fd_to_id[fd] = next_id++;
+ }
+ return Submit(fd, input, output);
+ }
case 0x2:
return GetSyncpoint(input, output);
case 0x3:
@@ -66,7 +70,10 @@ void nvhost_nvdec::OnOpen(DeviceFD fd) {}
void nvhost_nvdec::OnClose(DeviceFD fd) {
LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
- system.GPU().ClearCdmaInstance();
+ const auto iter = fd_to_id.find(fd);
+ if (iter != fd_to_id.end()) {
+ system.GPU().ClearCdmaInstance(iter->second);
+ }
}
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index 523d96e3a..a507c4d0a 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -24,6 +24,9 @@ public:
void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override;
+
+private:
+ u32 next_id{};
};
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
index e61261f98..8a05f0668 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -59,7 +59,8 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(const std::vector<u8>& input) {
return NvResult::Success;
}
-NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
+NvResult nvhost_nvdec_common::Submit(DeviceFD fd, const std::vector<u8>& input,
+ std::vector<u8>& output) {
IoctlSubmit params{};
std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count);
@@ -93,7 +94,7 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count);
system.Memory().ReadBlock(object->addr + cmd_buffer.offset, cmdlist.data(),
cmdlist.size() * sizeof(u32));
- gpu.PushCommandBuffer(cmdlist);
+ gpu.PushCommandBuffer(fd_to_id[fd], cmdlist);
}
std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
// Some games expect command_buffers to be written back
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
index 351625c17..e28c54df6 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -104,13 +104,14 @@ protected:
/// Ioctl command implementations
NvResult SetNVMAPfd(const std::vector<u8>& input);
- NvResult Submit(const std::vector<u8>& input, std::vector<u8>& output);
+ NvResult Submit(DeviceFD fd, const std::vector<u8>& input, std::vector<u8>& output);
NvResult GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
NvResult GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
NvResult MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
NvResult UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
NvResult SetSubmitTimeout(const std::vector<u8>& input, std::vector<u8>& output);
+ std::unordered_map<DeviceFD, u32> fd_to_id{};
s32_le nvmap_fd{};
u32_le submit_timeout{};
std::shared_ptr<nvmap> nvmap_dev;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index eac4dd530..76b39806f 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -21,7 +21,10 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& i
case 0x0:
switch (command.cmd) {
case 0x1:
- return Submit(input, output);
+ if (!fd_to_id.contains(fd)) {
+ fd_to_id[fd] = next_id++;
+ }
+ return Submit(fd, input, output);
case 0x2:
return GetSyncpoint(input, output);
case 0x3:
@@ -65,7 +68,10 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& i
void nvhost_vic::OnOpen(DeviceFD fd) {}
void nvhost_vic::OnClose(DeviceFD fd) {
- system.GPU().ClearCdmaInstance();
+ const auto iter = fd_to_id.find(fd);
+ if (iter != fd_to_id.end()) {
+ system.GPU().ClearCdmaInstance(iter->second);
+ }
}
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index 6d7fda9d1..c9732c037 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -23,5 +23,8 @@ public:
void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override;
+
+private:
+ u32 next_id{};
};
} // namespace Service::Nvidia::Devices