summaryrefslogtreecommitdiffstats
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/am.cpp7
-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.cpp96
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h41
-rw-r--r--src/core/hle/service/psc/psc.cpp17
-rw-r--r--src/core/hle/service/vi/vi.cpp68
-rw-r--r--src/video_core/dma_pusher.h2
-rw-r--r--src/video_core/engines/shader_bytecode.h18
-rw-r--r--src/video_core/rasterizer_interface.h5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp31
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h10
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp5
-rw-r--r--src/video_core/shader/decode/arithmetic.cpp2
-rw-r--r--src/video_core/shader/decode/arithmetic_half.cpp2
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp2
-rw-r--r--src/video_core/shader/decode/conversion.cpp6
-rw-r--r--src/video_core/shader/decode/ffma.cpp4
-rw-r--r--src/video_core/shader/decode/float_set.cpp2
-rw-r--r--src/video_core/shader/decode/float_set_predicate.cpp2
-rw-r--r--src/video_core/shader/decode/hfma2.cpp7
-rw-r--r--src/video_core/shader/decode/integer_set.cpp2
-rw-r--r--src/video_core/shader/decode/integer_set_predicate.cpp2
-rw-r--r--src/video_core/shader/decode/memory.cpp76
-rw-r--r--src/video_core/shader/decode/shift.cpp2
-rw-r--r--src/video_core/shader/decode/xmad.cpp5
-rw-r--r--src/video_core/shader/shader_ir.h2
-rw-r--r--src/video_core/surface.h3
-rw-r--r--src/video_core/textures/texture.h2
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp20
-rw-r--r--src/yuzu/configuration/configure_graphics.h2
-rw-r--r--src/yuzu/debugger/wait_tree.cpp20
-rw-r--r--src/yuzu/debugger/wait_tree.h10
-rw-r--r--src/yuzu/loading_screen.ui5
-rw-r--r--src/yuzu/main.cpp16
56 files changed, 666 insertions, 613 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
hle/kernel/svc_wrap.h
hle/kernel/thread.cpp
hle/kernel/thread.h
- hle/kernel/timer.cpp
- hle/kernel/timer.h
hle/kernel/vm_manager.cpp
hle/kernel/vm_manager.h
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 @@
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h"
-#include "core/hle/kernel/timer.h"
#include "core/hle/lock.h"
#include "core/hle/result.h"
@@ -86,27 +85,12 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_
}
}
-/// The timer callback event, called when a timer is fired
-static void TimerCallback(u64 timer_handle, int cycles_late) {
- const auto proper_handle = static_cast<Handle>(timer_handle);
- const auto& system = Core::System::GetInstance();
- SharedPtr<Timer> timer = system.Kernel().RetrieveTimerFromCallbackHandleTable(proper_handle);
-
- if (timer == nullptr) {
- LOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle);
- return;
- }
-
- timer->Signal(cycles_late);
-}
-
struct KernelCore::Impl {
void Initialize(KernelCore& kernel) {
Shutdown();
InitializeSystemResourceLimit(kernel);
InitializeThreads();
- InitializeTimers();
}
void Shutdown() {
@@ -122,9 +106,6 @@ struct KernelCore::Impl {
thread_wakeup_callback_handle_table.Clear();
thread_wakeup_event_type = nullptr;
- timer_callback_handle_table.Clear();
- timer_callback_event_type = nullptr;
-
named_ports.clear();
}
@@ -146,11 +127,6 @@ struct KernelCore::Impl {
CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
}
- void InitializeTimers() {
- timer_callback_handle_table.Clear();
- timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback);
- }
-
std::atomic<u32> next_object_id{0};
std::atomic<u64> next_process_id{Process::ProcessIDMin};
std::atomic<u64> next_thread_id{1};
@@ -161,12 +137,6 @@ struct KernelCore::Impl {
SharedPtr<ResourceLimit> system_resource_limit;
- /// The event type of the generic timer callback event
- CoreTiming::EventType* timer_callback_event_type = nullptr;
- // TODO(yuriks): This can be removed if Timer objects are explicitly pooled in the future,
- // allowing us to simply use a pool index or similar.
- Kernel::HandleTable timer_callback_handle_table;
-
CoreTiming::EventType* thread_wakeup_event_type = nullptr;
// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
// allowing us to simply use a pool index or similar.
@@ -198,10 +168,6 @@ SharedPtr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(Handle
return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle);
}
-SharedPtr<Timer> KernelCore::RetrieveTimerFromCallbackHandleTable(Handle handle) const {
- return impl->timer_callback_handle_table.Get<Timer>(handle);
-}
-
void KernelCore::AppendNewProcess(SharedPtr<Process> process) {
impl->process_list.push_back(std::move(process));
}
@@ -247,18 +213,10 @@ u64 KernelCore::CreateNewProcessID() {
return impl->next_process_id++;
}
-ResultVal<Handle> KernelCore::CreateTimerCallbackHandle(const SharedPtr<Timer>& timer) {
- return impl->timer_callback_handle_table.Create(timer);
-}
-
CoreTiming::EventType* KernelCore::ThreadWakeupCallbackEventType() const {
return impl->thread_wakeup_event_type;
}
-CoreTiming::EventType* KernelCore::TimerCallbackEventType() const {
- return impl->timer_callback_event_type;
-}
-
Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() {
return impl->thread_wakeup_callback_handle_table;
}
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;
class Process;
class ResourceLimit;
class Thread;
-class Timer;
/// Represents a single instance of the kernel.
class KernelCore {
@@ -51,9 +50,6 @@ public:
/// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
SharedPtr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const;
- /// Retrieves a shared pointer to a Timer instance within the timer callback handle table.
- SharedPtr<Timer> RetrieveTimerFromCallbackHandleTable(Handle handle) const;
-
/// Adds the given shared pointer to an internal list of active processes.
void AppendNewProcess(SharedPtr<Process> process);
@@ -82,7 +78,6 @@ private:
friend class Object;
friend class Process;
friend class Thread;
- friend class Timer;
/// Creates a new object ID, incrementing the internal object ID counter.
u32 CreateNewObjectID();
@@ -93,15 +88,9 @@ private:
/// Creates a new thread ID, incrementing the internal thread ID counter.
u64 CreateNewThreadID();
- /// Creates a timer callback handle for the given timer.
- ResultVal<Handle> CreateTimerCallbackHandle(const SharedPtr<Timer>& timer);
-
/// Retrieves the event type used for thread wakeup callbacks.
CoreTiming::EventType* ThreadWakeupCallbackEventType() const;
- /// Retrieves the event type used for timer callbacks.
- CoreTiming::EventType* TimerCallbackEventType() const;
-
/// Provides a reference to the thread wakeup callback handle table.
Kernel::HandleTable& ThreadWakeupCallbackHandleTable();
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 {
case HandleType::ReadableEvent:
case HandleType::Thread:
case HandleType::Process:
- case HandleType::Timer:
case HandleType::ServerPort:
case HandleType::ServerSession:
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 {
Thread,
Process,
AddressArbiter,
- Timer,
ResourceLimit,
ClientPort,
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() {
return RESULT_SUCCESS;
}
-void ReadableEvent::WakeupAllWaitingThreads() {
- WaitObject::WakeupAllWaitingThreads();
-}
-
} // 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:
bool ShouldWait(Thread* thread) const override;
void Acquire(Thread* thread) override;
- void WakeupAllWaitingThreads() override;
-
/// Unconditionally clears the readable event's state.
void Clear();
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 @@
-// Copyright 2015 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "common/assert.h"
-#include "common/logging/log.h"
-#include "core/core.h"
-#include "core/core_timing.h"
-#include "core/core_timing_util.h"
-#include "core/hle/kernel/handle_table.h"
-#include "core/hle/kernel/kernel.h"
-#include "core/hle/kernel/object.h"
-#include "core/hle/kernel/thread.h"
-#include "core/hle/kernel/timer.h"
-
-namespace Kernel {
-
-Timer::Timer(KernelCore& kernel) : WaitObject{kernel} {}
-Timer::~Timer() = default;
-
-SharedPtr<Timer> Timer::Create(KernelCore& kernel, ResetType reset_type, std::string name) {
- SharedPtr<Timer> timer(new Timer(kernel));
-
- timer->reset_type = reset_type;
- timer->signaled = false;
- timer->name = std::move(name);
- timer->initial_delay = 0;
- timer->interval_delay = 0;
- timer->callback_handle = kernel.CreateTimerCallbackHandle(timer).Unwrap();
-
- return timer;
-}
-
-bool Timer::ShouldWait(Thread* thread) const {
- return !signaled;
-}
-
-void Timer::Acquire(Thread* thread) {
- ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
-
- if (reset_type == ResetType::OneShot)
- signaled = false;
-}
-
-void Timer::Set(s64 initial, s64 interval) {
- // Ensure we get rid of any previous scheduled event
- Cancel();
-
- initial_delay = initial;
- interval_delay = interval;
-
- if (initial == 0) {
- // Immediately invoke the callback
- Signal(0);
- } else {
- CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(initial), kernel.TimerCallbackEventType(),
- callback_handle);
- }
-}
-
-void Timer::Cancel() {
- CoreTiming::UnscheduleEvent(kernel.TimerCallbackEventType(), callback_handle);
-}
-
-void Timer::Clear() {
- signaled = false;
-}
-
-void Timer::WakeupAllWaitingThreads() {
- WaitObject::WakeupAllWaitingThreads();
-}
-
-void Timer::Signal(int cycles_late) {
- LOG_TRACE(Kernel, "Timer {} fired", GetObjectId());
-
- signaled = true;
-
- // Resume all waiting threads
- WakeupAllWaitingThreads();
-
- if (interval_delay != 0) {
- // Reschedule the timer with the interval delay
- CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(interval_delay) - cycles_late,
- kernel.TimerCallbackEventType(), callback_handle);
- }
-}
-
-} // 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 @@
-// Copyright 2015 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include "common/common_types.h"
-#include "core/hle/kernel/object.h"
-#include "core/hle/kernel/wait_object.h"
-
-namespace Kernel {
-
-class KernelCore;
-
-class Timer final : public WaitObject {
-public:
- /**
- * Creates a timer
- * @param kernel The kernel instance to create the timer callback handle for.
- * @param reset_type ResetType describing how to create the timer
- * @param name Optional name of timer
- * @return The created Timer
- */
- static SharedPtr<Timer> Create(KernelCore& kernel, ResetType reset_type,
- std::string name = "Unknown");
-
- std::string GetTypeName() const override {
- return "Timer";
- }
- std::string GetName() const override {
- return name;
- }
-
- static const HandleType HANDLE_TYPE = HandleType::Timer;
- HandleType GetHandleType() const override {
- return HANDLE_TYPE;
- }
-
- ResetType GetResetType() const {
- return reset_type;
- }
-
- u64 GetInitialDelay() const {
- return initial_delay;
- }
-
- u64 GetIntervalDelay() const {
- return interval_delay;
- }
-
- bool ShouldWait(Thread* thread) const override;
- void Acquire(Thread* thread) override;
-
- void WakeupAllWaitingThreads() override;
-
- /**
- * Starts the timer, with the specified initial delay and interval.
- * @param initial Delay until the timer is first fired
- * @param interval Delay until the timer is fired after the first time
- */
- void Set(s64 initial, s64 interval);
-
- void Cancel();
- void Clear();
-
- /**
- * Signals the timer, waking up any waiting threads and rescheduling it
- * for the next interval.
- * This method should not be called from outside the timer callback handler,
- * lest multiple callback events get scheduled.
- */
- void Signal(int cycles_late);
-
-private:
- explicit Timer(KernelCore& kernel);
- ~Timer() override;
-
- ResetType reset_type; ///< The ResetType of this timer
-
- u64 initial_delay; ///< The delay until the timer fires for the first time
- u64 interval_delay; ///< The delay until the timer fires after the first time
-
- bool signaled; ///< Whether the timer has been signaled or not
- std::string name; ///< Name of timer (optional)
-
- /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
- Handle callback_handle;
-};
-
-} // 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:
* Add a thread to wait on this object
* @param thread Pointer to thread to add
*/
- virtual void AddWaitingThread(SharedPtr<Thread> thread);
+ void AddWaitingThread(SharedPtr<Thread> thread);
/**
* Removes a thread from waiting on this object (e.g. if it was resumed already)
* @param thread Pointer to thread to remove
*/
- virtual void RemoveWaitingThread(Thread* thread);
+ void RemoveWaitingThread(Thread* thread);
/**
* Wake up all threads waiting on this object that can be awoken, in priority order,
* and set the synchronization result and output of the thread.
*/
- virtual void WakeupAllWaitingThreads();
+ void WakeupAllWaitingThreads();
/**
* Wakes up a single thread waiting on this object.
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index d1cbe0e44..3f009d2b7 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -322,14 +322,15 @@ void ISelfController::SetScreenShotImageOrientation(Kernel::HLERequestContext& c
void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
+
// TODO(Subv): Find out how AM determines the display to use, for now just
// create the layer in the Default display.
- u64 display_id = nvflinger->OpenDisplay("Default");
- u64 layer_id = nvflinger->CreateLayer(display_id);
+ const auto display_id = nvflinger->OpenDisplay("Default");
+ const auto layer_id = nvflinger->CreateLayer(*display_id);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.Push(layer_id);
+ rb.Push(*layer_id);
}
void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) {
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,
{300, nullptr, "OpenOverlayAppletProxy"},
{350, nullptr, "OpenSystemApplicationProxy"},
{400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"},
- {401, nullptr, "GetSystemAppletControllerForDebug"},
+ {410, nullptr, "GetSystemAppletControllerForDebug"},
+ {1000, nullptr, "GetDebugFunctions"},
};
// clang-format on
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 {
class IAudioIn final : public ServiceFramework<IAudioIn> {
public:
IAudioIn() : ServiceFramework("IAudioIn") {
+ // clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetAudioInState"},
{1, nullptr, "StartAudioIn"},
@@ -28,16 +29,24 @@ public:
{12, nullptr, "SetAudioInDeviceGain"},
{13, nullptr, "GetAudioInDeviceGain"},
};
+ // clang-format on
+
RegisterHandlers(functions);
}
~IAudioIn() = default;
};
AudInU::AudInU() : ServiceFramework("audin:u") {
+ // clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "ListAudioIns"}, {1, nullptr, "OpenAudioIn"}, {2, nullptr, "Unknown"},
- {3, nullptr, "OpenAudioInAuto"}, {4, nullptr, "ListAudioInsAuto"},
+ {0, nullptr, "ListAudioIns"},
+ {1, nullptr, "OpenAudioIn"},
+ {2, nullptr, "Unknown"},
+ {3, nullptr, "OpenAudioInAuto"},
+ {4, nullptr, "ListAudioInsAuto"},
};
+ // clang-format on
+
RegisterHandlers(functions);
}
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 {
class IFinalOutputRecorder final : public ServiceFramework<IFinalOutputRecorder> {
public:
IFinalOutputRecorder() : ServiceFramework("IFinalOutputRecorder") {
+ // clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetFinalOutputRecorderState"},
{1, nullptr, "StartFinalOutputRecorder"},
@@ -20,10 +21,13 @@ public:
{4, nullptr, "RegisterBufferEvent"},
{5, nullptr, "GetReleasedFinalOutputRecorderBuffer"},
{6, nullptr, "ContainsFinalOutputRecorderBuffer"},
- {7, nullptr, "Unknown"},
+ {7, nullptr, "GetFinalOutputRecorderBufferEndTime"},
{8, nullptr, "AppendFinalOutputRecorderBufferAuto"},
{9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"},
+ {10, nullptr, "FlushFinalOutputRecorderBuffers"},
};
+ // clang-format on
+
RegisterHandlers(functions);
}
~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:
}; // namespace Audio
AudRenU::AudRenU() : ServiceFramework("audren:u") {
+ // clang-format off
static const FunctionInfo functions[] = {
{0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"},
{1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"},
- {2, &AudRenU::GetAudioDevice, "GetAudioDevice"},
+ {2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"},
{3, nullptr, "OpenAudioRendererAuto"},
- {4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo,
- "GetAudioDeviceServiceWithRevisionInfo"},
+ {4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"},
};
+ // clang-format on
+
RegisterHandlers(functions);
}
@@ -313,7 +315,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "buffer_size=0x{:X}", output_sz);
}
-void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) {
+void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
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:
private:
void OpenAudioRenderer(Kernel::HLERequestContext& ctx);
void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx);
- void GetAudioDevice(Kernel::HLERequestContext& ctx);
+ void GetAudioDeviceService(Kernel::HLERequestContext& ctx);
void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx);
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 @@
#include <chrono>
#include <cstring>
#include <memory>
-#include <optional>
#include <vector>
#include <opus.h>
@@ -30,48 +29,66 @@ public:
u32 channel_count)
: ServiceFramework("IHardwareOpusDecoderManager"), decoder(std::move(decoder)),
sample_rate(sample_rate), channel_count(channel_count) {
+ // clang-format off
static const FunctionInfo functions[] = {
- {0, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"},
+ {0, &IHardwareOpusDecoderManager::DecodeInterleavedOld, "DecodeInterleavedOld"},
{1, nullptr, "SetContext"},
- {2, nullptr, "DecodeInterleavedForMultiStream"},
+ {2, nullptr, "DecodeInterleavedForMultiStreamOld"},
{3, nullptr, "SetContextForMultiStream"},
- {4, &IHardwareOpusDecoderManager::DecodeInterleavedWithPerformance,
- "DecodeInterleavedWithPerformance"},
- {5, nullptr, "Unknown5"},
- {6, nullptr, "Unknown6"},
- {7, nullptr, "Unknown7"},
+ {4, &IHardwareOpusDecoderManager::DecodeInterleavedWithPerfOld, "DecodeInterleavedWithPerfOld"},
+ {5, nullptr, "DecodeInterleavedForMultiStreamWithPerfOld"},
+ {6, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"},
+ {7, nullptr, "DecodeInterleavedForMultiStream"},
};
+ // clang-format on
+
RegisterHandlers(functions);
}
private:
- void DecodeInterleaved(Kernel::HLERequestContext& ctx) {
+ /// Describes extra behavior that may be asked of the decoding context.
+ enum class ExtraBehavior {
+ /// No extra behavior.
+ None,
+
+ /// Resets the decoder context back to a freshly initialized state.
+ ResetContext,
+ };
+
+ void DecodeInterleavedOld(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Audio, "called");
- u32 consumed = 0;
- u32 sample_count = 0;
- std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16));
- if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples)) {
- LOG_ERROR(Audio, "Failed to decode opus data");
- IPC::ResponseBuilder rb{ctx, 2};
- // TODO(ogniK): Use correct error code
- rb.Push(ResultCode(-1));
- return;
- }
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(RESULT_SUCCESS);
- rb.Push<u32>(consumed);
- rb.Push<u32>(sample_count);
- ctx.WriteBuffer(samples.data(), samples.size() * sizeof(s16));
+ DecodeInterleavedHelper(ctx, nullptr, ExtraBehavior::None);
}
- void DecodeInterleavedWithPerformance(Kernel::HLERequestContext& ctx) {
+ void DecodeInterleavedWithPerfOld(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Audio, "called");
+
+ u64 performance = 0;
+ DecodeInterleavedHelper(ctx, &performance, ExtraBehavior::None);
+ }
+
+ void DecodeInterleaved(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Audio, "called");
+ IPC::RequestParser rp{ctx};
+ const auto extra_behavior =
+ rp.Pop<bool>() ? ExtraBehavior::ResetContext : ExtraBehavior::None;
+
+ u64 performance = 0;
+ DecodeInterleavedHelper(ctx, &performance, extra_behavior);
+ }
+
+ void DecodeInterleavedHelper(Kernel::HLERequestContext& ctx, u64* performance,
+ ExtraBehavior extra_behavior) {
u32 consumed = 0;
u32 sample_count = 0;
- u64 performance = 0;
std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16));
+
+ if (extra_behavior == ExtraBehavior::ResetContext) {
+ ResetDecoderContext();
+ }
+
if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples,
performance)) {
LOG_ERROR(Audio, "Failed to decode opus data");
@@ -80,25 +97,28 @@ private:
rb.Push(ResultCode(-1));
return;
}
- IPC::ResponseBuilder rb{ctx, 6};
+
+ const u32 param_size = performance != nullptr ? 6 : 4;
+ IPC::ResponseBuilder rb{ctx, param_size};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(consumed);
rb.Push<u32>(sample_count);
- rb.Push<u64>(performance);
+ if (performance) {
+ rb.Push<u64>(*performance);
+ }
ctx.WriteBuffer(samples.data(), samples.size() * sizeof(s16));
}
- bool Decoder_DecodeInterleaved(
- u32& consumed, u32& sample_count, const std::vector<u8>& input,
- std::vector<opus_int16>& output,
- std::optional<std::reference_wrapper<u64>> performance_time = std::nullopt) {
+ bool Decoder_DecodeInterleaved(u32& consumed, u32& sample_count, const std::vector<u8>& input,
+ std::vector<opus_int16>& output, u64* out_performance_time) {
const auto start_time = std::chrono::high_resolution_clock::now();
- std::size_t raw_output_sz = output.size() * sizeof(opus_int16);
+ const std::size_t raw_output_sz = output.size() * sizeof(opus_int16);
if (sizeof(OpusHeader) > input.size()) {
LOG_ERROR(Audio, "Input is smaller than the header size, header_sz={}, input_sz={}",
sizeof(OpusHeader), input.size());
return false;
}
+
OpusHeader hdr{};
std::memcpy(&hdr, input.data(), sizeof(OpusHeader));
if (sizeof(OpusHeader) + static_cast<u32>(hdr.sz) > input.size()) {
@@ -106,8 +126,9 @@ private:
sizeof(OpusHeader) + static_cast<u32>(hdr.sz), input.size());
return false;
}
- auto frame = input.data() + sizeof(OpusHeader);
- auto decoded_sample_count = opus_packet_get_nb_samples(
+
+ const auto frame = input.data() + sizeof(OpusHeader);
+ const auto decoded_sample_count = opus_packet_get_nb_samples(
frame, static_cast<opus_int32>(input.size() - sizeof(OpusHeader)),
static_cast<opus_int32>(sample_rate));
if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz) {
@@ -117,8 +138,9 @@ private:
decoded_sample_count * channel_count * sizeof(u16), raw_output_sz);
return false;
}
+
const int frame_size = (static_cast<int>(raw_output_sz / sizeof(s16) / channel_count));
- auto out_sample_count =
+ const auto out_sample_count =
opus_decode(decoder.get(), frame, hdr.sz, output.data(), frame_size, 0);
if (out_sample_count < 0) {
LOG_ERROR(Audio,
@@ -127,16 +149,24 @@ private:
out_sample_count, frame_size, static_cast<u32>(hdr.sz));
return false;
}
+
const auto end_time = std::chrono::high_resolution_clock::now() - start_time;
sample_count = out_sample_count;
consumed = static_cast<u32>(sizeof(OpusHeader) + hdr.sz);
- if (performance_time.has_value()) {
- performance_time->get() =
+ if (out_performance_time != nullptr) {
+ *out_performance_time =
std::chrono::duration_cast<std::chrono::milliseconds>(end_time).count();
}
+
return true;
}
+ void ResetDecoderContext() {
+ ASSERT(decoder != nullptr);
+
+ opus_decoder_ctl(decoder.get(), OPUS_RESET_STATE);
+ }
+
struct OpusHeader {
u32_be sz; // Needs to be BE for some odd reason
INSERT_PADDING_WORDS(1);
@@ -157,6 +187,7 @@ void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto sample_rate = rp.Pop<u32>();
const auto channel_count = rp.Pop<u32>();
+
LOG_DEBUG(Audio, "called with sample_rate={}, channel_count={}", sample_rate, channel_count);
ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
@@ -174,9 +205,10 @@ void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- auto sample_rate = rp.Pop<u32>();
- auto channel_count = rp.Pop<u32>();
- auto buffer_sz = rp.Pop<u32>();
+ const auto sample_rate = rp.Pop<u32>();
+ const auto channel_count = rp.Pop<u32>();
+ const auto buffer_sz = rp.Pop<u32>();
+
LOG_DEBUG(Audio, "called sample_rate={}, channel_count={}, buffer_size={}", sample_rate,
channel_count, buffer_sz);
@@ -185,8 +217,9 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
"Invalid sample rate");
ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
- std::size_t worker_sz = WorkerBufferSize(channel_count);
+ const std::size_t worker_sz = WorkerBufferSize(channel_count);
ASSERT_MSG(buffer_sz >= worker_sz, "Worker buffer too large");
+
std::unique_ptr<OpusDecoder, OpusDeleter> decoder{
static_cast<OpusDecoder*>(operator new(worker_sz))};
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:
explicit Bt() : ServiceFramework{"bt"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "Unknown0"},
- {1, nullptr, "Unknown1"},
- {2, nullptr, "Unknown2"},
- {3, nullptr, "Unknown3"},
- {4, nullptr, "Unknown4"},
- {5, nullptr, "Unknown5"},
- {6, nullptr, "Unknown6"},
- {7, nullptr, "Unknown7"},
- {8, nullptr, "Unknown8"},
- {9, &Bt::RegisterEvent, "RegisterEvent"},
+ {0, nullptr, "LeClientReadCharacteristic"},
+ {1, nullptr, "LeClientReadDescriptor"},
+ {2, nullptr, "LeClientWriteCharacteristic"},
+ {3, nullptr, "LeClientWriteDescriptor"},
+ {4, nullptr, "LeClientRegisterNotification"},
+ {5, nullptr, "LeClientDeregisterNotification"},
+ {6, nullptr, "SetLeResponse"},
+ {7, nullptr, "LeSendIndication"},
+ {8, nullptr, "GetLeEventInfo"},
+ {9, &Bt::RegisterBleEvent, "RegisterBleEvent"},
};
// clang-format on
RegisterHandlers(functions);
@@ -39,7 +39,7 @@ public:
}
private:
- void RegisterEvent(Kernel::HLERequestContext& ctx) {
+ void RegisterBleEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -55,11 +55,11 @@ public:
explicit BtDrv() : ServiceFramework{"btdrv"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "Unknown"},
- {1, nullptr, "Init"},
- {2, nullptr, "Enable"},
- {3, nullptr, "Disable"},
- {4, nullptr, "CleanupAndShutdown"},
+ {0, nullptr, "InitializeBluetoothDriver"},
+ {1, nullptr, "InitializeBluetooth"},
+ {2, nullptr, "EnableBluetooth"},
+ {3, nullptr, "DisableBluetooth"},
+ {4, nullptr, "CleanupBluetooth"},
{5, nullptr, "GetAdapterProperties"},
{6, nullptr, "GetAdapterProperty"},
{7, nullptr, "SetAdapterProperty"},
@@ -70,36 +70,91 @@ public:
{12, nullptr, "CancelBond"},
{13, nullptr, "PinReply"},
{14, nullptr, "SspReply"},
- {15, nullptr, "Unknown2"},
- {16, nullptr, "InitInterfaces"},
- {17, nullptr, "HidHostInterface_Connect"},
- {18, nullptr, "HidHostInterface_Disconnect"},
- {19, nullptr, "HidHostInterface_SendData"},
- {20, nullptr, "HidHostInterface_SendData2"},
- {21, nullptr, "HidHostInterface_SetReport"},
- {22, nullptr, "HidHostInterface_GetReport"},
- {23, nullptr, "HidHostInterface_WakeController"},
- {24, nullptr, "HidHostInterface_AddPairedDevice"},
- {25, nullptr, "HidHostInterface_GetPairedDevice"},
- {26, nullptr, "HidHostInterface_CleanupAndShutdown"},
- {27, nullptr, "Unknown3"},
- {28, nullptr, "ExtInterface_SetTSI"},
- {29, nullptr, "ExtInterface_SetBurstMode"},
- {30, nullptr, "ExtInterface_SetZeroRetran"},
- {31, nullptr, "ExtInterface_SetMcMode"},
- {32, nullptr, "ExtInterface_StartLlrMode"},
- {33, nullptr, "ExtInterface_ExitLlrMode"},
- {34, nullptr, "ExtInterface_SetRadio"},
- {35, nullptr, "ExtInterface_SetVisibility"},
- {36, nullptr, "Unknown4"},
- {37, nullptr, "Unknown5"},
- {38, nullptr, "HidHostInterface_GetLatestPlr"},
- {39, nullptr, "ExtInterface_GetPendingConnections"},
- {40, nullptr, "HidHostInterface_GetChannelMap"},
- {41, nullptr, "SetIsBluetoothBoostEnabled"},
- {42, nullptr, "GetIsBluetoothBoostEnabled"},
- {43, nullptr, "SetIsBluetoothAfhEnabled"},
- {44, nullptr, "GetIsBluetoothAfhEnabled"},
+ {15, nullptr, "GetEventInfo"},
+ {16, nullptr, "InitializeHid"},
+ {17, nullptr, "HidConnect"},
+ {18, nullptr, "HidDisconnect"},
+ {19, nullptr, "HidSendData"},
+ {20, nullptr, "HidSendData2"},
+ {21, nullptr, "HidSetReport"},
+ {22, nullptr, "HidGetReport"},
+ {23, nullptr, "HidWakeController"},
+ {24, nullptr, "HidAddPairedDevice"},
+ {25, nullptr, "HidGetPairedDevice"},
+ {26, nullptr, "CleanupHid"},
+ {27, nullptr, "HidGetEventInfo"},
+ {28, nullptr, "ExtSetTsi"},
+ {29, nullptr, "ExtSetBurstMode"},
+ {30, nullptr, "ExtSetZeroRetran"},
+ {31, nullptr, "ExtSetMcMode"},
+ {32, nullptr, "ExtStartLlrMode"},
+ {33, nullptr, "ExtExitLlrMode"},
+ {34, nullptr, "ExtSetRadio"},
+ {35, nullptr, "ExtSetVisibility"},
+ {36, nullptr, "ExtSetTbfcScan"},
+ {37, nullptr, "RegisterHidReportEvent"},
+ {38, nullptr, "HidGetReportEventInfo"},
+ {39, nullptr, "GetLatestPlr"},
+ {40, nullptr, "ExtGetPendingConnections"},
+ {41, nullptr, "GetChannelMap"},
+ {42, nullptr, "EnableBluetoothBoostSetting"},
+ {43, nullptr, "IsBluetoothBoostSettingEnabled"},
+ {44, nullptr, "EnableBluetoothAfhSetting"},
+ {45, nullptr, "IsBluetoothAfhSettingEnabled"},
+ {46, nullptr, "InitializeBluetoothLe"},
+ {47, nullptr, "EnableBluetoothLe"},
+ {48, nullptr, "DisableBluetoothLe"},
+ {49, nullptr, "CleanupBluetoothLe"},
+ {50, nullptr, "SetLeVisibility"},
+ {51, nullptr, "SetLeConnectionParameter"},
+ {52, nullptr, "SetLeDefaultConnectionParameter"},
+ {53, nullptr, "SetLeAdvertiseData"},
+ {54, nullptr, "SetLeAdvertiseParameter"},
+ {55, nullptr, "StartLeScan"},
+ {56, nullptr, "StopLeScan"},
+ {57, nullptr, "AddLeScanFilterCondition"},
+ {58, nullptr, "DeleteLeScanFilterCondition"},
+ {59, nullptr, "DeleteLeScanFilter"},
+ {60, nullptr, "ClearLeScanFilters"},
+ {61, nullptr, "EnableLeScanFilter"},
+ {62, nullptr, "RegisterLeClient"},
+ {63, nullptr, "UnregisterLeClient"},
+ {64, nullptr, "UnregisterLeClientAll"},
+ {65, nullptr, "LeClientConnect"},
+ {66, nullptr, "LeClientCancelConnection"},
+ {67, nullptr, "LeClientDisconnect"},
+ {68, nullptr, "LeClientGetAttributes"},
+ {69, nullptr, "LeClientDiscoverService"},
+ {70, nullptr, "LeClientConfigureMtu"},
+ {71, nullptr, "RegisterLeServer"},
+ {72, nullptr, "UnregisterLeServer"},
+ {73, nullptr, "LeServerConnect"},
+ {74, nullptr, "LeServerDisconnect"},
+ {75, nullptr, "CreateLeService"},
+ {76, nullptr, "StartLeService"},
+ {77, nullptr, "AddLeCharacteristic"},
+ {78, nullptr, "AddLeDescriptor"},
+ {79, nullptr, "GetLeCoreEventInfo"},
+ {80, nullptr, "LeGetFirstCharacteristic"},
+ {81, nullptr, "LeGetNextCharacteristic"},
+ {82, nullptr, "LeGetFirstDescriptor"},
+ {83, nullptr, "LeGetNextDescriptor"},
+ {84, nullptr, "RegisterLeCoreDataPath"},
+ {85, nullptr, "UnregisterLeCoreDataPath"},
+ {86, nullptr, "RegisterLeHidDataPath"},
+ {87, nullptr, "UnregisterLeHidDataPath"},
+ {88, nullptr, "RegisterLeDataPath"},
+ {89, nullptr, "UnregisterLeDataPath"},
+ {90, nullptr, "LeClientReadCharacteristic"},
+ {91, nullptr, "LeClientReadDescriptor"},
+ {92, nullptr, "LeClientWriteCharacteristic"},
+ {93, nullptr, "LeClientWriteDescriptor"},
+ {94, nullptr, "LeClientRegisterNotification"},
+ {95, nullptr, "LeClientDeregisterNotification"},
+ {96, nullptr, "GetLeHidEventInfo"},
+ {97, nullptr, "RegisterBleHidEvent"},
+ {98, nullptr, "SetLeScanParameter"},
+ {256, nullptr, "GetIsManufacturingMode"}
};
// clang-format on
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:
explicit IBtmUserCore() : ServiceFramework{"IBtmUserCore"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &IBtmUserCore::GetScanEvent, "GetScanEvent"},
- {1, nullptr, "Unknown1"},
- {2, nullptr, "Unknown2"},
- {3, nullptr, "Unknown3"},
- {4, nullptr, "Unknown4"},
- {5, nullptr, "Unknown5"},
- {6, nullptr, "Unknown6"},
- {7, nullptr, "Unknown7"},
- {8, nullptr, "Unknown8"},
- {9, nullptr, "Unknown9"},
- {10, nullptr, "Unknown10"},
- {17, &IBtmUserCore::GetConnectionEvent, "GetConnectionEvent"},
- {18, nullptr, "Unknown18"},
- {19, nullptr, "Unknown19"},
- {20, nullptr, "Unknown20"},
- {21, nullptr, "Unknown21"},
- {22, nullptr, "Unknown22"},
- {23, nullptr, "Unknown23"},
- {24, nullptr, "Unknown24"},
- {25, nullptr, "Unknown25"},
- {26, &IBtmUserCore::GetDiscoveryEvent, "AcquireBleServiceDiscoveryEventImpl"},
- {27, nullptr, "Unknown27"},
- {28, nullptr, "Unknown28"},
- {29, nullptr, "Unknown29"},
- {30, nullptr, "Unknown30"},
- {31, nullptr, "Unknown31"},
- {32, nullptr, "Unknown32"},
- {33, &IBtmUserCore::GetConfigEvent, "GetConfigEvent"},
- {34, nullptr, "Unknown34"},
- {35, nullptr, "Unknown35"},
- {36, nullptr, "Unknown36"},
- {37, nullptr, "Unknown37"},
+ {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"},
+ {1, nullptr, "GetBleScanFilterParameter"},
+ {2, nullptr, "GetBleScanFilterParameter2"},
+ {3, nullptr, "StartBleScanForGeneral"},
+ {4, nullptr, "StopBleScanForGeneral"},
+ {5, nullptr, "GetBleScanResultsForGeneral"},
+ {6, nullptr, "StartBleScanForPaired"},
+ {7, nullptr, "StopBleScanForPaired"},
+ {8, nullptr, "StartBleScanForSmartDevice"},
+ {9, nullptr, "StopBleScanForSmartDevice"},
+ {10, nullptr, "GetBleScanResultsForSmartDevice"},
+ {17, &IBtmUserCore::AcquireBleConnectionEvent, "AcquireBleConnectionEvent"},
+ {18, nullptr, "BleConnect"},
+ {19, nullptr, "BleDisconnect"},
+ {20, nullptr, "BleGetConnectionState"},
+ {21, nullptr, "AcquireBlePairingEvent"},
+ {22, nullptr, "BlePairDevice"},
+ {23, nullptr, "BleUnPairDevice"},
+ {24, nullptr, "BleUnPairDevice2"},
+ {25, nullptr, "BleGetPairedDevices"},
+ {26, &IBtmUserCore::AcquireBleServiceDiscoveryEvent, "AcquireBleServiceDiscoveryEvent"},
+ {27, nullptr, "GetGattServices"},
+ {28, nullptr, "GetGattService"},
+ {29, nullptr, "GetGattIncludedServices"},
+ {30, nullptr, "GetBelongingGattService"},
+ {31, nullptr, "GetGattCharacteristics"},
+ {32, nullptr, "GetGattDescriptors"},
+ {33, &IBtmUserCore::AcquireBleMtuConfigEvent, "AcquireBleMtuConfigEvent"},
+ {34, nullptr, "ConfigureBleMtu"},
+ {35, nullptr, "GetBleMtu"},
+ {36, nullptr, "RegisterBleGattDataPath"},
+ {37, nullptr, "UnregisterBleGattDataPath"},
};
// clang-format on
RegisterHandlers(functions);
@@ -68,7 +68,7 @@ public:
}
private:
- void GetScanEvent(Kernel::HLERequestContext& ctx) {
+ void AcquireBleScanEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -76,7 +76,7 @@ private:
rb.PushCopyObjects(scan_event.readable);
}
- void GetConnectionEvent(Kernel::HLERequestContext& ctx) {
+ void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -84,7 +84,7 @@ private:
rb.PushCopyObjects(connection_event.readable);
}
- void GetDiscoveryEvent(Kernel::HLERequestContext& ctx) {
+ void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -92,7 +92,7 @@ private:
rb.PushCopyObjects(service_discovery.readable);
}
- void GetConfigEvent(Kernel::HLERequestContext& ctx) {
+ void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -111,14 +111,14 @@ public:
explicit BTM_USR() : ServiceFramework{"btm:u"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &BTM_USR::GetCoreImpl, "GetCoreImpl"},
+ {0, &BTM_USR::GetCore, "GetCore"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
- void GetCoreImpl(Kernel::HLERequestContext& ctx) {
+ void GetCore(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -134,26 +134,64 @@ public:
static const FunctionInfo functions[] = {
{0, nullptr, "Unknown1"},
{1, nullptr, "Unknown2"},
- {2, nullptr, "RegisterSystemEventForConnectedDeviceConditionImpl"},
+ {2, nullptr, "RegisterSystemEventForConnectedDeviceCondition"},
{3, nullptr, "Unknown3"},
{4, nullptr, "Unknown4"},
{5, nullptr, "Unknown5"},
{6, nullptr, "Unknown6"},
{7, nullptr, "Unknown7"},
- {8, nullptr, "RegisterSystemEventForRegisteredDeviceInfoImpl"},
+ {8, nullptr, "RegisterSystemEventForRegisteredDeviceInfo"},
{9, nullptr, "Unknown8"},
{10, nullptr, "Unknown9"},
{11, nullptr, "Unknown10"},
{12, nullptr, "Unknown11"},
{13, nullptr, "Unknown12"},
- {14, nullptr, "EnableRadioImpl"},
- {15, nullptr, "DisableRadioImpl"},
+ {14, nullptr, "EnableRadio"},
+ {15, nullptr, "DisableRadio"},
{16, nullptr, "Unknown13"},
{17, nullptr, "Unknown14"},
{18, nullptr, "Unknown15"},
{19, nullptr, "Unknown16"},
{20, nullptr, "Unknown17"},
{21, nullptr, "Unknown18"},
+ {22, nullptr, "Unknown19"},
+ {23, nullptr, "Unknown20"},
+ {24, nullptr, "Unknown21"},
+ {25, nullptr, "Unknown22"},
+ {26, nullptr, "Unknown23"},
+ {27, nullptr, "Unknown24"},
+ {28, nullptr, "Unknown25"},
+ {29, nullptr, "Unknown26"},
+ {30, nullptr, "Unknown27"},
+ {31, nullptr, "Unknown28"},
+ {32, nullptr, "Unknown29"},
+ {33, nullptr, "Unknown30"},
+ {34, nullptr, "Unknown31"},
+ {35, nullptr, "Unknown32"},
+ {36, nullptr, "Unknown33"},
+ {37, nullptr, "Unknown34"},
+ {38, nullptr, "Unknown35"},
+ {39, nullptr, "Unknown36"},
+ {40, nullptr, "Unknown37"},
+ {41, nullptr, "Unknown38"},
+ {42, nullptr, "Unknown39"},
+ {43, nullptr, "Unknown40"},
+ {44, nullptr, "Unknown41"},
+ {45, nullptr, "Unknown42"},
+ {46, nullptr, "Unknown43"},
+ {47, nullptr, "Unknown44"},
+ {48, nullptr, "Unknown45"},
+ {49, nullptr, "Unknown46"},
+ {50, nullptr, "Unknown47"},
+ {51, nullptr, "Unknown48"},
+ {52, nullptr, "Unknown49"},
+ {53, nullptr, "Unknown50"},
+ {54, nullptr, "Unknown51"},
+ {55, nullptr, "Unknown52"},
+ {56, nullptr, "Unknown53"},
+ {57, nullptr, "Unknown54"},
+ {58, nullptr, "Unknown55"},
+ {59, nullptr, "Unknown56"},
};
// clang-format on
@@ -166,7 +204,7 @@ public:
explicit BTM_DBG() : ServiceFramework{"btm:dbg"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "RegisterSystemEventForDiscoveryImpl"},
+ {0, nullptr, "RegisterSystemEventForDiscovery"},
{1, nullptr, "Unknown1"},
{2, nullptr, "Unknown2"},
{3, nullptr, "Unknown3"},
@@ -175,6 +213,10 @@ public:
{6, nullptr, "Unknown6"},
{7, nullptr, "Unknown7"},
{8, nullptr, "Unknown8"},
+ {9, nullptr, "Unknown9"},
+ {10, nullptr, "Unknown10"},
+ {11, nullptr, "Unknown11"},
+ {12, nullptr, "Unknown11"},
};
// clang-format on
@@ -187,16 +229,16 @@ public:
explicit IBtmSystemCore() : ServiceFramework{"IBtmSystemCore"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "StartGamepadPairingImpl"},
- {1, nullptr, "CancelGamepadPairingImpl"},
- {2, nullptr, "ClearGamepadPairingDatabaseImpl"},
- {3, nullptr, "GetPairedGamepadCountImpl"},
- {4, nullptr, "EnableRadioImpl"},
- {5, nullptr, "DisableRadioImpl"},
- {6, nullptr, "GetRadioOnOffImpl"},
- {7, nullptr, "AcquireRadioEventImpl"},
- {8, nullptr, "AcquireGamepadPairingEventImpl"},
- {9, nullptr, "IsGamepadPairingStartedImpl"},
+ {0, nullptr, "StartGamepadPairing"},
+ {1, nullptr, "CancelGamepadPairing"},
+ {2, nullptr, "ClearGamepadPairingDatabase"},
+ {3, nullptr, "GetPairedGamepadCount"},
+ {4, nullptr, "EnableRadio"},
+ {5, nullptr, "DisableRadio"},
+ {6, nullptr, "GetRadioOnOff"},
+ {7, nullptr, "AcquireRadioEvent"},
+ {8, nullptr, "AcquireGamepadPairingEvent"},
+ {9, nullptr, "IsGamepadPairingStarted"},
};
// clang-format on
@@ -209,7 +251,7 @@ public:
explicit BTM_SYS() : ServiceFramework{"btm:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &BTM_SYS::GetCoreImpl, "GetCoreImpl"},
+ {0, &BTM_SYS::GetCore, "GetCore"},
};
// clang-format on
@@ -217,7 +259,7 @@ public:
}
private:
- void GetCoreImpl(Kernel::HLERequestContext& ctx) {
+ void GetCore(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_BTM, "called");
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:
FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "MountContent"},
- {1, &FSP_SRV::Initialize, "Initialize"},
+ {0, nullptr, "OpenFileSystem"},
+ {1, &FSP_SRV::SetCurrentProcess, "SetCurrentProcess"},
{2, nullptr, "OpenDataFileSystemByCurrentProcess"},
{7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"},
{8, nullptr, "OpenFileSystemWithId"},
@@ -637,10 +637,10 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
{12, nullptr, "OpenBisStorage"},
{13, nullptr, "InvalidateBisCache"},
{17, nullptr, "OpenHostFileSystem"},
- {18, &FSP_SRV::MountSdCard, "MountSdCard"},
+ {18, &FSP_SRV::OpenSdCardFileSystem, "OpenSdCardFileSystem"},
{19, nullptr, "FormatSdCardFileSystem"},
{21, nullptr, "DeleteSaveDataFileSystem"},
- {22, &FSP_SRV::CreateSaveData, "CreateSaveData"},
+ {22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"},
{23, nullptr, "CreateSaveDataFileSystemBySystemSaveDataId"},
{24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"},
{25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"},
@@ -652,7 +652,8 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
{32, nullptr, "ExtendSaveDataFileSystem"},
{33, nullptr, "DeleteCacheStorage"},
{34, nullptr, "GetCacheStorageSize"},
- {51, &FSP_SRV::MountSaveData, "MountSaveData"},
+ {35, nullptr, "CreateSaveDataFileSystemByHashSalt"},
+ {51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"},
{52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"},
{53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"},
{57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"},
@@ -664,21 +665,26 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
{64, nullptr, "OpenSaveDataInternalStorageFileSystem"},
{65, nullptr, "UpdateSaveDataMacForDebug"},
{66, nullptr, "WriteSaveDataFileSystemExtraData2"},
+ {67, nullptr, "FindSaveDataWithFilter"},
+ {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"},
{80, nullptr, "OpenSaveDataMetaFile"},
{81, nullptr, "OpenSaveDataTransferManager"},
{82, nullptr, "OpenSaveDataTransferManagerVersion2"},
{83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"},
+ {84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"},
{100, nullptr, "OpenImageDirectoryFileSystem"},
{110, nullptr, "OpenContentStorageFileSystem"},
+ {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
{200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
{201, nullptr, "OpenDataStorageByProgramId"},
{202, &FSP_SRV::OpenDataStorageByDataId, "OpenDataStorageByDataId"},
- {203, &FSP_SRV::OpenRomStorage, "OpenRomStorage"},
+ {203, &FSP_SRV::OpenPatchDataStorageByCurrentProcess, "OpenPatchDataStorageByCurrentProcess"},
{400, nullptr, "OpenDeviceOperator"},
{500, nullptr, "OpenSdCardDetectionEventNotifier"},
{501, nullptr, "OpenGameCardDetectionEventNotifier"},
{510, nullptr, "OpenSystemDataUpdateEventNotifier"},
{511, nullptr, "NotifySystemDataUpdateEvent"},
+ {520, nullptr, "SimulateGameCardDetectionEvent"},
{600, nullptr, "SetCurrentPosixTime"},
{601, nullptr, "QuerySaveDataTotalSize"},
{602, nullptr, "VerifySaveDataFileSystem"},
@@ -717,6 +723,8 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
{1008, nullptr, "OpenRegisteredUpdatePartition"},
{1009, nullptr, "GetAndClearMemoryReportInfo"},
{1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
+ {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
+ {1200, nullptr, "OpenMultiCommitManager"},
};
// clang-format on
RegisterHandlers(functions);
@@ -724,7 +732,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
FSP_SRV::~FSP_SRV() = default;
-void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) {
+void FSP_SRV::SetCurrentProcess(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
@@ -743,7 +751,7 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) {
rb.Push(ResultCode(-1));
}
-void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {
+void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
IFileSystem filesystem(OpenSDMC().Unwrap());
@@ -753,7 +761,7 @@ void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
}
-void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) {
+void FSP_SRV::CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto save_struct = rp.PopRaw<FileSys::SaveDataDescriptor>();
@@ -767,7 +775,7 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
-void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
+void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto space_id = rp.PopRaw<FileSys::SaveDataSpaceId>();
@@ -793,7 +801,7 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
void FSP_SRV::OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
- MountSaveData(ctx);
+ OpenSaveDataFileSystem(ctx);
}
void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx) {
@@ -881,7 +889,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<IStorage>(std::move(storage));
}
-void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
+void FSP_SRV::OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
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:
~FSP_SRV() override;
private:
- void Initialize(Kernel::HLERequestContext& ctx);
+ void SetCurrentProcess(Kernel::HLERequestContext& ctx);
void OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx);
- void MountSdCard(Kernel::HLERequestContext& ctx);
- void CreateSaveData(Kernel::HLERequestContext& ctx);
- void MountSaveData(Kernel::HLERequestContext& ctx);
+ void OpenSdCardFileSystem(Kernel::HLERequestContext& ctx);
+ void CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx);
+ void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx);
void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx);
void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx);
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx);
- void OpenRomStorage(Kernel::HLERequestContext& ctx);
+ void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
FileSys::VirtualFile romfs;
};
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:
{6, nullptr, "CloseContentStorageForcibly"},
{7, nullptr, "CloseContentMetaDatabaseForcibly"},
{8, nullptr, "CleanupContentMetaDatabase"},
- {9, nullptr, "OpenContentStorage2"},
- {10, nullptr, "CloseContentStorage"},
- {11, nullptr, "OpenContentMetaDatabase2"},
- {12, nullptr, "CloseContentMetaDatabase"},
+ {9, nullptr, "ActivateContentStorage"},
+ {10, nullptr, "InactivateContentStorage"},
+ {11, nullptr, "ActivateContentMetaDatabase"},
+ {12, nullptr, "InactivateContentMetaDatabase"},
};
// clang-format on
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:
{11, nullptr, "CalculateApplicationOccupiedSize"},
{16, nullptr, "PushApplicationRecord"},
{17, nullptr, "ListApplicationRecordContentMeta"},
- {19, nullptr, "LaunchApplication"},
+ {19, nullptr, "LaunchApplicationOld"},
{21, nullptr, "GetApplicationContentPath"},
{22, nullptr, "TerminateApplication"},
{23, nullptr, "ResolveApplicationContentPath"},
@@ -96,10 +96,10 @@ public:
{86, nullptr, "EnableApplicationCrashReport"},
{87, nullptr, "IsApplicationCrashReportEnabled"},
{90, nullptr, "BoostSystemMemoryResourceLimit"},
- {91, nullptr, "Unknown1"},
- {92, nullptr, "Unknown2"},
+ {91, nullptr, "DeprecatedLaunchApplication"},
+ {92, nullptr, "GetRunningApplicationProgramId"},
{93, nullptr, "GetMainApplicationProgramIndex"},
- {94, nullptr, "LaunchApplication2"},
+ {94, nullptr, "LaunchApplication"},
{95, nullptr, "GetApplicationLaunchInfo"},
{96, nullptr, "AcquireApplicationLaunchInfo"},
{97, nullptr, "GetMainApplicationProgramIndex2"},
@@ -163,7 +163,7 @@ public:
{907, nullptr, "WithdrawApplicationUpdateRequest"},
{908, nullptr, "ListApplicationRecordInstalledContentMeta"},
{909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
- {910, nullptr, "Unknown3"},
+ {910, nullptr, "HasApplicationRecord"},
{911, nullptr, "SetPreInstalledApplication"},
{912, nullptr, "ClearPreInstalledApplicationFlag"},
{1000, nullptr, "RequestVerifyApplicationDeprecated"},
@@ -219,10 +219,10 @@ public:
{2015, nullptr, "CompareSystemDeliveryInfo"},
{2016, nullptr, "ListNotCommittedContentMeta"},
{2017, nullptr, "CreateDownloadTask"},
- {2018, nullptr, "Unknown4"},
- {2050, nullptr, "Unknown5"},
- {2100, nullptr, "Unknown6"},
- {2101, nullptr, "Unknown7"},
+ {2018, nullptr, "GetApplicationDeliveryInfoHash"},
+ {2050, nullptr, "GetApplicationRightsOnClient"},
+ {2100, nullptr, "GetApplicationTerminateResult"},
+ {2101, nullptr, "GetRawApplicationTerminateResult"},
{2150, nullptr, "CreateRightsEnvironment"},
{2151, nullptr, "DestroyRightsEnvironment"},
{2152, nullptr, "ActivateRightsEnvironment"},
@@ -237,10 +237,10 @@ public:
{2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"},
{2190, nullptr, "GetRightsEnvironmentHandleForApplication"},
{2199, nullptr, "GetRightsEnvironmentCountForDebug"},
- {2200, nullptr, "Unknown8"},
- {2201, nullptr, "Unknown9"},
- {2250, nullptr, "Unknown10"},
- {2300, nullptr, "Unknown11"},
+ {2200, nullptr, "GetGameCardApplicationCopyIdentifier"},
+ {2201, nullptr, "GetInstalledApplicationCopyIdentifier"},
+ {2250, nullptr, "RequestReportActiveELicence"},
+ {2300, nullptr, "ListEventLog"},
};
// clang-format on
@@ -355,6 +355,7 @@ public:
static const FunctionInfo functions[] = {
{21, nullptr, "GetApplicationContentPath"},
{23, nullptr, "ResolveApplicationContentPath"},
+ {93, nullptr, "GetRunningApplicationProgramId"},
};
// clang-format on
@@ -389,6 +390,11 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestLinkDevice"},
+ {1, nullptr, "RequestCleanupAllPreInstalledApplications"},
+ {2, nullptr, "RequestCleanupPreInstalledApplication"},
+ {3, nullptr, "RequestSyncRights"},
+ {4, nullptr, "RequestUnlinkDevice"},
+ {5, nullptr, "RequestRevokeAllELicense"},
};
// clang-format on
@@ -403,7 +409,7 @@ public:
static const FunctionInfo functions[] = {
{100, nullptr, "ResetToFactorySettings"},
{101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
- {102, nullptr, "ResetToFactorySettingsForRefurbishment "},
+ {102, nullptr, "ResetToFactorySettingsForRefurbishment"},
};
// clang-format on
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 6db2cce41..cde06916d 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -46,7 +46,7 @@ void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
nvdrv = std::move(instance);
}
-u64 NVFlinger::OpenDisplay(std::string_view name) {
+std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
LOG_DEBUG(Service, "Opening \"{}\" display", name);
// TODO(Subv): Currently we only support the Default display.
@@ -54,35 +54,51 @@ u64 NVFlinger::OpenDisplay(std::string_view name) {
const auto itr = std::find_if(displays.begin(), displays.end(),
[&](const Display& display) { return display.name == name; });
-
- ASSERT(itr != displays.end());
+ if (itr == displays.end()) {
+ return {};
+ }
return itr->id;
}
-u64 NVFlinger::CreateLayer(u64 display_id) {
- auto& display = GetDisplay(display_id);
+std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
+ auto* const display = FindDisplay(display_id);
- ASSERT_MSG(display.layers.empty(), "Only one layer is supported per display at the moment");
+ if (display == nullptr) {
+ return {};
+ }
+
+ ASSERT_MSG(display->layers.empty(), "Only one layer is supported per display at the moment");
const u64 layer_id = next_layer_id++;
const u32 buffer_queue_id = next_buffer_queue_id++;
auto buffer_queue = std::make_shared<BufferQueue>(buffer_queue_id, layer_id);
- display.layers.emplace_back(layer_id, buffer_queue);
+ display->layers.emplace_back(layer_id, buffer_queue);
buffer_queues.emplace_back(std::move(buffer_queue));
return layer_id;
}
-u32 NVFlinger::GetBufferQueueId(u64 display_id, u64 layer_id) {
- const auto& layer = GetLayer(display_id, layer_id);
- return layer.buffer_queue->GetId();
+std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) const {
+ const auto* const layer = FindLayer(display_id, layer_id);
+
+ if (layer == nullptr) {
+ return {};
+ }
+
+ return layer->buffer_queue->GetId();
}
-Kernel::SharedPtr<Kernel::ReadableEvent> NVFlinger::GetVsyncEvent(u64 display_id) {
- return GetDisplay(display_id).vsync_event.readable;
+Kernel::SharedPtr<Kernel::ReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const {
+ auto* const display = FindDisplay(display_id);
+
+ if (display == nullptr) {
+ return nullptr;
+ }
+
+ return display->vsync_event.readable;
}
-std::shared_ptr<BufferQueue> NVFlinger::GetBufferQueue(u32 id) const {
+std::shared_ptr<BufferQueue> NVFlinger::FindBufferQueue(u32 id) const {
const auto itr = std::find_if(buffer_queues.begin(), buffer_queues.end(),
[&](const auto& queue) { return queue->GetId() == id; });
@@ -90,22 +106,60 @@ std::shared_ptr<BufferQueue> NVFlinger::GetBufferQueue(u32 id) const {
return *itr;
}
-Display& NVFlinger::GetDisplay(u64 display_id) {
+Display* NVFlinger::FindDisplay(u64 display_id) {
const auto itr = std::find_if(displays.begin(), displays.end(),
[&](const Display& display) { return display.id == display_id; });
- ASSERT(itr != displays.end());
- return *itr;
+ if (itr == displays.end()) {
+ return nullptr;
+ }
+
+ return &*itr;
+}
+
+const Display* NVFlinger::FindDisplay(u64 display_id) const {
+ const auto itr = std::find_if(displays.begin(), displays.end(),
+ [&](const Display& display) { return display.id == display_id; });
+
+ if (itr == displays.end()) {
+ return nullptr;
+ }
+
+ return &*itr;
}
-Layer& NVFlinger::GetLayer(u64 display_id, u64 layer_id) {
- auto& display = GetDisplay(display_id);
+Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) {
+ auto* const display = FindDisplay(display_id);
+
+ if (display == nullptr) {
+ return nullptr;
+ }
- const auto itr = std::find_if(display.layers.begin(), display.layers.end(),
+ const auto itr = std::find_if(display->layers.begin(), display->layers.end(),
[&](const Layer& layer) { return layer.id == layer_id; });
- ASSERT(itr != display.layers.end());
- return *itr;
+ if (itr == display->layers.end()) {
+ return nullptr;
+ }
+
+ return &*itr;
+}
+
+const Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) const {
+ const auto* const display = FindDisplay(display_id);
+
+ if (display == nullptr) {
+ return nullptr;
+ }
+
+ const auto itr = std::find_if(display->layers.begin(), display->layers.end(),
+ [&](const Layer& layer) { return layer.id == layer_id; });
+
+ if (itr == display->layers.end()) {
+ return nullptr;
+ }
+
+ return &*itr;
}
void NVFlinger::Compose() {
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 8f9a0a7f8..4c55e99f4 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -6,6 +6,7 @@
#include <array>
#include <memory>
+#include <optional>
#include <string>
#include <string_view>
#include <vector>
@@ -57,31 +58,45 @@ public:
/// Sets the NVDrv module instance to use to send buffers to the GPU.
void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance);
- /// Opens the specified display and returns the id.
- u64 OpenDisplay(std::string_view name);
+ /// Opens the specified display and returns the ID.
+ ///
+ /// If an invalid display name is provided, then an empty optional is returned.
+ std::optional<u64> OpenDisplay(std::string_view name);
- /// Creates a layer on the specified display and returns the layer id.
- u64 CreateLayer(u64 display_id);
+ /// Creates a layer on the specified display and returns the layer ID.
+ ///
+ /// If an invalid display ID is specified, then an empty optional is returned.
+ std::optional<u64> CreateLayer(u64 display_id);
- /// Gets the buffer queue id of the specified layer in the specified display.
- u32 GetBufferQueueId(u64 display_id, u64 layer_id);
+ /// Finds the buffer queue ID of the specified layer in the specified display.
+ ///
+ /// If an invalid display ID or layer ID is provided, then an empty optional is returned.
+ std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id) const;
/// Gets the vsync event for the specified display.
- Kernel::SharedPtr<Kernel::ReadableEvent> GetVsyncEvent(u64 display_id);
+ ///
+ /// If an invalid display ID is provided, then nullptr is returned.
+ Kernel::SharedPtr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const;
- /// Obtains a buffer queue identified by the id.
- std::shared_ptr<BufferQueue> GetBufferQueue(u32 id) const;
+ /// Obtains a buffer queue identified by the ID.
+ std::shared_ptr<BufferQueue> FindBufferQueue(u32 id) const;
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
/// finished.
void Compose();
private:
- /// Returns the display identified by the specified id.
- Display& GetDisplay(u64 display_id);
+ /// Finds the display identified by the specified ID.
+ Display* FindDisplay(u64 display_id);
- /// Returns the layer identified by the specified id in the desired display.
- Layer& GetLayer(u64 display_id, u64 layer_id);
+ /// Finds the display identified by the specified ID.
+ const Display* FindDisplay(u64 display_id) const;
+
+ /// Finds the layer identified by the specified ID in the desired display.
+ Layer* FindLayer(u64 display_id, u64 layer_id);
+
+ /// Finds the layer identified by the specified ID in the desired display.
+ const Layer* FindLayer(u64 display_id, u64 layer_id) const;
std::shared_ptr<Nvidia::Module> nvdrv;
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:
explicit PSC_C() : ServiceFramework{"psc:c"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "Unknown1"},
- {1, nullptr, "Unknown2"},
- {2, nullptr, "Unknown3"},
- {3, nullptr, "Unknown4"},
- {4, nullptr, "Unknown5"},
- {5, nullptr, "Unknown6"},
- {6, nullptr, "Unknown7"},
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "DispatchRequest"},
+ {2, nullptr, "GetResult"},
+ {3, nullptr, "GetState"},
+ {4, nullptr, "Cancel"},
+ {5, nullptr, "PrintModuleInformation"},
+ {6, nullptr, "GetModuleInformation"},
};
// clang-format on
@@ -39,7 +39,8 @@ public:
{0, nullptr, "Initialize"},
{1, nullptr, "GetRequest"},
{2, nullptr, "Acknowledge"},
- {3, nullptr, "Unknown1"},
+ {3, nullptr, "Finalize"},
+ {4, nullptr, "AcknowledgeEx"},
};
// clang-format on
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 0f2c25182..a317a2885 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -34,6 +34,7 @@ namespace Service::VI {
constexpr ResultCode ERR_OPERATION_FAILED{ErrorModule::VI, 1};
constexpr ResultCode ERR_UNSUPPORTED{ErrorModule::VI, 6};
+constexpr ResultCode ERR_NOT_FOUND{ErrorModule::VI, 7};
struct DisplayInfo {
/// The name of this particular display.
@@ -524,7 +525,7 @@ private:
LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id,
static_cast<u32>(transaction), flags);
- auto buffer_queue = nv_flinger->GetBufferQueue(id);
+ auto buffer_queue = nv_flinger->FindBufferQueue(id);
if (transaction == TransactionId::Connect) {
IGBPConnectRequestParcel request{ctx.ReadBuffer()};
@@ -558,7 +559,7 @@ private:
[=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
Kernel::ThreadWakeupReason reason) {
// Repeat TransactParcel DequeueBuffer when a buffer is available
- auto buffer_queue = nv_flinger->GetBufferQueue(id);
+ auto buffer_queue = nv_flinger->FindBufferQueue(id);
std::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
ASSERT_MSG(slot != std::nullopt, "Could not dequeue buffer.");
@@ -628,7 +629,7 @@ private:
LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown);
- const auto buffer_queue = nv_flinger->GetBufferQueue(id);
+ const auto buffer_queue = nv_flinger->FindBufferQueue(id);
// TODO(Subv): Find out what this actually is.
IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -838,11 +839,16 @@ private:
"(STUBBED) called. unknown=0x{:08X}, display=0x{:016X}, aruid=0x{:016X}",
unknown, display, aruid);
- const u64 layer_id = nv_flinger->CreateLayer(display);
+ const auto layer_id = nv_flinger->CreateLayer(display);
+ if (!layer_id) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ERR_NOT_FOUND);
+ return;
+ }
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.Push(layer_id);
+ rb.Push(*layer_id);
}
void AddToLayerStack(Kernel::HLERequestContext& ctx) {
@@ -950,9 +956,16 @@ private:
ASSERT_MSG(name == "Default", "Non-default displays aren't supported yet");
+ const auto display_id = nv_flinger->OpenDisplay(name);
+ if (!display_id) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ERR_NOT_FOUND);
+ return;
+ }
+
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.Push<u64>(nv_flinger->OpenDisplay(name));
+ rb.Push<u64>(*display_id);
}
void CloseDisplay(Kernel::HLERequestContext& ctx) {
@@ -1043,10 +1056,21 @@ private:
LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}, aruid=0x{:016X}", layer_id, aruid);
- const u64 display_id = nv_flinger->OpenDisplay(display_name);
- const u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id);
+ const auto display_id = nv_flinger->OpenDisplay(display_name);
+ if (!display_id) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ERR_NOT_FOUND);
+ return;
+ }
+
+ const auto buffer_queue_id = nv_flinger->FindBufferQueueId(*display_id, layer_id);
+ if (!buffer_queue_id) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ERR_NOT_FOUND);
+ return;
+ }
- NativeWindow native_window{buffer_queue_id};
+ NativeWindow native_window{*buffer_queue_id};
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize()));
@@ -1062,13 +1086,24 @@ private:
// TODO(Subv): What's the difference between a Stray and a Managed layer?
- const u64 layer_id = nv_flinger->CreateLayer(display_id);
- const u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id);
+ const auto layer_id = nv_flinger->CreateLayer(display_id);
+ if (!layer_id) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ERR_NOT_FOUND);
+ return;
+ }
+
+ const auto buffer_queue_id = nv_flinger->FindBufferQueueId(display_id, *layer_id);
+ if (!buffer_queue_id) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ERR_NOT_FOUND);
+ return;
+ }
- NativeWindow native_window{buffer_queue_id};
+ NativeWindow native_window{*buffer_queue_id};
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS);
- rb.Push(layer_id);
+ rb.Push(*layer_id);
rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize()));
}
@@ -1088,7 +1123,12 @@ private:
LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id);
- const auto vsync_event = nv_flinger->GetVsyncEvent(display_id);
+ const auto vsync_event = nv_flinger->FindVsyncEvent(display_id);
+ if (!vsync_event) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ERR_NOT_FOUND);
+ return;
+ }
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
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:
u32 subchannel; ///< Current subchannel
u32 method_count; ///< Current method count
u32 length_pending; ///< Large NI command length pending
- bool non_incrementing; ///< Current command’s NI flag
+ bool non_incrementing; ///< Current command's NI flag
};
DmaState dma_state{};
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 9989825f8..269df9437 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -217,9 +217,9 @@ enum class StoreType : u64 {
Signed8 = 1,
Unsigned16 = 2,
Signed16 = 3,
- Bytes32 = 4,
- Bytes64 = 5,
- Bytes128 = 6,
+ Bits32 = 4,
+ Bits64 = 5,
+ Bits128 = 6,
};
enum class IMinMaxExchange : u64 {
@@ -981,6 +981,10 @@ union Instruction {
}
return false;
}
+
+ bool IsComponentEnabled(std::size_t component) const {
+ return ((1ULL << component) & component_mask) != 0;
+ }
} txq;
union {
@@ -1248,11 +1252,19 @@ union Instruction {
union {
BitField<20, 14, u64> offset;
BitField<34, 5, u64> index;
+
+ u64 GetOffset() const {
+ return offset * 4;
+ }
} cbuf34;
union {
BitField<20, 16, s64> offset;
BitField<36, 5, u64> index;
+
+ s64 GetOffset() const {
+ return offset;
+ }
} cbuf36;
// Unsure about the size of this one.
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:
return false;
}
- /// Attempt to use a faster method to fill a region
- virtual bool AccelerateFill(const void* config) {
- return false;
- }
-
/// Attempt to use a faster method to display the framebuffer to screen
virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
u32 pixel_stride) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 7831bc8cc..53b52753c 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) {
cached_pages.add({pages_interval, delta});
}
-void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool using_color_fb,
- bool using_depth_fb, bool preserve_contents,
- std::optional<std::size_t> single_color_target) {
+std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
+ OpenGLState& current_state, bool using_color_fb, bool using_depth_fb, bool preserve_contents,
+ std::optional<std::size_t> single_color_target) {
MICROPROFILE_SCOPE(OpenGL_Framebuffer);
const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
const auto& regs = gpu.regs;
@@ -491,7 +491,7 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
// Only skip if the previous ConfigureFramebuffers call was from the same kind (multiple or
// single color targets). This is done because the guest registers may not change but the
// host framebuffer may contain different attachments
- return;
+ return current_depth_stencil_usage;
}
current_framebuffer_config_state = fb_config_state;
@@ -561,12 +561,14 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
depth_surface->MarkAsModified(true, res_cache);
fbkey.zeta = depth_surface->Texture().handle;
- fbkey.stencil_enable = regs.stencil_enable;
+ fbkey.stencil_enable = regs.stencil_enable &&
+ depth_surface->GetSurfaceParams().type == SurfaceType::DepthStencil;
}
SetupCachedFramebuffer(fbkey, current_state);
-
SyncViewport(current_state);
+
+ return current_depth_stencil_usage = {static_cast<bool>(depth_surface), fbkey.stencil_enable};
}
void RasterizerOpenGL::Clear() {
@@ -634,8 +636,8 @@ void RasterizerOpenGL::Clear() {
return;
}
- ConfigureFramebuffers(clear_state, use_color, use_depth || use_stencil, false,
- regs.clear_buffers.RT.Value());
+ const auto [clear_depth, clear_stencil] = ConfigureFramebuffers(
+ clear_state, use_color, use_depth || use_stencil, false, regs.clear_buffers.RT.Value());
if (regs.clear_flags.scissor) {
SyncScissorTest(clear_state);
}
@@ -650,11 +652,11 @@ void RasterizerOpenGL::Clear() {
glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color);
}
- if (use_depth && use_stencil) {
+ if (clear_depth && clear_stencil) {
glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil);
- } else if (use_depth) {
+ } else if (clear_depth) {
glClearBufferfv(GL_DEPTH, 0, &regs.clear_depth);
- } else if (use_stencil) {
+ } else if (clear_stencil) {
glClearBufferiv(GL_STENCIL, 0, &regs.clear_stencil);
}
}
@@ -781,11 +783,6 @@ bool RasterizerOpenGL::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs
return true;
}
-bool RasterizerOpenGL::AccelerateFill(const void* config) {
- UNREACHABLE();
- return true;
-}
-
bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
VAddr framebuffer_addr, u32 pixel_stride) {
if (!framebuffer_addr) {
@@ -957,7 +954,7 @@ void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::Shader
}
} else {
// Buffer is accessed directly, upload just what we use
- size = used_buffer.GetSize() * sizeof(float);
+ size = used_buffer.GetSize();
}
// Align the actual size so it ends up being a multiple of vec4 to meet the OpenGL std140
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:
void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src,
const Tegra::Engines::Fermi2D::Regs::Surface& dst) override;
- bool AccelerateFill(const void* config) override;
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
u32 pixel_stride) override;
bool AccelerateDrawBatch(bool is_indexed) override;
@@ -122,10 +121,12 @@ private:
* @param using_depth_fb If true, configure the depth/stencil framebuffer.
* @param preserve_contents If true, tries to preserve data from a previously used framebuffer.
* @param single_color_target Specifies if a single color buffer target should be used.
+ * @returns If depth (first) or stencil (second) are being stored in the bound zeta texture
+ * (requires using_depth_fb to be true)
*/
- void ConfigureFramebuffers(OpenGLState& current_state, bool use_color_fb = true,
- bool using_depth_fb = true, bool preserve_contents = true,
- std::optional<std::size_t> single_color_target = {});
+ std::pair<bool, bool> ConfigureFramebuffers(
+ OpenGLState& current_state, bool use_color_fb = true, bool using_depth_fb = true,
+ bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
/// Configures the current constbuffers to use for the draw command.
void SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, const Shader& shader,
@@ -214,6 +215,7 @@ private:
std::map<FramebufferCacheKey, OGLFramebuffer> framebuffer_cache;
FramebufferConfigState current_framebuffer_config_state;
+ std::pair<bool, bool> current_depth_stencil_usage{};
std::array<SamplerInfo, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_samplers;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 42e4e7aa1..a79eee03e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -719,7 +719,6 @@ void CachedSurface::FlushGLBuffer() {
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer[0], params.pixel_format, params.width,
params.height);
- ASSERT(params.type != SurfaceType::Fill);
const u8* const texture_src_data = Memory::GetPointer(params.addr);
ASSERT(texture_src_data);
if (params.is_tiled) {
@@ -863,9 +862,6 @@ void CachedSurface::EnsureTextureView() {
MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64));
void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) {
- if (params.type == SurfaceType::Fill)
- return;
-
MICROPROFILE_SCOPE(OpenGL_TextureUL);
for (u32 i = 0; i < params.max_mip_level; i++)
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 004245431..36035d0d2 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -543,8 +543,9 @@ private:
if (const auto immediate = std::get_if<ImmediateNode>(offset)) {
// Direct access
const u32 offset_imm = immediate->GetValue();
- return fmt::format("{}[{}][{}]", GetConstBuffer(cbuf->GetIndex()), offset_imm / 4,
- offset_imm % 4);
+ ASSERT_MSG(offset_imm % 4 == 0, "Unaligned cbuf direct access");
+ return fmt::format("{}[{}][{}]", GetConstBuffer(cbuf->GetIndex()),
+ offset_imm / (4 * 4), (offset_imm / 4) % 4);
} else if (std::holds_alternative<OperationNode>(*offset)) {
// Indirect access
diff --git a/src/video_core/shader/decode/arithmetic.cpp b/src/video_core/shader/decode/arithmetic.cpp
index e7847f614..51b8d55d4 100644
--- a/src/video_core/shader/decode/arithmetic.cpp
+++ b/src/video_core/shader/decode/arithmetic.cpp
@@ -25,7 +25,7 @@ u32 ShaderIR::DecodeArithmetic(BasicBlock& bb, const BasicBlock& code, u32 pc) {
} else if (instr.is_b_gpr) {
return GetRegister(instr.gpr20);
} else {
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
}
}();
diff --git a/src/video_core/shader/decode/arithmetic_half.cpp b/src/video_core/shader/decode/arithmetic_half.cpp
index a237dcb92..37eef2bf2 100644
--- a/src/video_core/shader/decode/arithmetic_half.cpp
+++ b/src/video_core/shader/decode/arithmetic_half.cpp
@@ -35,7 +35,7 @@ u32 ShaderIR::DecodeArithmeticHalf(BasicBlock& bb, const BasicBlock& code, u32 p
switch (opcode->get().GetId()) {
case OpCode::Id::HADD2_C:
case OpCode::Id::HMUL2_C:
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
case OpCode::Id::HADD2_R:
case OpCode::Id::HMUL2_R:
return GetRegister(instr.gpr20);
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index 4a8cc1a1c..cc9a76a19 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -26,7 +26,7 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, const BasicBlock& code, u3
} else if (instr.is_b_gpr) {
return GetRegister(instr.gpr20);
} else {
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
}
}();
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp
index ee18d3a99..728a393a1 100644
--- a/src/video_core/shader/decode/conversion.cpp
+++ b/src/video_core/shader/decode/conversion.cpp
@@ -48,7 +48,7 @@ u32 ShaderIR::DecodeConversion(BasicBlock& bb, const BasicBlock& code, u32 pc) {
if (instr.is_b_gpr) {
return GetRegister(instr.gpr20);
} else {
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
}
}();
const bool input_signed = instr.conversion.is_input_signed;
@@ -72,7 +72,7 @@ u32 ShaderIR::DecodeConversion(BasicBlock& bb, const BasicBlock& code, u32 pc) {
if (instr.is_b_gpr) {
return GetRegister(instr.gpr20);
} else {
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
}
}();
@@ -110,7 +110,7 @@ u32 ShaderIR::DecodeConversion(BasicBlock& bb, const BasicBlock& code, u32 pc) {
if (instr.is_b_gpr) {
return GetRegister(instr.gpr20);
} else {
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
}
}();
diff --git a/src/video_core/shader/decode/ffma.cpp b/src/video_core/shader/decode/ffma.cpp
index be8dc2230..52f39d3ff 100644
--- a/src/video_core/shader/decode/ffma.cpp
+++ b/src/video_core/shader/decode/ffma.cpp
@@ -27,14 +27,14 @@ u32 ShaderIR::DecodeFfma(BasicBlock& bb, const BasicBlock& code, u32 pc) {
auto [op_b, op_c] = [&]() -> std::tuple<Node, Node> {
switch (opcode->get().GetId()) {
case OpCode::Id::FFMA_CR: {
- return {GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset),
+ return {GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()),
GetRegister(instr.gpr39)};
}
case OpCode::Id::FFMA_RR:
return {GetRegister(instr.gpr20), GetRegister(instr.gpr39)};
case OpCode::Id::FFMA_RC: {
return {GetRegister(instr.gpr39),
- GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset)};
+ GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset())};
}
case OpCode::Id::FFMA_IMM:
return {GetImmediate19(instr), GetRegister(instr.gpr39)};
diff --git a/src/video_core/shader/decode/float_set.cpp b/src/video_core/shader/decode/float_set.cpp
index ba846f1bd..9f9da2278 100644
--- a/src/video_core/shader/decode/float_set.cpp
+++ b/src/video_core/shader/decode/float_set.cpp
@@ -25,7 +25,7 @@ u32 ShaderIR::DecodeFloatSet(BasicBlock& bb, const BasicBlock& code, u32 pc) {
} else if (instr.is_b_gpr) {
return GetRegister(instr.gpr20);
} else {
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
}
}();
diff --git a/src/video_core/shader/decode/float_set_predicate.cpp b/src/video_core/shader/decode/float_set_predicate.cpp
index e88b04d18..dd3aef6f2 100644
--- a/src/video_core/shader/decode/float_set_predicate.cpp
+++ b/src/video_core/shader/decode/float_set_predicate.cpp
@@ -25,7 +25,7 @@ u32 ShaderIR::DecodeFloatSetPredicate(BasicBlock& bb, const BasicBlock& code, u3
} else if (instr.is_b_gpr) {
return GetRegister(instr.gpr20);
} else {
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
}
}();
op_b = GetOperandAbsNegFloat(op_b, instr.fsetp.abs_b, false);
diff --git a/src/video_core/shader/decode/hfma2.cpp b/src/video_core/shader/decode/hfma2.cpp
index 4a6b945f9..43a0a9e10 100644
--- a/src/video_core/shader/decode/hfma2.cpp
+++ b/src/video_core/shader/decode/hfma2.cpp
@@ -39,13 +39,14 @@ u32 ShaderIR::DecodeHfma2(BasicBlock& bb, const BasicBlock& code, u32 pc) {
neg_b = instr.hfma2.negate_b;
neg_c = instr.hfma2.negate_c;
return {instr.hfma2.saturate, instr.hfma2.type_b,
- GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset), instr.hfma2.type_reg39,
- GetRegister(instr.gpr39)};
+ GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()),
+ instr.hfma2.type_reg39, GetRegister(instr.gpr39)};
case OpCode::Id::HFMA2_RC:
neg_b = instr.hfma2.negate_b;
neg_c = instr.hfma2.negate_c;
return {instr.hfma2.saturate, instr.hfma2.type_reg39, GetRegister(instr.gpr39),
- instr.hfma2.type_b, GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset)};
+ instr.hfma2.type_b,
+ GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset())};
case OpCode::Id::HFMA2_RR:
neg_b = instr.hfma2.rr.negate_b;
neg_c = instr.hfma2.rr.negate_c;
diff --git a/src/video_core/shader/decode/integer_set.cpp b/src/video_core/shader/decode/integer_set.cpp
index 85e67b03b..16eb3985f 100644
--- a/src/video_core/shader/decode/integer_set.cpp
+++ b/src/video_core/shader/decode/integer_set.cpp
@@ -23,7 +23,7 @@ u32 ShaderIR::DecodeIntegerSet(BasicBlock& bb, const BasicBlock& code, u32 pc) {
} else if (instr.is_b_gpr) {
return GetRegister(instr.gpr20);
} else {
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
}
}();
diff --git a/src/video_core/shader/decode/integer_set_predicate.cpp b/src/video_core/shader/decode/integer_set_predicate.cpp
index c8b105a08..daf97174b 100644
--- a/src/video_core/shader/decode/integer_set_predicate.cpp
+++ b/src/video_core/shader/decode/integer_set_predicate.cpp
@@ -25,7 +25,7 @@ u32 ShaderIR::DecodeIntegerSetPredicate(BasicBlock& bb, const BasicBlock& code,
} else if (instr.is_b_gpr) {
return GetRegister(instr.gpr20);
} else {
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
}
}();
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 04cb386b7..3dd26da20 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -80,7 +80,7 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) {
Node index = GetRegister(instr.gpr8);
const Node op_a =
- GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, index);
+ GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 0, index);
switch (instr.ld_c.type.Value()) {
case Tegra::Shader::UniformType::Single:
@@ -89,7 +89,7 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) {
case Tegra::Shader::UniformType::Double: {
const Node op_b =
- GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, index);
+ GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 4, index);
SetTemporal(bb, 0, op_a);
SetTemporal(bb, 1, op_b);
@@ -104,19 +104,42 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) {
}
case OpCode::Id::LD_L: {
UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}",
- static_cast<unsigned>(instr.ld_l.unknown.Value()));
-
- const Node index = Operation(OperationCode::IAdd, GetRegister(instr.gpr8),
- Immediate(static_cast<s32>(instr.smem_imm)));
- const Node lmem = GetLocalMemory(index);
+ static_cast<u32>(instr.ld_l.unknown.Value()));
+
+ const auto GetLmem = [&](s32 offset) {
+ ASSERT(offset % 4 == 0);
+ const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset);
+ const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8),
+ immediate_offset);
+ return GetLocalMemory(address);
+ };
switch (instr.ldst_sl.type.Value()) {
- case Tegra::Shader::StoreType::Bytes32:
- SetRegister(bb, instr.gpr0, lmem);
+ case Tegra::Shader::StoreType::Bits32:
+ case Tegra::Shader::StoreType::Bits64:
+ case Tegra::Shader::StoreType::Bits128: {
+ const u32 count = [&]() {
+ switch (instr.ldst_sl.type.Value()) {
+ case Tegra::Shader::StoreType::Bits32:
+ return 1;
+ case Tegra::Shader::StoreType::Bits64:
+ return 2;
+ case Tegra::Shader::StoreType::Bits128:
+ return 4;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+ }();
+ for (u32 i = 0; i < count; ++i)
+ SetTemporal(bb, i, GetLmem(i * 4));
+ for (u32 i = 0; i < count; ++i)
+ SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i));
break;
+ }
default:
UNIMPLEMENTED_MSG("LD_L Unhandled type: {}",
- static_cast<unsigned>(instr.ldst_sl.type.Value()));
+ static_cast<u32>(instr.ldst_sl.type.Value()));
}
break;
}
@@ -142,7 +165,7 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) {
ASSERT(cbuf != nullptr);
const auto cbuf_offset_imm = std::get_if<ImmediateNode>(cbuf->GetOffset());
ASSERT(cbuf_offset_imm != nullptr);
- const auto cbuf_offset = cbuf_offset_imm->GetValue() * 4;
+ const auto cbuf_offset = cbuf_offset_imm->GetValue();
bb.push_back(Comment(
fmt::format("Base address is c[0x{:x}][0x{:x}]", cbuf->GetIndex(), cbuf_offset)));
@@ -202,12 +225,20 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) {
UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}",
static_cast<u32>(instr.st_l.unknown.Value()));
- const Node index = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8),
- Immediate(static_cast<s32>(instr.smem_imm)));
+ const auto GetLmemAddr = [&](s32 offset) {
+ ASSERT(offset % 4 == 0);
+ const Node immediate = Immediate(static_cast<s32>(instr.smem_imm) + offset);
+ return Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), immediate);
+ };
switch (instr.ldst_sl.type.Value()) {
- case Tegra::Shader::StoreType::Bytes32:
- SetLocalMemory(bb, index, GetRegister(instr.gpr0));
+ case Tegra::Shader::StoreType::Bits128:
+ SetLocalMemory(bb, GetLmemAddr(12), GetRegister(instr.gpr0.Value() + 3));
+ SetLocalMemory(bb, GetLmemAddr(8), GetRegister(instr.gpr0.Value() + 2));
+ case Tegra::Shader::StoreType::Bits64:
+ SetLocalMemory(bb, GetLmemAddr(4), GetRegister(instr.gpr0.Value() + 1));
+ case Tegra::Shader::StoreType::Bits32:
+ SetLocalMemory(bb, GetLmemAddr(0), GetRegister(instr.gpr0));
break;
default:
UNIMPLEMENTED_MSG("ST_L Unhandled type: {}",
@@ -324,15 +355,18 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) {
const auto& sampler =
GetSampler(instr.sampler, Tegra::Shader::TextureType::Texture2D, false, false);
+ u32 indexer = 0;
switch (instr.txq.query_type) {
case Tegra::Shader::TextureQueryType::Dimension: {
for (u32 element = 0; element < 4; ++element) {
- MetaTexture meta{sampler, element};
- const Node value = Operation(OperationCode::F4TextureQueryDimensions,
- std::move(meta), GetRegister(instr.gpr8));
- SetTemporal(bb, element, value);
+ if (instr.txq.IsComponentEnabled(element)) {
+ MetaTexture meta{sampler, element};
+ const Node value = Operation(OperationCode::F4TextureQueryDimensions,
+ std::move(meta), GetRegister(instr.gpr8));
+ SetTemporal(bb, indexer++, value);
+ }
}
- for (u32 i = 0; i < 4; ++i) {
+ for (u32 i = 0; i < indexer; ++i) {
SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i));
}
break;
@@ -734,4 +768,4 @@ std::tuple<std::size_t, std::size_t> ShaderIR::ValidateAndGetCoordinateElement(
return {coord_count, total_coord_count};
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/shift.cpp b/src/video_core/shader/decode/shift.cpp
index 85026bb37..6623f8ff9 100644
--- a/src/video_core/shader/decode/shift.cpp
+++ b/src/video_core/shader/decode/shift.cpp
@@ -23,7 +23,7 @@ u32 ShaderIR::DecodeShift(BasicBlock& bb, const BasicBlock& code, u32 pc) {
} else if (instr.is_b_gpr) {
return GetRegister(instr.gpr20);
} else {
- return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset);
+ return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset());
}
}();
diff --git a/src/video_core/shader/decode/xmad.cpp b/src/video_core/shader/decode/xmad.cpp
index 0cd9cd1cc..9cb864500 100644
--- a/src/video_core/shader/decode/xmad.cpp
+++ b/src/video_core/shader/decode/xmad.cpp
@@ -32,13 +32,14 @@ u32 ShaderIR::DecodeXmad(BasicBlock& bb, const BasicBlock& code, u32 pc) {
auto [is_merge, op_b, op_c] = [&]() -> std::tuple<bool, Node, Node> {
switch (opcode->get().GetId()) {
case OpCode::Id::XMAD_CR:
- return {instr.xmad.merge_56, GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset),
+ return {instr.xmad.merge_56,
+ GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()),
GetRegister(instr.gpr39)};
case OpCode::Id::XMAD_RR:
return {instr.xmad.merge_37, GetRegister(instr.gpr20), GetRegister(instr.gpr39)};
case OpCode::Id::XMAD_RC:
return {false, GetRegister(instr.gpr39),
- GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset)};
+ GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset())};
case OpCode::Id::XMAD_IMM:
return {instr.xmad.merge_37, Immediate(static_cast<u32>(instr.xmad.imm20_16)),
GetRegister(instr.gpr39)};
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index c4ecb2e3c..6e42e3dfb 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -249,7 +249,7 @@ public:
}
u32 GetSize() const {
- return max_offset + 1;
+ return max_offset + sizeof(float);
}
private:
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 {
ColorTexture = 0,
Depth = 1,
DepthStencil = 2,
- Fill = 3,
- Invalid = 4,
+ Invalid = 3,
};
enum class SurfaceTarget {
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index e7c78bee2..bdb40dacf 100644
--- a/src/video_core/textures/texture.h
+++ b/src/video_core/textures/texture.h
@@ -182,7 +182,7 @@ struct TICEntry {
};
union {
BitField<0, 16, u32> height_minus_1;
- BitField<16, 15, u32> depth_minus_1;
+ BitField<16, 14, u32> depth_minus_1;
};
union {
BitField<6, 13, u32> mip_lod_bias;
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 8290b4384..d21f95469 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -62,9 +62,7 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
const QColor new_bg_color = QColorDialog::getColor(bg_color);
if (!new_bg_color.isValid())
return;
- bg_color = new_bg_color;
- ui->bg_button->setStyleSheet(
- QString("QPushButton { background-color: %1 }").arg(bg_color.name()));
+ UpdateBackgroundColorButton(new_bg_color);
});
}
@@ -76,10 +74,8 @@ void ConfigureGraphics::setConfiguration() {
ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit);
ui->frame_limit->setValue(Settings::values.frame_limit);
ui->use_accurate_gpu_emulation->setChecked(Settings::values.use_accurate_gpu_emulation);
- bg_color = QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green,
- Settings::values.bg_blue);
- ui->bg_button->setStyleSheet(
- QString("QPushButton { background-color: %1 }").arg(bg_color.name()));
+ UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green,
+ Settings::values.bg_blue));
}
void ConfigureGraphics::applyConfiguration() {
@@ -92,3 +88,13 @@ void ConfigureGraphics::applyConfiguration() {
Settings::values.bg_green = static_cast<float>(bg_color.greenF());
Settings::values.bg_blue = static_cast<float>(bg_color.blueF());
}
+
+void ConfigureGraphics::UpdateBackgroundColorButton(QColor color) {
+ bg_color = color;
+
+ QPixmap pixmap(ui->bg_button->size());
+ pixmap.fill(bg_color);
+
+ const QIcon color_icon(pixmap);
+ ui->bg_button->setIcon(color_icon);
+}
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h
index d6ffc6fde..f2799822d 100644
--- a/src/yuzu/configuration/configure_graphics.h
+++ b/src/yuzu/configuration/configure_graphics.h
@@ -23,6 +23,8 @@ public:
private:
void setConfiguration();
+ void UpdateBackgroundColorButton(QColor color);
+
std::unique_ptr<Ui::ConfigureGraphics> ui;
QColor bg_color;
};
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 @@
#include "core/hle/kernel/readable_event.h"
#include "core/hle/kernel/scheduler.h"
#include "core/hle/kernel/thread.h"
-#include "core/hle/kernel/timer.h"
#include "core/hle/kernel/wait_object.h"
#include "core/memory.h"
@@ -155,8 +154,6 @@ std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitO
switch (object.GetHandleType()) {
case Kernel::HandleType::ReadableEvent:
return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object));
- case Kernel::HandleType::Timer:
- return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object));
case Kernel::HandleType::Thread:
return std::make_unique<WaitTreeThread>(static_cast<const Kernel::Thread&>(object));
default:
@@ -348,23 +345,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const {
return list;
}
-WaitTreeTimer::WaitTreeTimer(const Kernel::Timer& object) : WaitTreeWaitObject(object) {}
-WaitTreeTimer::~WaitTreeTimer() = default;
-
-std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeTimer::GetChildren() const {
- std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren());
-
- const auto& timer = static_cast<const Kernel::Timer&>(object);
-
- list.push_back(std::make_unique<WaitTreeText>(
- tr("reset type = %1").arg(GetResetTypeQString(timer.GetResetType()))));
- list.push_back(
- std::make_unique<WaitTreeText>(tr("initial delay = %1").arg(timer.GetInitialDelay())));
- list.push_back(
- std::make_unique<WaitTreeText>(tr("interval delay = %1").arg(timer.GetIntervalDelay())));
- return list;
-}
-
WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list)
: thread_list(list) {}
WaitTreeThreadList::~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 {
class ReadableEvent;
class WaitObject;
class Thread;
-class Timer;
} // namespace Kernel
class WaitTreeThread;
@@ -150,15 +149,6 @@ public:
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
};
-class WaitTreeTimer : public WaitTreeWaitObject {
- Q_OBJECT
-public:
- explicit WaitTreeTimer(const Kernel::Timer& object);
- ~WaitTreeTimer() override;
-
- std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
-};
-
class WaitTreeThreadList : public WaitTreeExpandableItem {
Q_OBJECT
public:
diff --git a/src/yuzu/loading_screen.ui b/src/yuzu/loading_screen.ui
index a67d273fd..820b47536 100644
--- a/src/yuzu/loading_screen.ui
+++ b/src/yuzu/loading_screen.ui
@@ -132,7 +132,7 @@ border-radius: 15px;
font: 75 15pt &quot;Arial&quot;;</string>
</property>
<property name="text">
- <string>Stage 1 of 2. Estimate Time 5m 4s</string>
+ <string>Estimated Time 5m 4s</string>
</property>
</widget>
</item>
@@ -146,6 +146,9 @@ font: 75 15pt &quot;Arial&quot;;</string>
<property name="text">
<string/>
</property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
<property name="margin">
<number>30</number>
</property>
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index ab403b3ac..485e29de2 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1682,12 +1682,16 @@ void GMainWindow::OnToggleFilterBar() {
void GMainWindow::OnCaptureScreenshot() {
OnPauseGame();
- const QString path =
- QFileDialog::getSaveFileName(this, tr("Capture Screenshot"),
- UISettings::values.screenshot_path, tr("PNG Image (*.png)"));
- if (!path.isEmpty()) {
- UISettings::values.screenshot_path = QFileInfo(path).path();
- render_window->CaptureScreenshot(UISettings::values.screenshot_resolution_factor, path);
+ QFileDialog png_dialog(this, tr("Capture Screenshot"), UISettings::values.screenshot_path,
+ tr("PNG Image (*.png)"));
+ png_dialog.setAcceptMode(QFileDialog::AcceptSave);
+ png_dialog.setDefaultSuffix("png");
+ if (png_dialog.exec()) {
+ const QString path = png_dialog.selectedFiles().first();
+ if (!path.isEmpty()) {
+ UISettings::values.screenshot_path = QFileInfo(path).path();
+ render_window->CaptureScreenshot(UISettings::values.screenshot_resolution_factor, path);
+ }
}
OnStartGame();
}