summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/kernel/kernel.cpp42
-rw-r--r--src/core/hle/kernel/kernel.h11
-rw-r--r--src/core/hle/kernel/object.cpp1
-rw-r--r--src/core/hle/kernel/object.h1
-rw-r--r--src/core/hle/kernel/readable_event.cpp4
-rw-r--r--src/core/hle/kernel/readable_event.h2
-rw-r--r--src/core/hle/kernel/timer.cpp88
-rw-r--r--src/core/hle/kernel/timer.h90
-rw-r--r--src/core/hle/kernel/wait_object.h6
-rw-r--r--src/core/hle/service/am/applet_ae.cpp3
-rw-r--r--src/core/hle/service/audio/audin_u.cpp13
-rw-r--r--src/core/hle/service/audio/audrec_u.cpp6
-rw-r--r--src/core/hle/service/audio/audren_u.cpp10
-rw-r--r--src/core/hle/service/audio/audren_u.h2
-rw-r--r--src/core/hle/service/audio/hwopus.cpp117
-rw-r--r--src/core/hle/service/btdrv/btdrv.cpp147
-rw-r--r--src/core/hle/service/btm/btm.cpp152
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp32
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h10
-rw-r--r--src/core/hle/service/ncm/ncm.cpp8
-rw-r--r--src/core/hle/service/ns/ns.cpp34
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp34
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h26
-rw-r--r--src/core/hle/service/psc/psc.cpp17
-rw-r--r--src/core/hle/service/vi/vi.cpp10
-rw-r--r--src/video_core/dma_pusher.h2
-rw-r--r--src/video_core/rasterizer_interface.h5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp29
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h10
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h52
-rw-r--r--src/video_core/surface.h3
-rw-r--r--src/yuzu/debugger/wait_tree.cpp20
-rw-r--r--src/yuzu/debugger/wait_tree.h10
35 files changed, 484 insertions, 526 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 965c28787..f61bcd40d 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -140,8 +140,6 @@ add_library(core STATIC
140 hle/kernel/svc_wrap.h 140 hle/kernel/svc_wrap.h
141 hle/kernel/thread.cpp 141 hle/kernel/thread.cpp
142 hle/kernel/thread.h 142 hle/kernel/thread.h
143 hle/kernel/timer.cpp
144 hle/kernel/timer.h
145 hle/kernel/vm_manager.cpp 143 hle/kernel/vm_manager.cpp
146 hle/kernel/vm_manager.h 144 hle/kernel/vm_manager.h
147 hle/kernel/wait_object.cpp 145 hle/kernel/wait_object.cpp
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 67674cd47..7a524ce5a 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -18,7 +18,6 @@
18#include "core/hle/kernel/process.h" 18#include "core/hle/kernel/process.h"
19#include "core/hle/kernel/resource_limit.h" 19#include "core/hle/kernel/resource_limit.h"
20#include "core/hle/kernel/thread.h" 20#include "core/hle/kernel/thread.h"
21#include "core/hle/kernel/timer.h"
22#include "core/hle/lock.h" 21#include "core/hle/lock.h"
23#include "core/hle/result.h" 22#include "core/hle/result.h"
24 23
@@ -86,27 +85,12 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_
86 } 85 }
87} 86}
88 87
89/// The timer callback event, called when a timer is fired
90static void TimerCallback(u64 timer_handle, int cycles_late) {
91 const auto proper_handle = static_cast<Handle>(timer_handle);
92 const auto& system = Core::System::GetInstance();
93 SharedPtr<Timer> timer = system.Kernel().RetrieveTimerFromCallbackHandleTable(proper_handle);
94
95 if (timer == nullptr) {
96 LOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle);
97 return;
98 }
99
100 timer->Signal(cycles_late);
101}
102
103struct KernelCore::Impl { 88struct KernelCore::Impl {
104 void Initialize(KernelCore& kernel) { 89 void Initialize(KernelCore& kernel) {
105 Shutdown(); 90 Shutdown();
106 91
107 InitializeSystemResourceLimit(kernel); 92 InitializeSystemResourceLimit(kernel);
108 InitializeThreads(); 93 InitializeThreads();
109 InitializeTimers();
110 } 94 }
111 95
112 void Shutdown() { 96 void Shutdown() {
@@ -122,9 +106,6 @@ struct KernelCore::Impl {
122 thread_wakeup_callback_handle_table.Clear(); 106 thread_wakeup_callback_handle_table.Clear();
123 thread_wakeup_event_type = nullptr; 107 thread_wakeup_event_type = nullptr;
124 108
125 timer_callback_handle_table.Clear();
126 timer_callback_event_type = nullptr;
127
128 named_ports.clear(); 109 named_ports.clear();
129 } 110 }
130 111
@@ -146,11 +127,6 @@ struct KernelCore::Impl {
146 CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback); 127 CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
147 } 128 }
148 129
149 void InitializeTimers() {
150 timer_callback_handle_table.Clear();
151 timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback);
152 }
153
154 std::atomic<u32> next_object_id{0}; 130 std::atomic<u32> next_object_id{0};
155 std::atomic<u64> next_process_id{Process::ProcessIDMin}; 131 std::atomic<u64> next_process_id{Process::ProcessIDMin};
156 std::atomic<u64> next_thread_id{1}; 132 std::atomic<u64> next_thread_id{1};
@@ -161,12 +137,6 @@ struct KernelCore::Impl {
161 137
162 SharedPtr<ResourceLimit> system_resource_limit; 138 SharedPtr<ResourceLimit> system_resource_limit;
163 139
164 /// The event type of the generic timer callback event
165 CoreTiming::EventType* timer_callback_event_type = nullptr;
166 // TODO(yuriks): This can be removed if Timer objects are explicitly pooled in the future,
167 // allowing us to simply use a pool index or similar.
168 Kernel::HandleTable timer_callback_handle_table;
169
170 CoreTiming::EventType* thread_wakeup_event_type = nullptr; 140 CoreTiming::EventType* thread_wakeup_event_type = nullptr;
171 // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, 141 // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
172 // allowing us to simply use a pool index or similar. 142 // allowing us to simply use a pool index or similar.
@@ -198,10 +168,6 @@ SharedPtr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(Handle
198 return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle); 168 return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle);
199} 169}
200 170
201SharedPtr<Timer> KernelCore::RetrieveTimerFromCallbackHandleTable(Handle handle) const {
202 return impl->timer_callback_handle_table.Get<Timer>(handle);
203}
204
205void KernelCore::AppendNewProcess(SharedPtr<Process> process) { 171void KernelCore::AppendNewProcess(SharedPtr<Process> process) {
206 impl->process_list.push_back(std::move(process)); 172 impl->process_list.push_back(std::move(process));
207} 173}
@@ -247,18 +213,10 @@ u64 KernelCore::CreateNewProcessID() {
247 return impl->next_process_id++; 213 return impl->next_process_id++;
248} 214}
249 215
250ResultVal<Handle> KernelCore::CreateTimerCallbackHandle(const SharedPtr<Timer>& timer) {
251 return impl->timer_callback_handle_table.Create(timer);
252}
253
254CoreTiming::EventType* KernelCore::ThreadWakeupCallbackEventType() const { 216CoreTiming::EventType* KernelCore::ThreadWakeupCallbackEventType() const {
255 return impl->thread_wakeup_event_type; 217 return impl->thread_wakeup_event_type;
256} 218}
257 219
258CoreTiming::EventType* KernelCore::TimerCallbackEventType() const {
259 return impl->timer_callback_event_type;
260}
261
262Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() { 220Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() {
263 return impl->thread_wakeup_callback_handle_table; 221 return impl->thread_wakeup_callback_handle_table;
264} 222}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 58c9d108b..c643a6401 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -22,7 +22,6 @@ class HandleTable;
22class Process; 22class Process;
23class ResourceLimit; 23class ResourceLimit;
24class Thread; 24class Thread;
25class Timer;
26 25
27/// Represents a single instance of the kernel. 26/// Represents a single instance of the kernel.
28class KernelCore { 27class KernelCore {
@@ -51,9 +50,6 @@ public:
51 /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. 50 /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
52 SharedPtr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const; 51 SharedPtr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const;
53 52
54 /// Retrieves a shared pointer to a Timer instance within the timer callback handle table.
55 SharedPtr<Timer> RetrieveTimerFromCallbackHandleTable(Handle handle) const;
56
57 /// Adds the given shared pointer to an internal list of active processes. 53 /// Adds the given shared pointer to an internal list of active processes.
58 void AppendNewProcess(SharedPtr<Process> process); 54 void AppendNewProcess(SharedPtr<Process> process);
59 55
@@ -82,7 +78,6 @@ private:
82 friend class Object; 78 friend class Object;
83 friend class Process; 79 friend class Process;
84 friend class Thread; 80 friend class Thread;
85 friend class Timer;
86 81
87 /// Creates a new object ID, incrementing the internal object ID counter. 82 /// Creates a new object ID, incrementing the internal object ID counter.
88 u32 CreateNewObjectID(); 83 u32 CreateNewObjectID();
@@ -93,15 +88,9 @@ private:
93 /// Creates a new thread ID, incrementing the internal thread ID counter. 88 /// Creates a new thread ID, incrementing the internal thread ID counter.
94 u64 CreateNewThreadID(); 89 u64 CreateNewThreadID();
95 90
96 /// Creates a timer callback handle for the given timer.
97 ResultVal<Handle> CreateTimerCallbackHandle(const SharedPtr<Timer>& timer);
98
99 /// Retrieves the event type used for thread wakeup callbacks. 91 /// Retrieves the event type used for thread wakeup callbacks.
100 CoreTiming::EventType* ThreadWakeupCallbackEventType() const; 92 CoreTiming::EventType* ThreadWakeupCallbackEventType() const;
101 93
102 /// Retrieves the event type used for timer callbacks.
103 CoreTiming::EventType* TimerCallbackEventType() const;
104
105 /// Provides a reference to the thread wakeup callback handle table. 94 /// Provides a reference to the thread wakeup callback handle table.
106 Kernel::HandleTable& ThreadWakeupCallbackHandleTable(); 95 Kernel::HandleTable& ThreadWakeupCallbackHandleTable();
107 96
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp
index 806078638..8870463d0 100644
--- a/src/core/hle/kernel/object.cpp
+++ b/src/core/hle/kernel/object.cpp
@@ -16,7 +16,6 @@ bool Object::IsWaitable() const {
16 case HandleType::ReadableEvent: 16 case HandleType::ReadableEvent:
17 case HandleType::Thread: 17 case HandleType::Thread:
18 case HandleType::Process: 18 case HandleType::Process:
19 case HandleType::Timer:
20 case HandleType::ServerPort: 19 case HandleType::ServerPort:
21 case HandleType::ServerSession: 20 case HandleType::ServerSession:
22 return true; 21 return true;
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 1541b6e3c..4c2505908 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -25,7 +25,6 @@ enum class HandleType : u32 {
25 Thread, 25 Thread,
26 Process, 26 Process,
27 AddressArbiter, 27 AddressArbiter,
28 Timer,
29 ResourceLimit, 28 ResourceLimit,
30 ClientPort, 29 ClientPort,
31 ServerPort, 30 ServerPort,
diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp
index 6973e580c..0e5083f70 100644
--- a/src/core/hle/kernel/readable_event.cpp
+++ b/src/core/hle/kernel/readable_event.cpp
@@ -44,8 +44,4 @@ ResultCode ReadableEvent::Reset() {
44 return RESULT_SUCCESS; 44 return RESULT_SUCCESS;
45} 45}
46 46
47void ReadableEvent::WakeupAllWaitingThreads() {
48 WaitObject::WakeupAllWaitingThreads();
49}
50
51} // namespace Kernel 47} // namespace Kernel
diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h
index 80b3b0aba..77a9c362c 100644
--- a/src/core/hle/kernel/readable_event.h
+++ b/src/core/hle/kernel/readable_event.h
@@ -39,8 +39,6 @@ public:
39 bool ShouldWait(Thread* thread) const override; 39 bool ShouldWait(Thread* thread) const override;
40 void Acquire(Thread* thread) override; 40 void Acquire(Thread* thread) override;
41 41
42 void WakeupAllWaitingThreads() override;
43
44 /// Unconditionally clears the readable event's state. 42 /// Unconditionally clears the readable event's state.
45 void Clear(); 43 void Clear();
46 44
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
deleted file mode 100644
index 2c4f50e2b..000000000
--- a/src/core/hle/kernel/timer.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6#include "common/logging/log.h"
7#include "core/core.h"
8#include "core/core_timing.h"
9#include "core/core_timing_util.h"
10#include "core/hle/kernel/handle_table.h"
11#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/object.h"
13#include "core/hle/kernel/thread.h"
14#include "core/hle/kernel/timer.h"
15
16namespace Kernel {
17
18Timer::Timer(KernelCore& kernel) : WaitObject{kernel} {}
19Timer::~Timer() = default;
20
21SharedPtr<Timer> Timer::Create(KernelCore& kernel, ResetType reset_type, std::string name) {
22 SharedPtr<Timer> timer(new Timer(kernel));
23
24 timer->reset_type = reset_type;
25 timer->signaled = false;
26 timer->name = std::move(name);
27 timer->initial_delay = 0;
28 timer->interval_delay = 0;
29 timer->callback_handle = kernel.CreateTimerCallbackHandle(timer).Unwrap();
30
31 return timer;
32}
33
34bool Timer::ShouldWait(Thread* thread) const {
35 return !signaled;
36}
37
38void Timer::Acquire(Thread* thread) {
39 ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
40
41 if (reset_type == ResetType::OneShot)
42 signaled = false;
43}
44
45void Timer::Set(s64 initial, s64 interval) {
46 // Ensure we get rid of any previous scheduled event
47 Cancel();
48
49 initial_delay = initial;
50 interval_delay = interval;
51
52 if (initial == 0) {
53 // Immediately invoke the callback
54 Signal(0);
55 } else {
56 CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(initial), kernel.TimerCallbackEventType(),
57 callback_handle);
58 }
59}
60
61void Timer::Cancel() {
62 CoreTiming::UnscheduleEvent(kernel.TimerCallbackEventType(), callback_handle);
63}
64
65void Timer::Clear() {
66 signaled = false;
67}
68
69void Timer::WakeupAllWaitingThreads() {
70 WaitObject::WakeupAllWaitingThreads();
71}
72
73void Timer::Signal(int cycles_late) {
74 LOG_TRACE(Kernel, "Timer {} fired", GetObjectId());
75
76 signaled = true;
77
78 // Resume all waiting threads
79 WakeupAllWaitingThreads();
80
81 if (interval_delay != 0) {
82 // Reschedule the timer with the interval delay
83 CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(interval_delay) - cycles_late,
84 kernel.TimerCallbackEventType(), callback_handle);
85 }
86}
87
88} // namespace Kernel
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h
deleted file mode 100644
index 12915c1b1..000000000
--- a/src/core/hle/kernel/timer.h
+++ /dev/null
@@ -1,90 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8#include "core/hle/kernel/object.h"
9#include "core/hle/kernel/wait_object.h"
10
11namespace Kernel {
12
13class KernelCore;
14
15class Timer final : public WaitObject {
16public:
17 /**
18 * Creates a timer
19 * @param kernel The kernel instance to create the timer callback handle for.
20 * @param reset_type ResetType describing how to create the timer
21 * @param name Optional name of timer
22 * @return The created Timer
23 */
24 static SharedPtr<Timer> Create(KernelCore& kernel, ResetType reset_type,
25 std::string name = "Unknown");
26
27 std::string GetTypeName() const override {
28 return "Timer";
29 }
30 std::string GetName() const override {
31 return name;
32 }
33
34 static const HandleType HANDLE_TYPE = HandleType::Timer;
35 HandleType GetHandleType() const override {
36 return HANDLE_TYPE;
37 }
38
39 ResetType GetResetType() const {
40 return reset_type;
41 }
42
43 u64 GetInitialDelay() const {
44 return initial_delay;
45 }
46
47 u64 GetIntervalDelay() const {
48 return interval_delay;
49 }
50
51 bool ShouldWait(Thread* thread) const override;
52 void Acquire(Thread* thread) override;
53
54 void WakeupAllWaitingThreads() override;
55
56 /**
57 * Starts the timer, with the specified initial delay and interval.
58 * @param initial Delay until the timer is first fired
59 * @param interval Delay until the timer is fired after the first time
60 */
61 void Set(s64 initial, s64 interval);
62
63 void Cancel();
64 void Clear();
65
66 /**
67 * Signals the timer, waking up any waiting threads and rescheduling it
68 * for the next interval.
69 * This method should not be called from outside the timer callback handler,
70 * lest multiple callback events get scheduled.
71 */
72 void Signal(int cycles_late);
73
74private:
75 explicit Timer(KernelCore& kernel);
76 ~Timer() override;
77
78 ResetType reset_type; ///< The ResetType of this timer
79
80 u64 initial_delay; ///< The delay until the timer fires for the first time
81 u64 interval_delay; ///< The delay until the timer fires after the first time
82
83 bool signaled; ///< Whether the timer has been signaled or not
84 std::string name; ///< Name of timer (optional)
85
86 /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
87 Handle callback_handle;
88};
89
90} // namespace Kernel
diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h
index d70b67893..5987fb971 100644
--- a/src/core/hle/kernel/wait_object.h
+++ b/src/core/hle/kernel/wait_object.h
@@ -33,19 +33,19 @@ public:
33 * Add a thread to wait on this object 33 * Add a thread to wait on this object
34 * @param thread Pointer to thread to add 34 * @param thread Pointer to thread to add
35 */ 35 */
36 virtual void AddWaitingThread(SharedPtr<Thread> thread); 36 void AddWaitingThread(SharedPtr<Thread> thread);
37 37
38 /** 38 /**
39 * Removes a thread from waiting on this object (e.g. if it was resumed already) 39 * Removes a thread from waiting on this object (e.g. if it was resumed already)
40 * @param thread Pointer to thread to remove 40 * @param thread Pointer to thread to remove
41 */ 41 */
42 virtual void RemoveWaitingThread(Thread* thread); 42 void RemoveWaitingThread(Thread* thread);
43 43
44 /** 44 /**
45 * Wake up all threads waiting on this object that can be awoken, in priority order, 45 * Wake up all threads waiting on this object that can be awoken, in priority order,
46 * and set the synchronization result and output of the thread. 46 * and set the synchronization result and output of the thread.
47 */ 47 */
48 virtual void WakeupAllWaitingThreads(); 48 void WakeupAllWaitingThreads();
49 49
50 /** 50 /**
51 * Wakes up a single thread waiting on this object. 51 * Wakes up a single thread waiting on this object.
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp
index 41a573a91..b888f861d 100644
--- a/src/core/hle/service/am/applet_ae.cpp
+++ b/src/core/hle/service/am/applet_ae.cpp
@@ -249,7 +249,8 @@ AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
249 {300, nullptr, "OpenOverlayAppletProxy"}, 249 {300, nullptr, "OpenOverlayAppletProxy"},
250 {350, nullptr, "OpenSystemApplicationProxy"}, 250 {350, nullptr, "OpenSystemApplicationProxy"},
251 {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"}, 251 {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"},
252 {401, nullptr, "GetSystemAppletControllerForDebug"}, 252 {410, nullptr, "GetSystemAppletControllerForDebug"},
253 {1000, nullptr, "GetDebugFunctions"},
253 }; 254 };
254 // clang-format on 255 // clang-format on
255 256
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp
index 657010312..088410564 100644
--- a/src/core/hle/service/audio/audin_u.cpp
+++ b/src/core/hle/service/audio/audin_u.cpp
@@ -12,6 +12,7 @@ namespace Service::Audio {
12class IAudioIn final : public ServiceFramework<IAudioIn> { 12class IAudioIn final : public ServiceFramework<IAudioIn> {
13public: 13public:
14 IAudioIn() : ServiceFramework("IAudioIn") { 14 IAudioIn() : ServiceFramework("IAudioIn") {
15 // clang-format off
15 static const FunctionInfo functions[] = { 16 static const FunctionInfo functions[] = {
16 {0, nullptr, "GetAudioInState"}, 17 {0, nullptr, "GetAudioInState"},
17 {1, nullptr, "StartAudioIn"}, 18 {1, nullptr, "StartAudioIn"},
@@ -28,16 +29,24 @@ public:
28 {12, nullptr, "SetAudioInDeviceGain"}, 29 {12, nullptr, "SetAudioInDeviceGain"},
29 {13, nullptr, "GetAudioInDeviceGain"}, 30 {13, nullptr, "GetAudioInDeviceGain"},
30 }; 31 };
32 // clang-format on
33
31 RegisterHandlers(functions); 34 RegisterHandlers(functions);
32 } 35 }
33 ~IAudioIn() = default; 36 ~IAudioIn() = default;
34}; 37};
35 38
36AudInU::AudInU() : ServiceFramework("audin:u") { 39AudInU::AudInU() : ServiceFramework("audin:u") {
40 // clang-format off
37 static const FunctionInfo functions[] = { 41 static const FunctionInfo functions[] = {
38 {0, nullptr, "ListAudioIns"}, {1, nullptr, "OpenAudioIn"}, {2, nullptr, "Unknown"}, 42 {0, nullptr, "ListAudioIns"},
39 {3, nullptr, "OpenAudioInAuto"}, {4, nullptr, "ListAudioInsAuto"}, 43 {1, nullptr, "OpenAudioIn"},
44 {2, nullptr, "Unknown"},
45 {3, nullptr, "OpenAudioInAuto"},
46 {4, nullptr, "ListAudioInsAuto"},
40 }; 47 };
48 // clang-format on
49
41 RegisterHandlers(functions); 50 RegisterHandlers(functions);
42} 51}
43 52
diff --git a/src/core/hle/service/audio/audrec_u.cpp b/src/core/hle/service/audio/audrec_u.cpp
index 34974afa9..6956a2e64 100644
--- a/src/core/hle/service/audio/audrec_u.cpp
+++ b/src/core/hle/service/audio/audrec_u.cpp
@@ -12,6 +12,7 @@ namespace Service::Audio {
12class IFinalOutputRecorder final : public ServiceFramework<IFinalOutputRecorder> { 12class IFinalOutputRecorder final : public ServiceFramework<IFinalOutputRecorder> {
13public: 13public:
14 IFinalOutputRecorder() : ServiceFramework("IFinalOutputRecorder") { 14 IFinalOutputRecorder() : ServiceFramework("IFinalOutputRecorder") {
15 // clang-format off
15 static const FunctionInfo functions[] = { 16 static const FunctionInfo functions[] = {
16 {0, nullptr, "GetFinalOutputRecorderState"}, 17 {0, nullptr, "GetFinalOutputRecorderState"},
17 {1, nullptr, "StartFinalOutputRecorder"}, 18 {1, nullptr, "StartFinalOutputRecorder"},
@@ -20,10 +21,13 @@ public:
20 {4, nullptr, "RegisterBufferEvent"}, 21 {4, nullptr, "RegisterBufferEvent"},
21 {5, nullptr, "GetReleasedFinalOutputRecorderBuffer"}, 22 {5, nullptr, "GetReleasedFinalOutputRecorderBuffer"},
22 {6, nullptr, "ContainsFinalOutputRecorderBuffer"}, 23 {6, nullptr, "ContainsFinalOutputRecorderBuffer"},
23 {7, nullptr, "Unknown"}, 24 {7, nullptr, "GetFinalOutputRecorderBufferEndTime"},
24 {8, nullptr, "AppendFinalOutputRecorderBufferAuto"}, 25 {8, nullptr, "AppendFinalOutputRecorderBufferAuto"},
25 {9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"}, 26 {9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"},
27 {10, nullptr, "FlushFinalOutputRecorderBuffers"},
26 }; 28 };
29 // clang-format on
30
27 RegisterHandlers(functions); 31 RegisterHandlers(functions);
28 } 32 }
29 ~IFinalOutputRecorder() = default; 33 ~IFinalOutputRecorder() = default;
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 945259c7d..76cc48254 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -229,14 +229,16 @@ private:
229}; // namespace Audio 229}; // namespace Audio
230 230
231AudRenU::AudRenU() : ServiceFramework("audren:u") { 231AudRenU::AudRenU() : ServiceFramework("audren:u") {
232 // clang-format off
232 static const FunctionInfo functions[] = { 233 static const FunctionInfo functions[] = {
233 {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"}, 234 {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"},
234 {1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"}, 235 {1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"},
235 {2, &AudRenU::GetAudioDevice, "GetAudioDevice"}, 236 {2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"},
236 {3, nullptr, "OpenAudioRendererAuto"}, 237 {3, nullptr, "OpenAudioRendererAuto"},
237 {4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, 238 {4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"},
238 "GetAudioDeviceServiceWithRevisionInfo"},
239 }; 239 };
240 // clang-format on
241
240 RegisterHandlers(functions); 242 RegisterHandlers(functions);
241} 243}
242 244
@@ -313,7 +315,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
313 LOG_DEBUG(Service_Audio, "buffer_size=0x{:X}", output_sz); 315 LOG_DEBUG(Service_Audio, "buffer_size=0x{:X}", output_sz);
314} 316}
315 317
316void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { 318void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) {
317 LOG_DEBUG(Service_Audio, "called"); 319 LOG_DEBUG(Service_Audio, "called");
318 320
319 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 321 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h
index c6bc3a90a..3d63388fb 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -20,7 +20,7 @@ public:
20private: 20private:
21 void OpenAudioRenderer(Kernel::HLERequestContext& ctx); 21 void OpenAudioRenderer(Kernel::HLERequestContext& ctx);
22 void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx); 22 void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx);
23 void GetAudioDevice(Kernel::HLERequestContext& ctx); 23 void GetAudioDeviceService(Kernel::HLERequestContext& ctx);
24 void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx); 24 void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx);
25 25
26 enum class AudioFeatures : u32 { 26 enum class AudioFeatures : u32 {
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index a850cadc8..11eba4a12 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -5,7 +5,6 @@
5#include <chrono> 5#include <chrono>
6#include <cstring> 6#include <cstring>
7#include <memory> 7#include <memory>
8#include <optional>
9#include <vector> 8#include <vector>
10 9
11#include <opus.h> 10#include <opus.h>
@@ -30,48 +29,66 @@ public:
30 u32 channel_count) 29 u32 channel_count)
31 : ServiceFramework("IHardwareOpusDecoderManager"), decoder(std::move(decoder)), 30 : ServiceFramework("IHardwareOpusDecoderManager"), decoder(std::move(decoder)),
32 sample_rate(sample_rate), channel_count(channel_count) { 31 sample_rate(sample_rate), channel_count(channel_count) {
32 // clang-format off
33 static const FunctionInfo functions[] = { 33 static const FunctionInfo functions[] = {
34 {0, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"}, 34 {0, &IHardwareOpusDecoderManager::DecodeInterleavedOld, "DecodeInterleavedOld"},
35 {1, nullptr, "SetContext"}, 35 {1, nullptr, "SetContext"},
36 {2, nullptr, "DecodeInterleavedForMultiStream"}, 36 {2, nullptr, "DecodeInterleavedForMultiStreamOld"},
37 {3, nullptr, "SetContextForMultiStream"}, 37 {3, nullptr, "SetContextForMultiStream"},
38 {4, &IHardwareOpusDecoderManager::DecodeInterleavedWithPerformance, 38 {4, &IHardwareOpusDecoderManager::DecodeInterleavedWithPerfOld, "DecodeInterleavedWithPerfOld"},
39 "DecodeInterleavedWithPerformance"}, 39 {5, nullptr, "DecodeInterleavedForMultiStreamWithPerfOld"},
40 {5, nullptr, "Unknown5"}, 40 {6, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"},
41 {6, nullptr, "Unknown6"}, 41 {7, nullptr, "DecodeInterleavedForMultiStream"},
42 {7, nullptr, "Unknown7"},
43 }; 42 };
43 // clang-format on
44
44 RegisterHandlers(functions); 45 RegisterHandlers(functions);
45 } 46 }
46 47
47private: 48private:
48 void DecodeInterleaved(Kernel::HLERequestContext& ctx) { 49 /// Describes extra behavior that may be asked of the decoding context.
50 enum class ExtraBehavior {
51 /// No extra behavior.
52 None,
53
54 /// Resets the decoder context back to a freshly initialized state.
55 ResetContext,
56 };
57
58 void DecodeInterleavedOld(Kernel::HLERequestContext& ctx) {
49 LOG_DEBUG(Audio, "called"); 59 LOG_DEBUG(Audio, "called");
50 60
51 u32 consumed = 0; 61 DecodeInterleavedHelper(ctx, nullptr, ExtraBehavior::None);
52 u32 sample_count = 0;
53 std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16));
54 if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples)) {
55 LOG_ERROR(Audio, "Failed to decode opus data");
56 IPC::ResponseBuilder rb{ctx, 2};
57 // TODO(ogniK): Use correct error code
58 rb.Push(ResultCode(-1));
59 return;
60 }
61 IPC::ResponseBuilder rb{ctx, 4};
62 rb.Push(RESULT_SUCCESS);
63 rb.Push<u32>(consumed);
64 rb.Push<u32>(sample_count);
65 ctx.WriteBuffer(samples.data(), samples.size() * sizeof(s16));
66 } 62 }
67 63
68 void DecodeInterleavedWithPerformance(Kernel::HLERequestContext& ctx) { 64 void DecodeInterleavedWithPerfOld(Kernel::HLERequestContext& ctx) {
65 LOG_DEBUG(Audio, "called");
66
67 u64 performance = 0;
68 DecodeInterleavedHelper(ctx, &performance, ExtraBehavior::None);
69 }
70
71 void DecodeInterleaved(Kernel::HLERequestContext& ctx) {
69 LOG_DEBUG(Audio, "called"); 72 LOG_DEBUG(Audio, "called");
70 73
74 IPC::RequestParser rp{ctx};
75 const auto extra_behavior =
76 rp.Pop<bool>() ? ExtraBehavior::ResetContext : ExtraBehavior::None;
77
78 u64 performance = 0;
79 DecodeInterleavedHelper(ctx, &performance, extra_behavior);
80 }
81
82 void DecodeInterleavedHelper(Kernel::HLERequestContext& ctx, u64* performance,
83 ExtraBehavior extra_behavior) {
71 u32 consumed = 0; 84 u32 consumed = 0;
72 u32 sample_count = 0; 85 u32 sample_count = 0;
73 u64 performance = 0;
74 std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16)); 86 std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16));
87
88 if (extra_behavior == ExtraBehavior::ResetContext) {
89 ResetDecoderContext();
90 }
91
75 if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples, 92 if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples,
76 performance)) { 93 performance)) {
77 LOG_ERROR(Audio, "Failed to decode opus data"); 94 LOG_ERROR(Audio, "Failed to decode opus data");
@@ -80,25 +97,28 @@ private:
80 rb.Push(ResultCode(-1)); 97 rb.Push(ResultCode(-1));
81 return; 98 return;
82 } 99 }
83 IPC::ResponseBuilder rb{ctx, 6}; 100
101 const u32 param_size = performance != nullptr ? 6 : 4;
102 IPC::ResponseBuilder rb{ctx, param_size};
84 rb.Push(RESULT_SUCCESS); 103 rb.Push(RESULT_SUCCESS);
85 rb.Push<u32>(consumed); 104 rb.Push<u32>(consumed);
86 rb.Push<u32>(sample_count); 105 rb.Push<u32>(sample_count);
87 rb.Push<u64>(performance); 106 if (performance) {
107 rb.Push<u64>(*performance);
108 }
88 ctx.WriteBuffer(samples.data(), samples.size() * sizeof(s16)); 109 ctx.WriteBuffer(samples.data(), samples.size() * sizeof(s16));
89 } 110 }
90 111
91 bool Decoder_DecodeInterleaved( 112 bool Decoder_DecodeInterleaved(u32& consumed, u32& sample_count, const std::vector<u8>& input,
92 u32& consumed, u32& sample_count, const std::vector<u8>& input, 113 std::vector<opus_int16>& output, u64* out_performance_time) {
93 std::vector<opus_int16>& output,
94 std::optional<std::reference_wrapper<u64>> performance_time = std::nullopt) {
95 const auto start_time = std::chrono::high_resolution_clock::now(); 114 const auto start_time = std::chrono::high_resolution_clock::now();
96 std::size_t raw_output_sz = output.size() * sizeof(opus_int16); 115 const std::size_t raw_output_sz = output.size() * sizeof(opus_int16);
97 if (sizeof(OpusHeader) > input.size()) { 116 if (sizeof(OpusHeader) > input.size()) {
98 LOG_ERROR(Audio, "Input is smaller than the header size, header_sz={}, input_sz={}", 117 LOG_ERROR(Audio, "Input is smaller than the header size, header_sz={}, input_sz={}",
99 sizeof(OpusHeader), input.size()); 118 sizeof(OpusHeader), input.size());
100 return false; 119 return false;
101 } 120 }
121
102 OpusHeader hdr{}; 122 OpusHeader hdr{};
103 std::memcpy(&hdr, input.data(), sizeof(OpusHeader)); 123 std::memcpy(&hdr, input.data(), sizeof(OpusHeader));
104 if (sizeof(OpusHeader) + static_cast<u32>(hdr.sz) > input.size()) { 124 if (sizeof(OpusHeader) + static_cast<u32>(hdr.sz) > input.size()) {
@@ -106,8 +126,9 @@ private:
106 sizeof(OpusHeader) + static_cast<u32>(hdr.sz), input.size()); 126 sizeof(OpusHeader) + static_cast<u32>(hdr.sz), input.size());
107 return false; 127 return false;
108 } 128 }
109 auto frame = input.data() + sizeof(OpusHeader); 129
110 auto decoded_sample_count = opus_packet_get_nb_samples( 130 const auto frame = input.data() + sizeof(OpusHeader);
131 const auto decoded_sample_count = opus_packet_get_nb_samples(
111 frame, static_cast<opus_int32>(input.size() - sizeof(OpusHeader)), 132 frame, static_cast<opus_int32>(input.size() - sizeof(OpusHeader)),
112 static_cast<opus_int32>(sample_rate)); 133 static_cast<opus_int32>(sample_rate));
113 if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz) { 134 if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz) {
@@ -117,8 +138,9 @@ private:
117 decoded_sample_count * channel_count * sizeof(u16), raw_output_sz); 138 decoded_sample_count * channel_count * sizeof(u16), raw_output_sz);
118 return false; 139 return false;
119 } 140 }
141
120 const int frame_size = (static_cast<int>(raw_output_sz / sizeof(s16) / channel_count)); 142 const int frame_size = (static_cast<int>(raw_output_sz / sizeof(s16) / channel_count));
121 auto out_sample_count = 143 const auto out_sample_count =
122 opus_decode(decoder.get(), frame, hdr.sz, output.data(), frame_size, 0); 144 opus_decode(decoder.get(), frame, hdr.sz, output.data(), frame_size, 0);
123 if (out_sample_count < 0) { 145 if (out_sample_count < 0) {
124 LOG_ERROR(Audio, 146 LOG_ERROR(Audio,
@@ -127,16 +149,24 @@ private:
127 out_sample_count, frame_size, static_cast<u32>(hdr.sz)); 149 out_sample_count, frame_size, static_cast<u32>(hdr.sz));
128 return false; 150 return false;
129 } 151 }
152
130 const auto end_time = std::chrono::high_resolution_clock::now() - start_time; 153 const auto end_time = std::chrono::high_resolution_clock::now() - start_time;
131 sample_count = out_sample_count; 154 sample_count = out_sample_count;
132 consumed = static_cast<u32>(sizeof(OpusHeader) + hdr.sz); 155 consumed = static_cast<u32>(sizeof(OpusHeader) + hdr.sz);
133 if (performance_time.has_value()) { 156 if (out_performance_time != nullptr) {
134 performance_time->get() = 157 *out_performance_time =
135 std::chrono::duration_cast<std::chrono::milliseconds>(end_time).count(); 158 std::chrono::duration_cast<std::chrono::milliseconds>(end_time).count();
136 } 159 }
160
137 return true; 161 return true;
138 } 162 }
139 163
164 void ResetDecoderContext() {
165 ASSERT(decoder != nullptr);
166
167 opus_decoder_ctl(decoder.get(), OPUS_RESET_STATE);
168 }
169
140 struct OpusHeader { 170 struct OpusHeader {
141 u32_be sz; // Needs to be BE for some odd reason 171 u32_be sz; // Needs to be BE for some odd reason
142 INSERT_PADDING_WORDS(1); 172 INSERT_PADDING_WORDS(1);
@@ -157,6 +187,7 @@ void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
157 IPC::RequestParser rp{ctx}; 187 IPC::RequestParser rp{ctx};
158 const auto sample_rate = rp.Pop<u32>(); 188 const auto sample_rate = rp.Pop<u32>();
159 const auto channel_count = rp.Pop<u32>(); 189 const auto channel_count = rp.Pop<u32>();
190
160 LOG_DEBUG(Audio, "called with sample_rate={}, channel_count={}", sample_rate, channel_count); 191 LOG_DEBUG(Audio, "called with sample_rate={}, channel_count={}", sample_rate, channel_count);
161 192
162 ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 || 193 ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
@@ -174,9 +205,10 @@ void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
174 205
175void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) { 206void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
176 IPC::RequestParser rp{ctx}; 207 IPC::RequestParser rp{ctx};
177 auto sample_rate = rp.Pop<u32>(); 208 const auto sample_rate = rp.Pop<u32>();
178 auto channel_count = rp.Pop<u32>(); 209 const auto channel_count = rp.Pop<u32>();
179 auto buffer_sz = rp.Pop<u32>(); 210 const auto buffer_sz = rp.Pop<u32>();
211
180 LOG_DEBUG(Audio, "called sample_rate={}, channel_count={}, buffer_size={}", sample_rate, 212 LOG_DEBUG(Audio, "called sample_rate={}, channel_count={}, buffer_size={}", sample_rate,
181 channel_count, buffer_sz); 213 channel_count, buffer_sz);
182 214
@@ -185,8 +217,9 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
185 "Invalid sample rate"); 217 "Invalid sample rate");
186 ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); 218 ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
187 219
188 std::size_t worker_sz = WorkerBufferSize(channel_count); 220 const std::size_t worker_sz = WorkerBufferSize(channel_count);
189 ASSERT_MSG(buffer_sz >= worker_sz, "Worker buffer too large"); 221 ASSERT_MSG(buffer_sz >= worker_sz, "Worker buffer too large");
222
190 std::unique_ptr<OpusDecoder, OpusDeleter> decoder{ 223 std::unique_ptr<OpusDecoder, OpusDeleter> decoder{
191 static_cast<OpusDecoder*>(operator new(worker_sz))}; 224 static_cast<OpusDecoder*>(operator new(worker_sz))};
192 if (const int err = opus_decoder_init(decoder.get(), sample_rate, channel_count)) { 225 if (const int err = opus_decoder_init(decoder.get(), sample_rate, channel_count)) {
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
index 5704ca0ab..59ef603e1 100644
--- a/src/core/hle/service/btdrv/btdrv.cpp
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -19,16 +19,16 @@ public:
19 explicit Bt() : ServiceFramework{"bt"} { 19 explicit Bt() : ServiceFramework{"bt"} {
20 // clang-format off 20 // clang-format off
21 static const FunctionInfo functions[] = { 21 static const FunctionInfo functions[] = {
22 {0, nullptr, "Unknown0"}, 22 {0, nullptr, "LeClientReadCharacteristic"},
23 {1, nullptr, "Unknown1"}, 23 {1, nullptr, "LeClientReadDescriptor"},
24 {2, nullptr, "Unknown2"}, 24 {2, nullptr, "LeClientWriteCharacteristic"},
25 {3, nullptr, "Unknown3"}, 25 {3, nullptr, "LeClientWriteDescriptor"},
26 {4, nullptr, "Unknown4"}, 26 {4, nullptr, "LeClientRegisterNotification"},
27 {5, nullptr, "Unknown5"}, 27 {5, nullptr, "LeClientDeregisterNotification"},
28 {6, nullptr, "Unknown6"}, 28 {6, nullptr, "SetLeResponse"},
29 {7, nullptr, "Unknown7"}, 29 {7, nullptr, "LeSendIndication"},
30 {8, nullptr, "Unknown8"}, 30 {8, nullptr, "GetLeEventInfo"},
31 {9, &Bt::RegisterEvent, "RegisterEvent"}, 31 {9, &Bt::RegisterBleEvent, "RegisterBleEvent"},
32 }; 32 };
33 // clang-format on 33 // clang-format on
34 RegisterHandlers(functions); 34 RegisterHandlers(functions);
@@ -39,7 +39,7 @@ public:
39 } 39 }
40 40
41private: 41private:
42 void RegisterEvent(Kernel::HLERequestContext& ctx) { 42 void RegisterBleEvent(Kernel::HLERequestContext& ctx) {
43 LOG_WARNING(Service_BTM, "(STUBBED) called"); 43 LOG_WARNING(Service_BTM, "(STUBBED) called");
44 44
45 IPC::ResponseBuilder rb{ctx, 2, 1}; 45 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -55,11 +55,11 @@ public:
55 explicit BtDrv() : ServiceFramework{"btdrv"} { 55 explicit BtDrv() : ServiceFramework{"btdrv"} {
56 // clang-format off 56 // clang-format off
57 static const FunctionInfo functions[] = { 57 static const FunctionInfo functions[] = {
58 {0, nullptr, "Unknown"}, 58 {0, nullptr, "InitializeBluetoothDriver"},
59 {1, nullptr, "Init"}, 59 {1, nullptr, "InitializeBluetooth"},
60 {2, nullptr, "Enable"}, 60 {2, nullptr, "EnableBluetooth"},
61 {3, nullptr, "Disable"}, 61 {3, nullptr, "DisableBluetooth"},
62 {4, nullptr, "CleanupAndShutdown"}, 62 {4, nullptr, "CleanupBluetooth"},
63 {5, nullptr, "GetAdapterProperties"}, 63 {5, nullptr, "GetAdapterProperties"},
64 {6, nullptr, "GetAdapterProperty"}, 64 {6, nullptr, "GetAdapterProperty"},
65 {7, nullptr, "SetAdapterProperty"}, 65 {7, nullptr, "SetAdapterProperty"},
@@ -70,36 +70,91 @@ public:
70 {12, nullptr, "CancelBond"}, 70 {12, nullptr, "CancelBond"},
71 {13, nullptr, "PinReply"}, 71 {13, nullptr, "PinReply"},
72 {14, nullptr, "SspReply"}, 72 {14, nullptr, "SspReply"},
73 {15, nullptr, "Unknown2"}, 73 {15, nullptr, "GetEventInfo"},
74 {16, nullptr, "InitInterfaces"}, 74 {16, nullptr, "InitializeHid"},
75 {17, nullptr, "HidHostInterface_Connect"}, 75 {17, nullptr, "HidConnect"},
76 {18, nullptr, "HidHostInterface_Disconnect"}, 76 {18, nullptr, "HidDisconnect"},
77 {19, nullptr, "HidHostInterface_SendData"}, 77 {19, nullptr, "HidSendData"},
78 {20, nullptr, "HidHostInterface_SendData2"}, 78 {20, nullptr, "HidSendData2"},
79 {21, nullptr, "HidHostInterface_SetReport"}, 79 {21, nullptr, "HidSetReport"},
80 {22, nullptr, "HidHostInterface_GetReport"}, 80 {22, nullptr, "HidGetReport"},
81 {23, nullptr, "HidHostInterface_WakeController"}, 81 {23, nullptr, "HidWakeController"},
82 {24, nullptr, "HidHostInterface_AddPairedDevice"}, 82 {24, nullptr, "HidAddPairedDevice"},
83 {25, nullptr, "HidHostInterface_GetPairedDevice"}, 83 {25, nullptr, "HidGetPairedDevice"},
84 {26, nullptr, "HidHostInterface_CleanupAndShutdown"}, 84 {26, nullptr, "CleanupHid"},
85 {27, nullptr, "Unknown3"}, 85 {27, nullptr, "HidGetEventInfo"},
86 {28, nullptr, "ExtInterface_SetTSI"}, 86 {28, nullptr, "ExtSetTsi"},
87 {29, nullptr, "ExtInterface_SetBurstMode"}, 87 {29, nullptr, "ExtSetBurstMode"},
88 {30, nullptr, "ExtInterface_SetZeroRetran"}, 88 {30, nullptr, "ExtSetZeroRetran"},
89 {31, nullptr, "ExtInterface_SetMcMode"}, 89 {31, nullptr, "ExtSetMcMode"},
90 {32, nullptr, "ExtInterface_StartLlrMode"}, 90 {32, nullptr, "ExtStartLlrMode"},
91 {33, nullptr, "ExtInterface_ExitLlrMode"}, 91 {33, nullptr, "ExtExitLlrMode"},
92 {34, nullptr, "ExtInterface_SetRadio"}, 92 {34, nullptr, "ExtSetRadio"},
93 {35, nullptr, "ExtInterface_SetVisibility"}, 93 {35, nullptr, "ExtSetVisibility"},
94 {36, nullptr, "Unknown4"}, 94 {36, nullptr, "ExtSetTbfcScan"},
95 {37, nullptr, "Unknown5"}, 95 {37, nullptr, "RegisterHidReportEvent"},
96 {38, nullptr, "HidHostInterface_GetLatestPlr"}, 96 {38, nullptr, "HidGetReportEventInfo"},
97 {39, nullptr, "ExtInterface_GetPendingConnections"}, 97 {39, nullptr, "GetLatestPlr"},
98 {40, nullptr, "HidHostInterface_GetChannelMap"}, 98 {40, nullptr, "ExtGetPendingConnections"},
99 {41, nullptr, "SetIsBluetoothBoostEnabled"}, 99 {41, nullptr, "GetChannelMap"},
100 {42, nullptr, "GetIsBluetoothBoostEnabled"}, 100 {42, nullptr, "EnableBluetoothBoostSetting"},
101 {43, nullptr, "SetIsBluetoothAfhEnabled"}, 101 {43, nullptr, "IsBluetoothBoostSettingEnabled"},
102 {44, nullptr, "GetIsBluetoothAfhEnabled"}, 102 {44, nullptr, "EnableBluetoothAfhSetting"},
103 {45, nullptr, "IsBluetoothAfhSettingEnabled"},
104 {46, nullptr, "InitializeBluetoothLe"},
105 {47, nullptr, "EnableBluetoothLe"},
106 {48, nullptr, "DisableBluetoothLe"},
107 {49, nullptr, "CleanupBluetoothLe"},
108 {50, nullptr, "SetLeVisibility"},
109 {51, nullptr, "SetLeConnectionParameter"},
110 {52, nullptr, "SetLeDefaultConnectionParameter"},
111 {53, nullptr, "SetLeAdvertiseData"},
112 {54, nullptr, "SetLeAdvertiseParameter"},
113 {55, nullptr, "StartLeScan"},
114 {56, nullptr, "StopLeScan"},
115 {57, nullptr, "AddLeScanFilterCondition"},
116 {58, nullptr, "DeleteLeScanFilterCondition"},
117 {59, nullptr, "DeleteLeScanFilter"},
118 {60, nullptr, "ClearLeScanFilters"},
119 {61, nullptr, "EnableLeScanFilter"},
120 {62, nullptr, "RegisterLeClient"},
121 {63, nullptr, "UnregisterLeClient"},
122 {64, nullptr, "UnregisterLeClientAll"},
123 {65, nullptr, "LeClientConnect"},
124 {66, nullptr, "LeClientCancelConnection"},
125 {67, nullptr, "LeClientDisconnect"},
126 {68, nullptr, "LeClientGetAttributes"},
127 {69, nullptr, "LeClientDiscoverService"},
128 {70, nullptr, "LeClientConfigureMtu"},
129 {71, nullptr, "RegisterLeServer"},
130 {72, nullptr, "UnregisterLeServer"},
131 {73, nullptr, "LeServerConnect"},
132 {74, nullptr, "LeServerDisconnect"},
133 {75, nullptr, "CreateLeService"},
134 {76, nullptr, "StartLeService"},
135 {77, nullptr, "AddLeCharacteristic"},
136 {78, nullptr, "AddLeDescriptor"},
137 {79, nullptr, "GetLeCoreEventInfo"},
138 {80, nullptr, "LeGetFirstCharacteristic"},
139 {81, nullptr, "LeGetNextCharacteristic"},
140 {82, nullptr, "LeGetFirstDescriptor"},
141 {83, nullptr, "LeGetNextDescriptor"},
142 {84, nullptr, "RegisterLeCoreDataPath"},
143 {85, nullptr, "UnregisterLeCoreDataPath"},
144 {86, nullptr, "RegisterLeHidDataPath"},
145 {87, nullptr, "UnregisterLeHidDataPath"},
146 {88, nullptr, "RegisterLeDataPath"},
147 {89, nullptr, "UnregisterLeDataPath"},
148 {90, nullptr, "LeClientReadCharacteristic"},
149 {91, nullptr, "LeClientReadDescriptor"},
150 {92, nullptr, "LeClientWriteCharacteristic"},
151 {93, nullptr, "LeClientWriteDescriptor"},
152 {94, nullptr, "LeClientRegisterNotification"},
153 {95, nullptr, "LeClientDeregisterNotification"},
154 {96, nullptr, "GetLeHidEventInfo"},
155 {97, nullptr, "RegisterBleHidEvent"},
156 {98, nullptr, "SetLeScanParameter"},
157 {256, nullptr, "GetIsManufacturingMode"}
103 }; 158 };
104 // clang-format on 159 // clang-format on
105 160
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index ef7398a23..4f15c3f19 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -20,38 +20,38 @@ public:
20 explicit IBtmUserCore() : ServiceFramework{"IBtmUserCore"} { 20 explicit IBtmUserCore() : ServiceFramework{"IBtmUserCore"} {
21 // clang-format off 21 // clang-format off
22 static const FunctionInfo functions[] = { 22 static const FunctionInfo functions[] = {
23 {0, &IBtmUserCore::GetScanEvent, "GetScanEvent"}, 23 {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"},
24 {1, nullptr, "Unknown1"}, 24 {1, nullptr, "GetBleScanFilterParameter"},
25 {2, nullptr, "Unknown2"}, 25 {2, nullptr, "GetBleScanFilterParameter2"},
26 {3, nullptr, "Unknown3"}, 26 {3, nullptr, "StartBleScanForGeneral"},
27 {4, nullptr, "Unknown4"}, 27 {4, nullptr, "StopBleScanForGeneral"},
28 {5, nullptr, "Unknown5"}, 28 {5, nullptr, "GetBleScanResultsForGeneral"},
29 {6, nullptr, "Unknown6"}, 29 {6, nullptr, "StartBleScanForPaired"},
30 {7, nullptr, "Unknown7"}, 30 {7, nullptr, "StopBleScanForPaired"},
31 {8, nullptr, "Unknown8"}, 31 {8, nullptr, "StartBleScanForSmartDevice"},
32 {9, nullptr, "Unknown9"}, 32 {9, nullptr, "StopBleScanForSmartDevice"},
33 {10, nullptr, "Unknown10"}, 33 {10, nullptr, "GetBleScanResultsForSmartDevice"},
34 {17, &IBtmUserCore::GetConnectionEvent, "GetConnectionEvent"}, 34 {17, &IBtmUserCore::AcquireBleConnectionEvent, "AcquireBleConnectionEvent"},
35 {18, nullptr, "Unknown18"}, 35 {18, nullptr, "BleConnect"},
36 {19, nullptr, "Unknown19"}, 36 {19, nullptr, "BleDisconnect"},
37 {20, nullptr, "Unknown20"}, 37 {20, nullptr, "BleGetConnectionState"},
38 {21, nullptr, "Unknown21"}, 38 {21, nullptr, "AcquireBlePairingEvent"},
39 {22, nullptr, "Unknown22"}, 39 {22, nullptr, "BlePairDevice"},
40 {23, nullptr, "Unknown23"}, 40 {23, nullptr, "BleUnPairDevice"},
41 {24, nullptr, "Unknown24"}, 41 {24, nullptr, "BleUnPairDevice2"},
42 {25, nullptr, "Unknown25"}, 42 {25, nullptr, "BleGetPairedDevices"},
43 {26, &IBtmUserCore::GetDiscoveryEvent, "AcquireBleServiceDiscoveryEventImpl"}, 43 {26, &IBtmUserCore::AcquireBleServiceDiscoveryEvent, "AcquireBleServiceDiscoveryEvent"},
44 {27, nullptr, "Unknown27"}, 44 {27, nullptr, "GetGattServices"},
45 {28, nullptr, "Unknown28"}, 45 {28, nullptr, "GetGattService"},
46 {29, nullptr, "Unknown29"}, 46 {29, nullptr, "GetGattIncludedServices"},
47 {30, nullptr, "Unknown30"}, 47 {30, nullptr, "GetBelongingGattService"},
48 {31, nullptr, "Unknown31"}, 48 {31, nullptr, "GetGattCharacteristics"},
49 {32, nullptr, "Unknown32"}, 49 {32, nullptr, "GetGattDescriptors"},
50 {33, &IBtmUserCore::GetConfigEvent, "GetConfigEvent"}, 50 {33, &IBtmUserCore::AcquireBleMtuConfigEvent, "AcquireBleMtuConfigEvent"},
51 {34, nullptr, "Unknown34"}, 51 {34, nullptr, "ConfigureBleMtu"},
52 {35, nullptr, "Unknown35"}, 52 {35, nullptr, "GetBleMtu"},
53 {36, nullptr, "Unknown36"}, 53 {36, nullptr, "RegisterBleGattDataPath"},
54 {37, nullptr, "Unknown37"}, 54 {37, nullptr, "UnregisterBleGattDataPath"},
55 }; 55 };
56 // clang-format on 56 // clang-format on
57 RegisterHandlers(functions); 57 RegisterHandlers(functions);
@@ -68,7 +68,7 @@ public:
68 } 68 }
69 69
70private: 70private:
71 void GetScanEvent(Kernel::HLERequestContext& ctx) { 71 void AcquireBleScanEvent(Kernel::HLERequestContext& ctx) {
72 LOG_WARNING(Service_BTM, "(STUBBED) called"); 72 LOG_WARNING(Service_BTM, "(STUBBED) called");
73 73
74 IPC::ResponseBuilder rb{ctx, 2, 1}; 74 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -76,7 +76,7 @@ private:
76 rb.PushCopyObjects(scan_event.readable); 76 rb.PushCopyObjects(scan_event.readable);
77 } 77 }
78 78
79 void GetConnectionEvent(Kernel::HLERequestContext& ctx) { 79 void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) {
80 LOG_WARNING(Service_BTM, "(STUBBED) called"); 80 LOG_WARNING(Service_BTM, "(STUBBED) called");
81 81
82 IPC::ResponseBuilder rb{ctx, 2, 1}; 82 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -84,7 +84,7 @@ private:
84 rb.PushCopyObjects(connection_event.readable); 84 rb.PushCopyObjects(connection_event.readable);
85 } 85 }
86 86
87 void GetDiscoveryEvent(Kernel::HLERequestContext& ctx) { 87 void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) {
88 LOG_WARNING(Service_BTM, "(STUBBED) called"); 88 LOG_WARNING(Service_BTM, "(STUBBED) called");
89 89
90 IPC::ResponseBuilder rb{ctx, 2, 1}; 90 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -92,7 +92,7 @@ private:
92 rb.PushCopyObjects(service_discovery.readable); 92 rb.PushCopyObjects(service_discovery.readable);
93 } 93 }
94 94
95 void GetConfigEvent(Kernel::HLERequestContext& ctx) { 95 void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) {
96 LOG_WARNING(Service_BTM, "(STUBBED) called"); 96 LOG_WARNING(Service_BTM, "(STUBBED) called");
97 97
98 IPC::ResponseBuilder rb{ctx, 2, 1}; 98 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -111,14 +111,14 @@ public:
111 explicit BTM_USR() : ServiceFramework{"btm:u"} { 111 explicit BTM_USR() : ServiceFramework{"btm:u"} {
112 // clang-format off 112 // clang-format off
113 static const FunctionInfo functions[] = { 113 static const FunctionInfo functions[] = {
114 {0, &BTM_USR::GetCoreImpl, "GetCoreImpl"}, 114 {0, &BTM_USR::GetCore, "GetCore"},
115 }; 115 };
116 // clang-format on 116 // clang-format on
117 RegisterHandlers(functions); 117 RegisterHandlers(functions);
118 } 118 }
119 119
120private: 120private:
121 void GetCoreImpl(Kernel::HLERequestContext& ctx) { 121 void GetCore(Kernel::HLERequestContext& ctx) {
122 LOG_DEBUG(Service_BTM, "called"); 122 LOG_DEBUG(Service_BTM, "called");
123 123
124 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 124 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -134,26 +134,64 @@ public:
134 static const FunctionInfo functions[] = { 134 static const FunctionInfo functions[] = {
135 {0, nullptr, "Unknown1"}, 135 {0, nullptr, "Unknown1"},
136 {1, nullptr, "Unknown2"}, 136 {1, nullptr, "Unknown2"},
137 {2, nullptr, "RegisterSystemEventForConnectedDeviceConditionImpl"}, 137 {2, nullptr, "RegisterSystemEventForConnectedDeviceCondition"},
138 {3, nullptr, "Unknown3"}, 138 {3, nullptr, "Unknown3"},
139 {4, nullptr, "Unknown4"}, 139 {4, nullptr, "Unknown4"},
140 {5, nullptr, "Unknown5"}, 140 {5, nullptr, "Unknown5"},
141 {6, nullptr, "Unknown6"}, 141 {6, nullptr, "Unknown6"},
142 {7, nullptr, "Unknown7"}, 142 {7, nullptr, "Unknown7"},
143 {8, nullptr, "RegisterSystemEventForRegisteredDeviceInfoImpl"}, 143 {8, nullptr, "RegisterSystemEventForRegisteredDeviceInfo"},
144 {9, nullptr, "Unknown8"}, 144 {9, nullptr, "Unknown8"},
145 {10, nullptr, "Unknown9"}, 145 {10, nullptr, "Unknown9"},
146 {11, nullptr, "Unknown10"}, 146 {11, nullptr, "Unknown10"},
147 {12, nullptr, "Unknown11"}, 147 {12, nullptr, "Unknown11"},
148 {13, nullptr, "Unknown12"}, 148 {13, nullptr, "Unknown12"},
149 {14, nullptr, "EnableRadioImpl"}, 149 {14, nullptr, "EnableRadio"},
150 {15, nullptr, "DisableRadioImpl"}, 150 {15, nullptr, "DisableRadio"},
151 {16, nullptr, "Unknown13"}, 151 {16, nullptr, "Unknown13"},
152 {17, nullptr, "Unknown14"}, 152 {17, nullptr, "Unknown14"},
153 {18, nullptr, "Unknown15"}, 153 {18, nullptr, "Unknown15"},
154 {19, nullptr, "Unknown16"}, 154 {19, nullptr, "Unknown16"},
155 {20, nullptr, "Unknown17"}, 155 {20, nullptr, "Unknown17"},
156 {21, nullptr, "Unknown18"}, 156 {21, nullptr, "Unknown18"},
157 {22, nullptr, "Unknown19"},
158 {23, nullptr, "Unknown20"},
159 {24, nullptr, "Unknown21"},
160 {25, nullptr, "Unknown22"},
161 {26, nullptr, "Unknown23"},
162 {27, nullptr, "Unknown24"},
163 {28, nullptr, "Unknown25"},
164 {29, nullptr, "Unknown26"},
165 {30, nullptr, "Unknown27"},
166 {31, nullptr, "Unknown28"},
167 {32, nullptr, "Unknown29"},
168 {33, nullptr, "Unknown30"},
169 {34, nullptr, "Unknown31"},
170 {35, nullptr, "Unknown32"},
171 {36, nullptr, "Unknown33"},
172 {37, nullptr, "Unknown34"},
173 {38, nullptr, "Unknown35"},
174 {39, nullptr, "Unknown36"},
175 {40, nullptr, "Unknown37"},
176 {41, nullptr, "Unknown38"},
177 {42, nullptr, "Unknown39"},
178 {43, nullptr, "Unknown40"},
179 {44, nullptr, "Unknown41"},
180 {45, nullptr, "Unknown42"},
181 {46, nullptr, "Unknown43"},
182 {47, nullptr, "Unknown44"},
183 {48, nullptr, "Unknown45"},
184 {49, nullptr, "Unknown46"},
185 {50, nullptr, "Unknown47"},
186 {51, nullptr, "Unknown48"},
187 {52, nullptr, "Unknown49"},
188 {53, nullptr, "Unknown50"},
189 {54, nullptr, "Unknown51"},
190 {55, nullptr, "Unknown52"},
191 {56, nullptr, "Unknown53"},
192 {57, nullptr, "Unknown54"},
193 {58, nullptr, "Unknown55"},
194 {59, nullptr, "Unknown56"},
157 }; 195 };
158 // clang-format on 196 // clang-format on
159 197
@@ -166,7 +204,7 @@ public:
166 explicit BTM_DBG() : ServiceFramework{"btm:dbg"} { 204 explicit BTM_DBG() : ServiceFramework{"btm:dbg"} {
167 // clang-format off 205 // clang-format off
168 static const FunctionInfo functions[] = { 206 static const FunctionInfo functions[] = {
169 {0, nullptr, "RegisterSystemEventForDiscoveryImpl"}, 207 {0, nullptr, "RegisterSystemEventForDiscovery"},
170 {1, nullptr, "Unknown1"}, 208 {1, nullptr, "Unknown1"},
171 {2, nullptr, "Unknown2"}, 209 {2, nullptr, "Unknown2"},
172 {3, nullptr, "Unknown3"}, 210 {3, nullptr, "Unknown3"},
@@ -175,6 +213,10 @@ public:
175 {6, nullptr, "Unknown6"}, 213 {6, nullptr, "Unknown6"},
176 {7, nullptr, "Unknown7"}, 214 {7, nullptr, "Unknown7"},
177 {8, nullptr, "Unknown8"}, 215 {8, nullptr, "Unknown8"},
216 {9, nullptr, "Unknown9"},
217 {10, nullptr, "Unknown10"},
218 {11, nullptr, "Unknown11"},
219 {12, nullptr, "Unknown11"},
178 }; 220 };
179 // clang-format on 221 // clang-format on
180 222
@@ -187,16 +229,16 @@ public:
187 explicit IBtmSystemCore() : ServiceFramework{"IBtmSystemCore"} { 229 explicit IBtmSystemCore() : ServiceFramework{"IBtmSystemCore"} {
188 // clang-format off 230 // clang-format off
189 static const FunctionInfo functions[] = { 231 static const FunctionInfo functions[] = {
190 {0, nullptr, "StartGamepadPairingImpl"}, 232 {0, nullptr, "StartGamepadPairing"},
191 {1, nullptr, "CancelGamepadPairingImpl"}, 233 {1, nullptr, "CancelGamepadPairing"},
192 {2, nullptr, "ClearGamepadPairingDatabaseImpl"}, 234 {2, nullptr, "ClearGamepadPairingDatabase"},
193 {3, nullptr, "GetPairedGamepadCountImpl"}, 235 {3, nullptr, "GetPairedGamepadCount"},
194 {4, nullptr, "EnableRadioImpl"}, 236 {4, nullptr, "EnableRadio"},
195 {5, nullptr, "DisableRadioImpl"}, 237 {5, nullptr, "DisableRadio"},
196 {6, nullptr, "GetRadioOnOffImpl"}, 238 {6, nullptr, "GetRadioOnOff"},
197 {7, nullptr, "AcquireRadioEventImpl"}, 239 {7, nullptr, "AcquireRadioEvent"},
198 {8, nullptr, "AcquireGamepadPairingEventImpl"}, 240 {8, nullptr, "AcquireGamepadPairingEvent"},
199 {9, nullptr, "IsGamepadPairingStartedImpl"}, 241 {9, nullptr, "IsGamepadPairingStarted"},
200 }; 242 };
201 // clang-format on 243 // clang-format on
202 244
@@ -209,7 +251,7 @@ public:
209 explicit BTM_SYS() : ServiceFramework{"btm:sys"} { 251 explicit BTM_SYS() : ServiceFramework{"btm:sys"} {
210 // clang-format off 252 // clang-format off
211 static const FunctionInfo functions[] = { 253 static const FunctionInfo functions[] = {
212 {0, &BTM_SYS::GetCoreImpl, "GetCoreImpl"}, 254 {0, &BTM_SYS::GetCore, "GetCore"},
213 }; 255 };
214 // clang-format on 256 // clang-format on
215 257
@@ -217,7 +259,7 @@ public:
217 } 259 }
218 260
219private: 261private:
220 void GetCoreImpl(Kernel::HLERequestContext& ctx) { 262 void GetCore(Kernel::HLERequestContext& ctx) {
221 LOG_DEBUG(Service_BTM, "called"); 263 LOG_DEBUG(Service_BTM, "called");
222 264
223 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 265 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 74c4e583b..54959edd8 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -627,8 +627,8 @@ private:
627FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { 627FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
628 // clang-format off 628 // clang-format off
629 static const FunctionInfo functions[] = { 629 static const FunctionInfo functions[] = {
630 {0, nullptr, "MountContent"}, 630 {0, nullptr, "OpenFileSystem"},
631 {1, &FSP_SRV::Initialize, "Initialize"}, 631 {1, &FSP_SRV::SetCurrentProcess, "SetCurrentProcess"},
632 {2, nullptr, "OpenDataFileSystemByCurrentProcess"}, 632 {2, nullptr, "OpenDataFileSystemByCurrentProcess"},
633 {7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"}, 633 {7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"},
634 {8, nullptr, "OpenFileSystemWithId"}, 634 {8, nullptr, "OpenFileSystemWithId"},
@@ -637,10 +637,10 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
637 {12, nullptr, "OpenBisStorage"}, 637 {12, nullptr, "OpenBisStorage"},
638 {13, nullptr, "InvalidateBisCache"}, 638 {13, nullptr, "InvalidateBisCache"},
639 {17, nullptr, "OpenHostFileSystem"}, 639 {17, nullptr, "OpenHostFileSystem"},
640 {18, &FSP_SRV::MountSdCard, "MountSdCard"}, 640 {18, &FSP_SRV::OpenSdCardFileSystem, "OpenSdCardFileSystem"},
641 {19, nullptr, "FormatSdCardFileSystem"}, 641 {19, nullptr, "FormatSdCardFileSystem"},
642 {21, nullptr, "DeleteSaveDataFileSystem"}, 642 {21, nullptr, "DeleteSaveDataFileSystem"},
643 {22, &FSP_SRV::CreateSaveData, "CreateSaveData"}, 643 {22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"},
644 {23, nullptr, "CreateSaveDataFileSystemBySystemSaveDataId"}, 644 {23, nullptr, "CreateSaveDataFileSystemBySystemSaveDataId"},
645 {24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"}, 645 {24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"},
646 {25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"}, 646 {25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"},
@@ -652,7 +652,8 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
652 {32, nullptr, "ExtendSaveDataFileSystem"}, 652 {32, nullptr, "ExtendSaveDataFileSystem"},
653 {33, nullptr, "DeleteCacheStorage"}, 653 {33, nullptr, "DeleteCacheStorage"},
654 {34, nullptr, "GetCacheStorageSize"}, 654 {34, nullptr, "GetCacheStorageSize"},
655 {51, &FSP_SRV::MountSaveData, "MountSaveData"}, 655 {35, nullptr, "CreateSaveDataFileSystemByHashSalt"},
656 {51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"},
656 {52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"}, 657 {52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"},
657 {53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"}, 658 {53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"},
658 {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, 659 {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"},
@@ -664,21 +665,26 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
664 {64, nullptr, "OpenSaveDataInternalStorageFileSystem"}, 665 {64, nullptr, "OpenSaveDataInternalStorageFileSystem"},
665 {65, nullptr, "UpdateSaveDataMacForDebug"}, 666 {65, nullptr, "UpdateSaveDataMacForDebug"},
666 {66, nullptr, "WriteSaveDataFileSystemExtraData2"}, 667 {66, nullptr, "WriteSaveDataFileSystemExtraData2"},
668 {67, nullptr, "FindSaveDataWithFilter"},
669 {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"},
667 {80, nullptr, "OpenSaveDataMetaFile"}, 670 {80, nullptr, "OpenSaveDataMetaFile"},
668 {81, nullptr, "OpenSaveDataTransferManager"}, 671 {81, nullptr, "OpenSaveDataTransferManager"},
669 {82, nullptr, "OpenSaveDataTransferManagerVersion2"}, 672 {82, nullptr, "OpenSaveDataTransferManagerVersion2"},
670 {83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"}, 673 {83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"},
674 {84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"},
671 {100, nullptr, "OpenImageDirectoryFileSystem"}, 675 {100, nullptr, "OpenImageDirectoryFileSystem"},
672 {110, nullptr, "OpenContentStorageFileSystem"}, 676 {110, nullptr, "OpenContentStorageFileSystem"},
677 {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
673 {200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"}, 678 {200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
674 {201, nullptr, "OpenDataStorageByProgramId"}, 679 {201, nullptr, "OpenDataStorageByProgramId"},
675 {202, &FSP_SRV::OpenDataStorageByDataId, "OpenDataStorageByDataId"}, 680 {202, &FSP_SRV::OpenDataStorageByDataId, "OpenDataStorageByDataId"},
676 {203, &FSP_SRV::OpenRomStorage, "OpenRomStorage"}, 681 {203, &FSP_SRV::OpenPatchDataStorageByCurrentProcess, "OpenPatchDataStorageByCurrentProcess"},
677 {400, nullptr, "OpenDeviceOperator"}, 682 {400, nullptr, "OpenDeviceOperator"},
678 {500, nullptr, "OpenSdCardDetectionEventNotifier"}, 683 {500, nullptr, "OpenSdCardDetectionEventNotifier"},
679 {501, nullptr, "OpenGameCardDetectionEventNotifier"}, 684 {501, nullptr, "OpenGameCardDetectionEventNotifier"},
680 {510, nullptr, "OpenSystemDataUpdateEventNotifier"}, 685 {510, nullptr, "OpenSystemDataUpdateEventNotifier"},
681 {511, nullptr, "NotifySystemDataUpdateEvent"}, 686 {511, nullptr, "NotifySystemDataUpdateEvent"},
687 {520, nullptr, "SimulateGameCardDetectionEvent"},
682 {600, nullptr, "SetCurrentPosixTime"}, 688 {600, nullptr, "SetCurrentPosixTime"},
683 {601, nullptr, "QuerySaveDataTotalSize"}, 689 {601, nullptr, "QuerySaveDataTotalSize"},
684 {602, nullptr, "VerifySaveDataFileSystem"}, 690 {602, nullptr, "VerifySaveDataFileSystem"},
@@ -717,6 +723,8 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
717 {1008, nullptr, "OpenRegisteredUpdatePartition"}, 723 {1008, nullptr, "OpenRegisteredUpdatePartition"},
718 {1009, nullptr, "GetAndClearMemoryReportInfo"}, 724 {1009, nullptr, "GetAndClearMemoryReportInfo"},
719 {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, 725 {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
726 {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
727 {1200, nullptr, "OpenMultiCommitManager"},
720 }; 728 };
721 // clang-format on 729 // clang-format on
722 RegisterHandlers(functions); 730 RegisterHandlers(functions);
@@ -724,7 +732,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
724 732
725FSP_SRV::~FSP_SRV() = default; 733FSP_SRV::~FSP_SRV() = default;
726 734
727void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { 735void FSP_SRV::SetCurrentProcess(Kernel::HLERequestContext& ctx) {
728 LOG_WARNING(Service_FS, "(STUBBED) called"); 736 LOG_WARNING(Service_FS, "(STUBBED) called");
729 737
730 IPC::ResponseBuilder rb{ctx, 2}; 738 IPC::ResponseBuilder rb{ctx, 2};
@@ -743,7 +751,7 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) {
743 rb.Push(ResultCode(-1)); 751 rb.Push(ResultCode(-1));
744} 752}
745 753
746void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { 754void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) {
747 LOG_DEBUG(Service_FS, "called"); 755 LOG_DEBUG(Service_FS, "called");
748 756
749 IFileSystem filesystem(OpenSDMC().Unwrap()); 757 IFileSystem filesystem(OpenSDMC().Unwrap());
@@ -753,7 +761,7 @@ void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {
753 rb.PushIpcInterface<IFileSystem>(std::move(filesystem)); 761 rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
754} 762}
755 763
756void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) { 764void FSP_SRV::CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
757 IPC::RequestParser rp{ctx}; 765 IPC::RequestParser rp{ctx};
758 766
759 auto save_struct = rp.PopRaw<FileSys::SaveDataDescriptor>(); 767 auto save_struct = rp.PopRaw<FileSys::SaveDataDescriptor>();
@@ -767,7 +775,7 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) {
767 rb.Push(RESULT_SUCCESS); 775 rb.Push(RESULT_SUCCESS);
768} 776}
769 777
770void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { 778void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
771 IPC::RequestParser rp{ctx}; 779 IPC::RequestParser rp{ctx};
772 780
773 auto space_id = rp.PopRaw<FileSys::SaveDataSpaceId>(); 781 auto space_id = rp.PopRaw<FileSys::SaveDataSpaceId>();
@@ -793,7 +801,7 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
793 801
794void FSP_SRV::OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx) { 802void FSP_SRV::OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx) {
795 LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); 803 LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
796 MountSaveData(ctx); 804 OpenSaveDataFileSystem(ctx);
797} 805}
798 806
799void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx) { 807void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx) {
@@ -881,7 +889,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
881 rb.PushIpcInterface<IStorage>(std::move(storage)); 889 rb.PushIpcInterface<IStorage>(std::move(storage));
882} 890}
883 891
884void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { 892void FSP_SRV::OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
885 IPC::RequestParser rp{ctx}; 893 IPC::RequestParser rp{ctx};
886 894
887 auto storage_id = rp.PopRaw<FileSys::StorageId>(); 895 auto storage_id = rp.PopRaw<FileSys::StorageId>();
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h
index e7abec0a3..3a5f4e200 100644
--- a/src/core/hle/service/filesystem/fsp_srv.h
+++ b/src/core/hle/service/filesystem/fsp_srv.h
@@ -19,17 +19,17 @@ public:
19 ~FSP_SRV() override; 19 ~FSP_SRV() override;
20 20
21private: 21private:
22 void Initialize(Kernel::HLERequestContext& ctx); 22 void SetCurrentProcess(Kernel::HLERequestContext& ctx);
23 void OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx); 23 void OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx);
24 void MountSdCard(Kernel::HLERequestContext& ctx); 24 void OpenSdCardFileSystem(Kernel::HLERequestContext& ctx);
25 void CreateSaveData(Kernel::HLERequestContext& ctx); 25 void CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx);
26 void MountSaveData(Kernel::HLERequestContext& ctx); 26 void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx);
27 void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx); 27 void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx);
28 void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx); 28 void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx);
29 void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); 29 void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
30 void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); 30 void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
31 void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx); 31 void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx);
32 void OpenRomStorage(Kernel::HLERequestContext& ctx); 32 void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
33 33
34 FileSys::VirtualFile romfs; 34 FileSys::VirtualFile romfs;
35}; 35};
diff --git a/src/core/hle/service/ncm/ncm.cpp b/src/core/hle/service/ncm/ncm.cpp
index 0297edca0..5d31f638f 100644
--- a/src/core/hle/service/ncm/ncm.cpp
+++ b/src/core/hle/service/ncm/ncm.cpp
@@ -40,10 +40,10 @@ public:
40 {6, nullptr, "CloseContentStorageForcibly"}, 40 {6, nullptr, "CloseContentStorageForcibly"},
41 {7, nullptr, "CloseContentMetaDatabaseForcibly"}, 41 {7, nullptr, "CloseContentMetaDatabaseForcibly"},
42 {8, nullptr, "CleanupContentMetaDatabase"}, 42 {8, nullptr, "CleanupContentMetaDatabase"},
43 {9, nullptr, "OpenContentStorage2"}, 43 {9, nullptr, "ActivateContentStorage"},
44 {10, nullptr, "CloseContentStorage"}, 44 {10, nullptr, "InactivateContentStorage"},
45 {11, nullptr, "OpenContentMetaDatabase2"}, 45 {11, nullptr, "ActivateContentMetaDatabase"},
46 {12, nullptr, "CloseContentMetaDatabase"}, 46 {12, nullptr, "InactivateContentMetaDatabase"},
47 }; 47 };
48 // clang-format on 48 // clang-format on
49 49
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 2663f56b1..0eb04037a 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -43,7 +43,7 @@ public:
43 {11, nullptr, "CalculateApplicationOccupiedSize"}, 43 {11, nullptr, "CalculateApplicationOccupiedSize"},
44 {16, nullptr, "PushApplicationRecord"}, 44 {16, nullptr, "PushApplicationRecord"},
45 {17, nullptr, "ListApplicationRecordContentMeta"}, 45 {17, nullptr, "ListApplicationRecordContentMeta"},
46 {19, nullptr, "LaunchApplication"}, 46 {19, nullptr, "LaunchApplicationOld"},
47 {21, nullptr, "GetApplicationContentPath"}, 47 {21, nullptr, "GetApplicationContentPath"},
48 {22, nullptr, "TerminateApplication"}, 48 {22, nullptr, "TerminateApplication"},
49 {23, nullptr, "ResolveApplicationContentPath"}, 49 {23, nullptr, "ResolveApplicationContentPath"},
@@ -96,10 +96,10 @@ public:
96 {86, nullptr, "EnableApplicationCrashReport"}, 96 {86, nullptr, "EnableApplicationCrashReport"},
97 {87, nullptr, "IsApplicationCrashReportEnabled"}, 97 {87, nullptr, "IsApplicationCrashReportEnabled"},
98 {90, nullptr, "BoostSystemMemoryResourceLimit"}, 98 {90, nullptr, "BoostSystemMemoryResourceLimit"},
99 {91, nullptr, "Unknown1"}, 99 {91, nullptr, "DeprecatedLaunchApplication"},
100 {92, nullptr, "Unknown2"}, 100 {92, nullptr, "GetRunningApplicationProgramId"},
101 {93, nullptr, "GetMainApplicationProgramIndex"}, 101 {93, nullptr, "GetMainApplicationProgramIndex"},
102 {94, nullptr, "LaunchApplication2"}, 102 {94, nullptr, "LaunchApplication"},
103 {95, nullptr, "GetApplicationLaunchInfo"}, 103 {95, nullptr, "GetApplicationLaunchInfo"},
104 {96, nullptr, "AcquireApplicationLaunchInfo"}, 104 {96, nullptr, "AcquireApplicationLaunchInfo"},
105 {97, nullptr, "GetMainApplicationProgramIndex2"}, 105 {97, nullptr, "GetMainApplicationProgramIndex2"},
@@ -163,7 +163,7 @@ public:
163 {907, nullptr, "WithdrawApplicationUpdateRequest"}, 163 {907, nullptr, "WithdrawApplicationUpdateRequest"},
164 {908, nullptr, "ListApplicationRecordInstalledContentMeta"}, 164 {908, nullptr, "ListApplicationRecordInstalledContentMeta"},
165 {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"}, 165 {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
166 {910, nullptr, "Unknown3"}, 166 {910, nullptr, "HasApplicationRecord"},
167 {911, nullptr, "SetPreInstalledApplication"}, 167 {911, nullptr, "SetPreInstalledApplication"},
168 {912, nullptr, "ClearPreInstalledApplicationFlag"}, 168 {912, nullptr, "ClearPreInstalledApplicationFlag"},
169 {1000, nullptr, "RequestVerifyApplicationDeprecated"}, 169 {1000, nullptr, "RequestVerifyApplicationDeprecated"},
@@ -219,10 +219,10 @@ public:
219 {2015, nullptr, "CompareSystemDeliveryInfo"}, 219 {2015, nullptr, "CompareSystemDeliveryInfo"},
220 {2016, nullptr, "ListNotCommittedContentMeta"}, 220 {2016, nullptr, "ListNotCommittedContentMeta"},
221 {2017, nullptr, "CreateDownloadTask"}, 221 {2017, nullptr, "CreateDownloadTask"},
222 {2018, nullptr, "Unknown4"}, 222 {2018, nullptr, "GetApplicationDeliveryInfoHash"},
223 {2050, nullptr, "Unknown5"}, 223 {2050, nullptr, "GetApplicationRightsOnClient"},
224 {2100, nullptr, "Unknown6"}, 224 {2100, nullptr, "GetApplicationTerminateResult"},
225 {2101, nullptr, "Unknown7"}, 225 {2101, nullptr, "GetRawApplicationTerminateResult"},
226 {2150, nullptr, "CreateRightsEnvironment"}, 226 {2150, nullptr, "CreateRightsEnvironment"},
227 {2151, nullptr, "DestroyRightsEnvironment"}, 227 {2151, nullptr, "DestroyRightsEnvironment"},
228 {2152, nullptr, "ActivateRightsEnvironment"}, 228 {2152, nullptr, "ActivateRightsEnvironment"},
@@ -237,10 +237,10 @@ public:
237 {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"}, 237 {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"},
238 {2190, nullptr, "GetRightsEnvironmentHandleForApplication"}, 238 {2190, nullptr, "GetRightsEnvironmentHandleForApplication"},
239 {2199, nullptr, "GetRightsEnvironmentCountForDebug"}, 239 {2199, nullptr, "GetRightsEnvironmentCountForDebug"},
240 {2200, nullptr, "Unknown8"}, 240 {2200, nullptr, "GetGameCardApplicationCopyIdentifier"},
241 {2201, nullptr, "Unknown9"}, 241 {2201, nullptr, "GetInstalledApplicationCopyIdentifier"},
242 {2250, nullptr, "Unknown10"}, 242 {2250, nullptr, "RequestReportActiveELicence"},
243 {2300, nullptr, "Unknown11"}, 243 {2300, nullptr, "ListEventLog"},
244 }; 244 };
245 // clang-format on 245 // clang-format on
246 246
@@ -355,6 +355,7 @@ public:
355 static const FunctionInfo functions[] = { 355 static const FunctionInfo functions[] = {
356 {21, nullptr, "GetApplicationContentPath"}, 356 {21, nullptr, "GetApplicationContentPath"},
357 {23, nullptr, "ResolveApplicationContentPath"}, 357 {23, nullptr, "ResolveApplicationContentPath"},
358 {93, nullptr, "GetRunningApplicationProgramId"},
358 }; 359 };
359 // clang-format on 360 // clang-format on
360 361
@@ -389,6 +390,11 @@ public:
389 // clang-format off 390 // clang-format off
390 static const FunctionInfo functions[] = { 391 static const FunctionInfo functions[] = {
391 {0, nullptr, "RequestLinkDevice"}, 392 {0, nullptr, "RequestLinkDevice"},
393 {1, nullptr, "RequestCleanupAllPreInstalledApplications"},
394 {2, nullptr, "RequestCleanupPreInstalledApplication"},
395 {3, nullptr, "RequestSyncRights"},
396 {4, nullptr, "RequestUnlinkDevice"},
397 {5, nullptr, "RequestRevokeAllELicense"},
392 }; 398 };
393 // clang-format on 399 // clang-format on
394 400
@@ -403,7 +409,7 @@ public:
403 static const FunctionInfo functions[] = { 409 static const FunctionInfo functions[] = {
404 {100, nullptr, "ResetToFactorySettings"}, 410 {100, nullptr, "ResetToFactorySettings"},
405 {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, 411 {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
406 {102, nullptr, "ResetToFactorySettingsForRefurbishment "}, 412 {102, nullptr, "ResetToFactorySettingsForRefurbishment"},
407 }; 413 };
408 // clang-format on 414 // clang-format on
409 415
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 6db2cce41..8dfc0df03 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -61,7 +61,7 @@ u64 NVFlinger::OpenDisplay(std::string_view name) {
61} 61}
62 62
63u64 NVFlinger::CreateLayer(u64 display_id) { 63u64 NVFlinger::CreateLayer(u64 display_id) {
64 auto& display = GetDisplay(display_id); 64 auto& display = FindDisplay(display_id);
65 65
66 ASSERT_MSG(display.layers.empty(), "Only one layer is supported per display at the moment"); 66 ASSERT_MSG(display.layers.empty(), "Only one layer is supported per display at the moment");
67 67
@@ -73,16 +73,16 @@ u64 NVFlinger::CreateLayer(u64 display_id) {
73 return layer_id; 73 return layer_id;
74} 74}
75 75
76u32 NVFlinger::GetBufferQueueId(u64 display_id, u64 layer_id) { 76u32 NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) const {
77 const auto& layer = GetLayer(display_id, layer_id); 77 const auto& layer = FindLayer(display_id, layer_id);
78 return layer.buffer_queue->GetId(); 78 return layer.buffer_queue->GetId();
79} 79}
80 80
81Kernel::SharedPtr<Kernel::ReadableEvent> NVFlinger::GetVsyncEvent(u64 display_id) { 81Kernel::SharedPtr<Kernel::ReadableEvent> NVFlinger::GetVsyncEvent(u64 display_id) {
82 return GetDisplay(display_id).vsync_event.readable; 82 return FindDisplay(display_id).vsync_event.readable;
83} 83}
84 84
85std::shared_ptr<BufferQueue> NVFlinger::GetBufferQueue(u32 id) const { 85std::shared_ptr<BufferQueue> NVFlinger::FindBufferQueue(u32 id) const {
86 const auto itr = std::find_if(buffer_queues.begin(), buffer_queues.end(), 86 const auto itr = std::find_if(buffer_queues.begin(), buffer_queues.end(),
87 [&](const auto& queue) { return queue->GetId() == id; }); 87 [&](const auto& queue) { return queue->GetId() == id; });
88 88
@@ -90,7 +90,7 @@ std::shared_ptr<BufferQueue> NVFlinger::GetBufferQueue(u32 id) const {
90 return *itr; 90 return *itr;
91} 91}
92 92
93Display& NVFlinger::GetDisplay(u64 display_id) { 93Display& NVFlinger::FindDisplay(u64 display_id) {
94 const auto itr = std::find_if(displays.begin(), displays.end(), 94 const auto itr = std::find_if(displays.begin(), displays.end(),
95 [&](const Display& display) { return display.id == display_id; }); 95 [&](const Display& display) { return display.id == display_id; });
96 96
@@ -98,8 +98,26 @@ Display& NVFlinger::GetDisplay(u64 display_id) {
98 return *itr; 98 return *itr;
99} 99}
100 100
101Layer& NVFlinger::GetLayer(u64 display_id, u64 layer_id) { 101const Display& NVFlinger::FindDisplay(u64 display_id) const {
102 auto& display = GetDisplay(display_id); 102 const auto itr = std::find_if(displays.begin(), displays.end(),
103 [&](const Display& display) { return display.id == display_id; });
104
105 ASSERT(itr != displays.end());
106 return *itr;
107}
108
109Layer& NVFlinger::FindLayer(u64 display_id, u64 layer_id) {
110 auto& display = FindDisplay(display_id);
111
112 const auto itr = std::find_if(display.layers.begin(), display.layers.end(),
113 [&](const Layer& layer) { return layer.id == layer_id; });
114
115 ASSERT(itr != display.layers.end());
116 return *itr;
117}
118
119const Layer& NVFlinger::FindLayer(u64 display_id, u64 layer_id) const {
120 const auto& display = FindDisplay(display_id);
103 121
104 const auto itr = std::find_if(display.layers.begin(), display.layers.end(), 122 const auto itr = std::find_if(display.layers.begin(), display.layers.end(),
105 [&](const Layer& layer) { return layer.id == layer_id; }); 123 [&](const Layer& layer) { return layer.id == layer_id; });
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 8f9a0a7f8..83e974ed3 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -57,31 +57,37 @@ public:
57 /// Sets the NVDrv module instance to use to send buffers to the GPU. 57 /// Sets the NVDrv module instance to use to send buffers to the GPU.
58 void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance); 58 void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance);
59 59
60 /// Opens the specified display and returns the id. 60 /// Opens the specified display and returns the ID.
61 u64 OpenDisplay(std::string_view name); 61 u64 OpenDisplay(std::string_view name);
62 62
63 /// Creates a layer on the specified display and returns the layer id. 63 /// Creates a layer on the specified display and returns the layer ID.
64 u64 CreateLayer(u64 display_id); 64 u64 CreateLayer(u64 display_id);
65 65
66 /// Gets the buffer queue id of the specified layer in the specified display. 66 /// Finds the buffer queue ID of the specified layer in the specified display.
67 u32 GetBufferQueueId(u64 display_id, u64 layer_id); 67 u32 FindBufferQueueId(u64 display_id, u64 layer_id) const;
68 68
69 /// Gets the vsync event for the specified display. 69 /// Gets the vsync event for the specified display.
70 Kernel::SharedPtr<Kernel::ReadableEvent> GetVsyncEvent(u64 display_id); 70 Kernel::SharedPtr<Kernel::ReadableEvent> GetVsyncEvent(u64 display_id);
71 71
72 /// Obtains a buffer queue identified by the id. 72 /// Obtains a buffer queue identified by the ID.
73 std::shared_ptr<BufferQueue> GetBufferQueue(u32 id) const; 73 std::shared_ptr<BufferQueue> FindBufferQueue(u32 id) const;
74 74
75 /// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when 75 /// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
76 /// finished. 76 /// finished.
77 void Compose(); 77 void Compose();
78 78
79private: 79private:
80 /// Returns the display identified by the specified id. 80 /// Finds the display identified by the specified ID.
81 Display& GetDisplay(u64 display_id); 81 Display& FindDisplay(u64 display_id);
82 82
83 /// Returns the layer identified by the specified id in the desired display. 83 /// Finds the display identified by the specified ID.
84 Layer& GetLayer(u64 display_id, u64 layer_id); 84 const Display& FindDisplay(u64 display_id) const;
85
86 /// Finds the layer identified by the specified ID in the desired display.
87 Layer& FindLayer(u64 display_id, u64 layer_id);
88
89 /// Finds the layer identified by the specified ID in the desired display.
90 const Layer& FindLayer(u64 display_id, u64 layer_id) const;
85 91
86 std::shared_ptr<Nvidia::Module> nvdrv; 92 std::shared_ptr<Nvidia::Module> nvdrv;
87 93
diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp
index 0ba0a4076..53ec6b031 100644
--- a/src/core/hle/service/psc/psc.cpp
+++ b/src/core/hle/service/psc/psc.cpp
@@ -17,13 +17,13 @@ public:
17 explicit PSC_C() : ServiceFramework{"psc:c"} { 17 explicit PSC_C() : ServiceFramework{"psc:c"} {
18 // clang-format off 18 // clang-format off
19 static const FunctionInfo functions[] = { 19 static const FunctionInfo functions[] = {
20 {0, nullptr, "Unknown1"}, 20 {0, nullptr, "Initialize"},
21 {1, nullptr, "Unknown2"}, 21 {1, nullptr, "DispatchRequest"},
22 {2, nullptr, "Unknown3"}, 22 {2, nullptr, "GetResult"},
23 {3, nullptr, "Unknown4"}, 23 {3, nullptr, "GetState"},
24 {4, nullptr, "Unknown5"}, 24 {4, nullptr, "Cancel"},
25 {5, nullptr, "Unknown6"}, 25 {5, nullptr, "PrintModuleInformation"},
26 {6, nullptr, "Unknown7"}, 26 {6, nullptr, "GetModuleInformation"},
27 }; 27 };
28 // clang-format on 28 // clang-format on
29 29
@@ -39,7 +39,8 @@ public:
39 {0, nullptr, "Initialize"}, 39 {0, nullptr, "Initialize"},
40 {1, nullptr, "GetRequest"}, 40 {1, nullptr, "GetRequest"},
41 {2, nullptr, "Acknowledge"}, 41 {2, nullptr, "Acknowledge"},
42 {3, nullptr, "Unknown1"}, 42 {3, nullptr, "Finalize"},
43 {4, nullptr, "AcknowledgeEx"},
43 }; 44 };
44 // clang-format on 45 // clang-format on
45 46
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 0f2c25182..fe08c38f2 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -524,7 +524,7 @@ private:
524 LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id, 524 LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id,
525 static_cast<u32>(transaction), flags); 525 static_cast<u32>(transaction), flags);
526 526
527 auto buffer_queue = nv_flinger->GetBufferQueue(id); 527 auto buffer_queue = nv_flinger->FindBufferQueue(id);
528 528
529 if (transaction == TransactionId::Connect) { 529 if (transaction == TransactionId::Connect) {
530 IGBPConnectRequestParcel request{ctx.ReadBuffer()}; 530 IGBPConnectRequestParcel request{ctx.ReadBuffer()};
@@ -558,7 +558,7 @@ private:
558 [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, 558 [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
559 Kernel::ThreadWakeupReason reason) { 559 Kernel::ThreadWakeupReason reason) {
560 // Repeat TransactParcel DequeueBuffer when a buffer is available 560 // Repeat TransactParcel DequeueBuffer when a buffer is available
561 auto buffer_queue = nv_flinger->GetBufferQueue(id); 561 auto buffer_queue = nv_flinger->FindBufferQueue(id);
562 std::optional<u32> slot = buffer_queue->DequeueBuffer(width, height); 562 std::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
563 ASSERT_MSG(slot != std::nullopt, "Could not dequeue buffer."); 563 ASSERT_MSG(slot != std::nullopt, "Could not dequeue buffer.");
564 564
@@ -628,7 +628,7 @@ private:
628 628
629 LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown); 629 LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown);
630 630
631 const auto buffer_queue = nv_flinger->GetBufferQueue(id); 631 const auto buffer_queue = nv_flinger->FindBufferQueue(id);
632 632
633 // TODO(Subv): Find out what this actually is. 633 // TODO(Subv): Find out what this actually is.
634 IPC::ResponseBuilder rb{ctx, 2, 1}; 634 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -1044,7 +1044,7 @@ private:
1044 LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}, aruid=0x{:016X}", layer_id, aruid); 1044 LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}, aruid=0x{:016X}", layer_id, aruid);
1045 1045
1046 const u64 display_id = nv_flinger->OpenDisplay(display_name); 1046 const u64 display_id = nv_flinger->OpenDisplay(display_name);
1047 const u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); 1047 const u32 buffer_queue_id = nv_flinger->FindBufferQueueId(display_id, layer_id);
1048 1048
1049 NativeWindow native_window{buffer_queue_id}; 1049 NativeWindow native_window{buffer_queue_id};
1050 IPC::ResponseBuilder rb{ctx, 4}; 1050 IPC::ResponseBuilder rb{ctx, 4};
@@ -1063,7 +1063,7 @@ private:
1063 // TODO(Subv): What's the difference between a Stray and a Managed layer? 1063 // TODO(Subv): What's the difference between a Stray and a Managed layer?
1064 1064
1065 const u64 layer_id = nv_flinger->CreateLayer(display_id); 1065 const u64 layer_id = nv_flinger->CreateLayer(display_id);
1066 const u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); 1066 const u32 buffer_queue_id = nv_flinger->FindBufferQueueId(display_id, layer_id);
1067 1067
1068 NativeWindow native_window{buffer_queue_id}; 1068 NativeWindow native_window{buffer_queue_id};
1069 IPC::ResponseBuilder rb{ctx, 6}; 1069 IPC::ResponseBuilder rb{ctx, 6};
diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h
index 16e0697c4..1097e5c49 100644
--- a/src/video_core/dma_pusher.h
+++ b/src/video_core/dma_pusher.h
@@ -83,7 +83,7 @@ private:
83 u32 subchannel; ///< Current subchannel 83 u32 subchannel; ///< Current subchannel
84 u32 method_count; ///< Current method count 84 u32 method_count; ///< Current method count
85 u32 length_pending; ///< Large NI command length pending 85 u32 length_pending; ///< Large NI command length pending
86 bool non_incrementing; ///< Current commands NI flag 86 bool non_incrementing; ///< Current command's NI flag
87 }; 87 };
88 88
89 DmaState dma_state{}; 89 DmaState dma_state{};
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index ff5310848..4c08bb148 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -49,11 +49,6 @@ public:
49 return false; 49 return false;
50 } 50 }
51 51
52 /// Attempt to use a faster method to fill a region
53 virtual bool AccelerateFill(const void* config) {
54 return false;
55 }
56
57 /// Attempt to use a faster method to display the framebuffer to screen 52 /// Attempt to use a faster method to display the framebuffer to screen
58 virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 53 virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
59 u32 pixel_stride) { 54 u32 pixel_stride) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index aed6843d4..9f7c837d6 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -477,9 +477,9 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
477 cached_pages.add({pages_interval, delta}); 477 cached_pages.add({pages_interval, delta});
478} 478}
479 479
480void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool using_color_fb, 480std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
481 bool using_depth_fb, bool preserve_contents, 481 OpenGLState& current_state, bool using_color_fb, bool using_depth_fb, bool preserve_contents,
482 std::optional<std::size_t> single_color_target) { 482 std::optional<std::size_t> single_color_target) {
483 MICROPROFILE_SCOPE(OpenGL_Framebuffer); 483 MICROPROFILE_SCOPE(OpenGL_Framebuffer);
484 const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); 484 const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
485 const auto& regs = gpu.regs; 485 const auto& regs = gpu.regs;
@@ -491,7 +491,7 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
491 // Only skip if the previous ConfigureFramebuffers call was from the same kind (multiple or 491 // Only skip if the previous ConfigureFramebuffers call was from the same kind (multiple or
492 // single color targets). This is done because the guest registers may not change but the 492 // single color targets). This is done because the guest registers may not change but the
493 // host framebuffer may contain different attachments 493 // host framebuffer may contain different attachments
494 return; 494 return current_depth_stencil_usage;
495 } 495 }
496 current_framebuffer_config_state = fb_config_state; 496 current_framebuffer_config_state = fb_config_state;
497 497
@@ -561,12 +561,14 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
561 depth_surface->MarkAsModified(true, res_cache); 561 depth_surface->MarkAsModified(true, res_cache);
562 562
563 fbkey.zeta = depth_surface->Texture().handle; 563 fbkey.zeta = depth_surface->Texture().handle;
564 fbkey.stencil_enable = regs.stencil_enable; 564 fbkey.stencil_enable = regs.stencil_enable &&
565 depth_surface->GetSurfaceParams().type == SurfaceType::DepthStencil;
565 } 566 }
566 567
567 SetupCachedFramebuffer(fbkey, current_state); 568 SetupCachedFramebuffer(fbkey, current_state);
568
569 SyncViewport(current_state); 569 SyncViewport(current_state);
570
571 return current_depth_stencil_usage = {static_cast<bool>(depth_surface), fbkey.stencil_enable};
570} 572}
571 573
572void RasterizerOpenGL::Clear() { 574void RasterizerOpenGL::Clear() {
@@ -634,8 +636,8 @@ void RasterizerOpenGL::Clear() {
634 return; 636 return;
635 } 637 }
636 638
637 ConfigureFramebuffers(clear_state, use_color, use_depth || use_stencil, false, 639 const auto [clear_depth, clear_stencil] = ConfigureFramebuffers(
638 regs.clear_buffers.RT.Value()); 640 clear_state, use_color, use_depth || use_stencil, false, regs.clear_buffers.RT.Value());
639 if (regs.clear_flags.scissor) { 641 if (regs.clear_flags.scissor) {
640 SyncScissorTest(clear_state); 642 SyncScissorTest(clear_state);
641 } 643 }
@@ -650,11 +652,11 @@ void RasterizerOpenGL::Clear() {
650 glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color); 652 glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color);
651 } 653 }
652 654
653 if (use_depth && use_stencil) { 655 if (clear_depth && clear_stencil) {
654 glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil); 656 glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil);
655 } else if (use_depth) { 657 } else if (clear_depth) {
656 glClearBufferfv(GL_DEPTH, 0, &regs.clear_depth); 658 glClearBufferfv(GL_DEPTH, 0, &regs.clear_depth);
657 } else if (use_stencil) { 659 } else if (clear_stencil) {
658 glClearBufferiv(GL_STENCIL, 0, &regs.clear_stencil); 660 glClearBufferiv(GL_STENCIL, 0, &regs.clear_stencil);
659 } 661 }
660} 662}
@@ -781,11 +783,6 @@ bool RasterizerOpenGL::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs
781 return true; 783 return true;
782} 784}
783 785
784bool RasterizerOpenGL::AccelerateFill(const void* config) {
785 UNREACHABLE();
786 return true;
787}
788
789bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, 786bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
790 VAddr framebuffer_addr, u32 pixel_stride) { 787 VAddr framebuffer_addr, u32 pixel_stride) {
791 if (!framebuffer_addr) { 788 if (!framebuffer_addr) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index a103692f9..7f2bf0f8b 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -56,7 +56,6 @@ public:
56 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 56 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
57 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, 57 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src,
58 const Tegra::Engines::Fermi2D::Regs::Surface& dst) override; 58 const Tegra::Engines::Fermi2D::Regs::Surface& dst) override;
59 bool AccelerateFill(const void* config) override;
60 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 59 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
61 u32 pixel_stride) override; 60 u32 pixel_stride) override;
62 bool AccelerateDrawBatch(bool is_indexed) override; 61 bool AccelerateDrawBatch(bool is_indexed) override;
@@ -122,10 +121,12 @@ private:
122 * @param using_depth_fb If true, configure the depth/stencil framebuffer. 121 * @param using_depth_fb If true, configure the depth/stencil framebuffer.
123 * @param preserve_contents If true, tries to preserve data from a previously used framebuffer. 122 * @param preserve_contents If true, tries to preserve data from a previously used framebuffer.
124 * @param single_color_target Specifies if a single color buffer target should be used. 123 * @param single_color_target Specifies if a single color buffer target should be used.
124 * @returns If depth (first) or stencil (second) are being stored in the bound zeta texture
125 * (requires using_depth_fb to be true)
125 */ 126 */
126 void ConfigureFramebuffers(OpenGLState& current_state, bool use_color_fb = true, 127 std::pair<bool, bool> ConfigureFramebuffers(
127 bool using_depth_fb = true, bool preserve_contents = true, 128 OpenGLState& current_state, bool use_color_fb = true, bool using_depth_fb = true,
128 std::optional<std::size_t> single_color_target = {}); 129 bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
129 130
130 /// Configures the current constbuffers to use for the draw command. 131 /// Configures the current constbuffers to use for the draw command.
131 void SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, const Shader& shader, 132 void SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, const Shader& shader,
@@ -214,6 +215,7 @@ private:
214 215
215 std::map<FramebufferCacheKey, OGLFramebuffer> framebuffer_cache; 216 std::map<FramebufferCacheKey, OGLFramebuffer> framebuffer_cache;
216 FramebufferConfigState current_framebuffer_config_state; 217 FramebufferConfigState current_framebuffer_config_state;
218 std::pair<bool, bool> current_depth_stencil_usage{};
217 219
218 std::array<SamplerInfo, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_samplers; 220 std::array<SamplerInfo, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_samplers;
219 221
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index c44e2aca2..50286432d 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -128,6 +128,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
128 params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); 128 params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format));
129 params.unaligned_height = config.tic.Height(); 129 params.unaligned_height = config.tic.Height();
130 params.target = SurfaceTargetFromTextureType(config.tic.texture_type); 130 params.target = SurfaceTargetFromTextureType(config.tic.texture_type);
131 params.identity = SurfaceClass::Uploaded;
131 132
132 switch (params.target) { 133 switch (params.target) {
133 case SurfaceTarget::Texture1D: 134 case SurfaceTarget::Texture1D:
@@ -195,6 +196,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
195 params.height = config.height; 196 params.height = config.height;
196 params.unaligned_height = config.height; 197 params.unaligned_height = config.height;
197 params.target = SurfaceTarget::Texture2D; 198 params.target = SurfaceTarget::Texture2D;
199 params.identity = SurfaceClass::RenderTarget;
198 params.depth = 1; 200 params.depth = 1;
199 params.max_mip_level = 1; 201 params.max_mip_level = 1;
200 params.is_layered = false; 202 params.is_layered = false;
@@ -230,6 +232,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
230 params.height = zeta_height; 232 params.height = zeta_height;
231 params.unaligned_height = zeta_height; 233 params.unaligned_height = zeta_height;
232 params.target = SurfaceTarget::Texture2D; 234 params.target = SurfaceTarget::Texture2D;
235 params.identity = SurfaceClass::DepthBuffer;
233 params.depth = 1; 236 params.depth = 1;
234 params.max_mip_level = 1; 237 params.max_mip_level = 1;
235 params.is_layered = false; 238 params.is_layered = false;
@@ -258,6 +261,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
258 params.height = config.height; 261 params.height = config.height;
259 params.unaligned_height = config.height; 262 params.unaligned_height = config.height;
260 params.target = SurfaceTarget::Texture2D; 263 params.target = SurfaceTarget::Texture2D;
264 params.identity = SurfaceClass::Copy;
261 params.depth = 1; 265 params.depth = 1;
262 params.max_mip_level = 1; 266 params.max_mip_level = 1;
263 params.rt = {}; 267 params.rt = {};
@@ -575,8 +579,7 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
575 579
576 ApplyTextureDefaults(SurfaceTargetToGL(params.target), params.max_mip_level); 580 ApplyTextureDefaults(SurfaceTargetToGL(params.target), params.max_mip_level);
577 581
578 LabelGLObject(GL_TEXTURE, texture.handle, params.addr, 582 OpenGL::LabelGLObject(GL_TEXTURE, texture.handle, params.addr, params.IdentityString());
579 SurfaceParams::SurfaceTargetName(params.target));
580 583
581 // Clamp size to mapped GPU memory region 584 // Clamp size to mapped GPU memory region
582 // TODO(bunnei): Super Mario Odyssey maps a 0x40000 byte region and then uses it for a 0x80000 585 // TODO(bunnei): Super Mario Odyssey maps a 0x40000 byte region and then uses it for a 0x80000
@@ -731,7 +734,6 @@ void CachedSurface::FlushGLBuffer() {
731 glPixelStorei(GL_PACK_ROW_LENGTH, 0); 734 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
732 ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer[0], params.pixel_format, params.width, 735 ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer[0], params.pixel_format, params.width,
733 params.height); 736 params.height);
734 ASSERT(params.type != SurfaceType::Fill);
735 const u8* const texture_src_data = Memory::GetPointer(params.addr); 737 const u8* const texture_src_data = Memory::GetPointer(params.addr);
736 ASSERT(texture_src_data); 738 ASSERT(texture_src_data);
737 if (params.is_tiled) { 739 if (params.is_tiled) {
@@ -901,9 +903,6 @@ void CachedSurface::EnsureTextureView() {
901 903
902MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64)); 904MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64));
903void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) { 905void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) {
904 if (params.type == SurfaceType::Fill)
905 return;
906
907 MICROPROFILE_SCOPE(OpenGL_TextureUL); 906 MICROPROFILE_SCOPE(OpenGL_TextureUL);
908 907
909 for (u32 i = 0; i < params.max_mip_level; i++) 908 for (u32 i = 0; i < params.max_mip_level; i++)
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index dae0feb20..8d7d6722c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -35,6 +35,14 @@ using PixelFormat = VideoCore::Surface::PixelFormat;
35using ComponentType = VideoCore::Surface::ComponentType; 35using ComponentType = VideoCore::Surface::ComponentType;
36 36
37struct SurfaceParams { 37struct SurfaceParams {
38
39 enum class SurfaceClass {
40 Uploaded,
41 RenderTarget,
42 DepthBuffer,
43 Copy,
44 };
45
38 static std::string SurfaceTargetName(SurfaceTarget target) { 46 static std::string SurfaceTargetName(SurfaceTarget target) {
39 switch (target) { 47 switch (target) {
40 case SurfaceTarget::Texture1D: 48 case SurfaceTarget::Texture1D:
@@ -210,6 +218,48 @@ struct SurfaceParams {
210 /// Initializes parameters for caching, should be called after everything has been initialized 218 /// Initializes parameters for caching, should be called after everything has been initialized
211 void InitCacheParameters(Tegra::GPUVAddr gpu_addr); 219 void InitCacheParameters(Tegra::GPUVAddr gpu_addr);
212 220
221 std::string TargetName() const {
222 switch (target) {
223 case SurfaceTarget::Texture1D:
224 return "1D";
225 case SurfaceTarget::Texture2D:
226 return "2D";
227 case SurfaceTarget::Texture3D:
228 return "3D";
229 case SurfaceTarget::Texture1DArray:
230 return "1DArray";
231 case SurfaceTarget::Texture2DArray:
232 return "2DArray";
233 case SurfaceTarget::TextureCubemap:
234 return "Cube";
235 default:
236 LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target));
237 UNREACHABLE();
238 return fmt::format("TUK({})", static_cast<u32>(target));
239 }
240 }
241
242 std::string ClassName() const {
243 switch (identity) {
244 case SurfaceClass::Uploaded:
245 return "UP";
246 case SurfaceClass::RenderTarget:
247 return "RT";
248 case SurfaceClass::DepthBuffer:
249 return "DB";
250 case SurfaceClass::Copy:
251 return "CP";
252 default:
253 LOG_CRITICAL(HW_GPU, "Unimplemented surface_class={}", static_cast<u32>(identity));
254 UNREACHABLE();
255 return fmt::format("CUK({})", static_cast<u32>(identity));
256 }
257 }
258
259 std::string IdentityString() const {
260 return ClassName() + '_' + TargetName() + '_' + (is_tiled ? 'T' : 'L');
261 }
262
213 bool is_tiled; 263 bool is_tiled;
214 u32 block_width; 264 u32 block_width;
215 u32 block_height; 265 u32 block_height;
@@ -223,6 +273,7 @@ struct SurfaceParams {
223 u32 depth; 273 u32 depth;
224 u32 unaligned_height; 274 u32 unaligned_height;
225 SurfaceTarget target; 275 SurfaceTarget target;
276 SurfaceClass identity;
226 u32 max_mip_level; 277 u32 max_mip_level;
227 bool is_layered; 278 bool is_layered;
228 bool is_array; 279 bool is_array;
@@ -256,6 +307,7 @@ struct SurfaceReserveKey : Common::HashableStruct<OpenGL::SurfaceParams> {
256 static SurfaceReserveKey Create(const OpenGL::SurfaceParams& params) { 307 static SurfaceReserveKey Create(const OpenGL::SurfaceParams& params) {
257 SurfaceReserveKey res; 308 SurfaceReserveKey res;
258 res.state = params; 309 res.state = params;
310 res.state.identity = {}; // Ignore the origin of the texture
259 res.state.gpu_addr = {}; // Ignore GPU vaddr in caching 311 res.state.gpu_addr = {}; // Ignore GPU vaddr in caching
260 res.state.rt = {}; // Ignore rt config in caching 312 res.state.rt = {}; // Ignore rt config in caching
261 return res; 313 return res;
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
index edd3816ba..b783e4b27 100644
--- a/src/video_core/surface.h
+++ b/src/video_core/surface.h
@@ -109,8 +109,7 @@ enum class SurfaceType {
109 ColorTexture = 0, 109 ColorTexture = 0,
110 Depth = 1, 110 Depth = 1,
111 DepthStencil = 2, 111 DepthStencil = 2,
112 Fill = 3, 112 Invalid = 3,
113 Invalid = 4,
114}; 113};
115 114
116enum class SurfaceTarget { 115enum class SurfaceTarget {
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 0c0864742..f50225d5f 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -13,7 +13,6 @@
13#include "core/hle/kernel/readable_event.h" 13#include "core/hle/kernel/readable_event.h"
14#include "core/hle/kernel/scheduler.h" 14#include "core/hle/kernel/scheduler.h"
15#include "core/hle/kernel/thread.h" 15#include "core/hle/kernel/thread.h"
16#include "core/hle/kernel/timer.h"
17#include "core/hle/kernel/wait_object.h" 16#include "core/hle/kernel/wait_object.h"
18#include "core/memory.h" 17#include "core/memory.h"
19 18
@@ -155,8 +154,6 @@ std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitO
155 switch (object.GetHandleType()) { 154 switch (object.GetHandleType()) {
156 case Kernel::HandleType::ReadableEvent: 155 case Kernel::HandleType::ReadableEvent:
157 return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object)); 156 return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object));
158 case Kernel::HandleType::Timer:
159 return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object));
160 case Kernel::HandleType::Thread: 157 case Kernel::HandleType::Thread:
161 return std::make_unique<WaitTreeThread>(static_cast<const Kernel::Thread&>(object)); 158 return std::make_unique<WaitTreeThread>(static_cast<const Kernel::Thread&>(object));
162 default: 159 default:
@@ -348,23 +345,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const {
348 return list; 345 return list;
349} 346}
350 347
351WaitTreeTimer::WaitTreeTimer(const Kernel::Timer& object) : WaitTreeWaitObject(object) {}
352WaitTreeTimer::~WaitTreeTimer() = default;
353
354std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeTimer::GetChildren() const {
355 std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren());
356
357 const auto& timer = static_cast<const Kernel::Timer&>(object);
358
359 list.push_back(std::make_unique<WaitTreeText>(
360 tr("reset type = %1").arg(GetResetTypeQString(timer.GetResetType()))));
361 list.push_back(
362 std::make_unique<WaitTreeText>(tr("initial delay = %1").arg(timer.GetInitialDelay())));
363 list.push_back(
364 std::make_unique<WaitTreeText>(tr("interval delay = %1").arg(timer.GetIntervalDelay())));
365 return list;
366}
367
368WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list) 348WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list)
369 : thread_list(list) {} 349 : thread_list(list) {}
370WaitTreeThreadList::~WaitTreeThreadList() = default; 350WaitTreeThreadList::~WaitTreeThreadList() = default;
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h
index e639ef412..365c3dbfe 100644
--- a/src/yuzu/debugger/wait_tree.h
+++ b/src/yuzu/debugger/wait_tree.h
@@ -20,7 +20,6 @@ namespace Kernel {
20class ReadableEvent; 20class ReadableEvent;
21class WaitObject; 21class WaitObject;
22class Thread; 22class Thread;
23class Timer;
24} // namespace Kernel 23} // namespace Kernel
25 24
26class WaitTreeThread; 25class WaitTreeThread;
@@ -150,15 +149,6 @@ public:
150 std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; 149 std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
151}; 150};
152 151
153class WaitTreeTimer : public WaitTreeWaitObject {
154 Q_OBJECT
155public:
156 explicit WaitTreeTimer(const Kernel::Timer& object);
157 ~WaitTreeTimer() override;
158
159 std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
160};
161
162class WaitTreeThreadList : public WaitTreeExpandableItem { 152class WaitTreeThreadList : public WaitTreeExpandableItem {
163 Q_OBJECT 153 Q_OBJECT
164public: 154public: