From e81a2080ebf9712231dd29c081141780ffd46cfb Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 20 Apr 2018 12:01:14 -0500 Subject: [PATCH 01/74] Kernel: Corrected the implementation of svcArbitrateLock and svcArbitrateUnlock. Switch mutexes are no longer kernel objects, they are managed in userland and only use the kernel to handle the contention case. Mutex addresses store a special flag value (0x40000000) to notify the guest code that there are still some threads waiting for the mutex to be released. This flag is updated when a thread calls ArbitrateUnlock. TODO: * Fix svcWaitProcessWideKey * Fix svcSignalProcessWideKey * Remove the Mutex class. --- src/core/hle/kernel/errors.h | 1 + src/core/hle/kernel/mutex.cpp | 94 ++++++++++++++++++++++++++++++++++ src/core/hle/kernel/mutex.h | 12 +++++ src/core/hle/kernel/svc.cpp | 22 +------- src/core/hle/kernel/thread.cpp | 13 ++++- src/core/hle/kernel/thread.h | 6 ++- 6 files changed, 126 insertions(+), 22 deletions(-) diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h index 29d8dfdaab..5be20c8781 100644 --- a/src/core/hle/kernel/errors.h +++ b/src/core/hle/kernel/errors.h @@ -20,6 +20,7 @@ enum { MaxConnectionsReached = 52, // Confirmed Switch OS error codes + MisalignedAddress = 102, InvalidHandle = 114, Timeout = 117, SynchronizationCanceled = 118, diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 0b9dc700c3..50a9a0805f 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -7,6 +7,7 @@ #include #include "common/assert.h" #include "core/core.h" +#include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/mutex.h" @@ -15,6 +16,30 @@ namespace Kernel { +/// Returns the number of threads that are waiting for a mutex, and the highest priority one among +/// those. +static std::pair, u32> GetHighestPriorityMutexWaitingThread(VAddr mutex_addr) { + auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList(); + + SharedPtr highest_priority_thread; + u32 num_waiters = 0; + + for (auto& thread : thread_list) { + if (thread->mutex_wait_address != mutex_addr) + continue; + + ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); + + ++num_waiters; + if (highest_priority_thread == nullptr || + thread->GetPriority() < highest_priority_thread->GetPriority()) { + highest_priority_thread = thread; + } + } + + return {highest_priority_thread, num_waiters}; +} + void ReleaseThreadMutexes(Thread* thread) { for (auto& mtx : thread->held_mutexes) { mtx->SetHasWaiters(false); @@ -135,4 +160,73 @@ void Mutex::SetHasWaiters(bool has_waiters) { Memory::Write32(guest_addr, guest_state.raw); } +ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, + Handle requesting_thread_handle) { + // The mutex address must be 4-byte aligned + if ((address % sizeof(u32)) != 0) { + return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress); + } + + SharedPtr holding_thread = g_handle_table.Get(holding_thread_handle); + SharedPtr requesting_thread = g_handle_table.Get(requesting_thread_handle); + + // TODO(Subv): It is currently unknown if it is possible to lock a mutex in behalf of another + // thread. + ASSERT(requesting_thread == GetCurrentThread()); + + u32 addr_value = Memory::Read32(address); + + // If the mutex isn't being held, just return success. + if (addr_value != (holding_thread_handle | Mutex::MutexHasWaitersFlag)) { + return RESULT_SUCCESS; + } + + if (holding_thread == nullptr) + return ERR_INVALID_HANDLE; + + // Wait until the mutex is released + requesting_thread->mutex_wait_address = address; + requesting_thread->wait_handle = requesting_thread_handle; + + requesting_thread->status = THREADSTATUS_WAIT_MUTEX; + requesting_thread->wakeup_callback = nullptr; + + Core::System::GetInstance().PrepareReschedule(); + + return RESULT_SUCCESS; +} + +ResultCode Mutex::Release(VAddr address) { + // The mutex address must be 4-byte aligned + if ((address % sizeof(u32)) != 0) { + return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress); + } + + auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(address); + + // There are no more threads waiting for the mutex, release it completely. + if (thread == nullptr) { + Memory::Write32(address, 0); + return RESULT_SUCCESS; + } + + u32 mutex_value = thread->wait_handle; + + if (num_waiters >= 2) { + // Notify the guest that there are still some threads waiting for the mutex + mutex_value |= Mutex::MutexHasWaitersFlag; + } + + // Grant the mutex to the next waiting thread and resume it. + Memory::Write32(address, mutex_value); + + ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); + thread->ResumeFromWait(); + + thread->condvar_wait_address = 0; + thread->mutex_wait_address = 0; + thread->wait_handle = 0; + + return RESULT_SUCCESS; +} } // namespace Kernel diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 38db210053..3109230874 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -77,6 +77,18 @@ public: /// Sets the has_waiters bit in the guest state. void SetHasWaiters(bool has_waiters); + /// Flag that indicates that a mutex still has threads waiting for it. + static constexpr u32 MutexHasWaitersFlag = 0x40000000; + /// Mask of the bits in a mutex address value that contain the mutex owner. + static constexpr u32 MutexOwnerMask = 0xBFFFFFFF; + + /// Attempts to acquire a mutex at the specified address. + static ResultCode TryAcquire(VAddr address, Handle holding_thread_handle, + Handle requesting_thread_handle); + + /// Releases the mutex at the specified address. + static ResultCode Release(VAddr address); + private: Mutex(); ~Mutex() override; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 6204bcaaa0..92273b488d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -262,32 +262,14 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, "requesting_current_thread_handle=0x%08X", holding_thread_handle, mutex_addr, requesting_thread_handle); - SharedPtr holding_thread = g_handle_table.Get(holding_thread_handle); - SharedPtr requesting_thread = g_handle_table.Get(requesting_thread_handle); - - ASSERT(requesting_thread); - ASSERT(requesting_thread == GetCurrentThread()); - - SharedPtr mutex = g_object_address_table.Get(mutex_addr); - if (!mutex) { - // Create a new mutex for the specified address if one does not already exist - mutex = Mutex::Create(holding_thread, mutex_addr); - mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); - } - - ASSERT(holding_thread == mutex->GetHoldingThread()); - - return WaitSynchronization1(mutex, requesting_thread.get()); + return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle); } /// Unlock a mutex static ResultCode ArbitrateUnlock(VAddr mutex_addr) { LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr); - SharedPtr mutex = g_object_address_table.Get(mutex_addr); - ASSERT(mutex); - - return mutex->Release(GetCurrentThread()); + return Mutex::Release(mutex_addr); } /// Break program execution diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index f3a8aa4aa2..0a0ad7cfb4 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -126,6 +126,14 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { resume = thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr, 0); } + if (thread->mutex_wait_address != 0 || thread->condvar_wait_address != 0 || + thread->wait_handle) { + ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); + thread->mutex_wait_address = 0; + thread->condvar_wait_address = 0; + thread->wait_handle = 0; + } + if (resume) thread->ResumeFromWait(); } @@ -151,6 +159,7 @@ void Thread::ResumeFromWait() { case THREADSTATUS_WAIT_HLE_EVENT: case THREADSTATUS_WAIT_SLEEP: case THREADSTATUS_WAIT_IPC: + case THREADSTATUS_WAIT_MUTEX: break; case THREADSTATUS_READY: @@ -256,7 +265,9 @@ ResultVal> Thread::Create(std::string name, VAddr entry_point, thread->last_running_ticks = CoreTiming::GetTicks(); thread->processor_id = processor_id; thread->wait_objects.clear(); - thread->wait_address = 0; + thread->mutex_wait_address = 0; + thread->condvar_wait_address = 0; + thread->wait_handle = 0; thread->name = std::move(name); thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap(); thread->owner_process = owner_process; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index dbf47e2691..a3a6e6a643 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -43,6 +43,7 @@ enum ThreadStatus { THREADSTATUS_WAIT_IPC, ///< Waiting for the reply from an IPC request THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true + THREADSTATUS_WAIT_MUTEX, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc THREADSTATUS_DORMANT, ///< Created but not yet made ready THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated }; @@ -217,7 +218,10 @@ public: // passed to WaitSynchronization1/N. std::vector> wait_objects; - VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address + // If waiting on a ConditionVariable, this is the ConditionVariable address + VAddr condvar_wait_address; + VAddr mutex_wait_address; ///< If waiting on a Mutex, this is the mutex address + Handle wait_handle; ///< The handle used to wait for the mutex. std::string name; From b18ccf9399430a91790a93a122d5cd05266301ab Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 20 Apr 2018 14:39:28 -0500 Subject: [PATCH 02/74] Kernel: Properly implemented svcWaitProcessWideKey and svcSignalProcessWideKey They work in tandem with guest code to provide synchronization primitives along with svcArbitrateLock/Unlock --- src/core/hle/kernel/svc.cpp | 129 +++++++++++++----------------------- 1 file changed, 46 insertions(+), 83 deletions(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 92273b488d..99c1c2d2a1 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -616,77 +616,18 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var SharedPtr thread = g_handle_table.Get(thread_handle); ASSERT(thread); - SharedPtr mutex = g_object_address_table.Get(mutex_addr); - if (!mutex) { - // Create a new mutex for the specified address if one does not already exist - mutex = Mutex::Create(thread, mutex_addr); - mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); - } + CASCADE_CODE(Mutex::Release(mutex_addr)); - SharedPtr condition_variable = - g_object_address_table.Get(condition_variable_addr); - if (!condition_variable) { - // Create a new condition_variable for the specified address if one does not already exist - condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap(); - condition_variable->name = - Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); - } + SharedPtr current_thread = GetCurrentThread(); + current_thread->condvar_wait_address = condition_variable_addr; + current_thread->mutex_wait_address = mutex_addr; + current_thread->wait_handle = thread_handle; + current_thread->status = THREADSTATUS_WAIT_MUTEX; + current_thread->wakeup_callback = nullptr; - if (condition_variable->mutex_addr) { - // Previously created the ConditionVariable using WaitProcessWideKeyAtomic, verify - // everything is correct - ASSERT(condition_variable->mutex_addr == mutex_addr); - } else { - // Previously created the ConditionVariable using SignalProcessWideKey, set the mutex - // associated with it - condition_variable->mutex_addr = mutex_addr; - } - - if (mutex->GetOwnerHandle()) { - // Release the mutex if the current thread is holding it - mutex->Release(thread.get()); - } - - auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, - SharedPtr thread, - SharedPtr object, size_t index) { - ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); - - if (reason == ThreadWakeupReason::Timeout) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return true; - } - - ASSERT(reason == ThreadWakeupReason::Signal); - - // Now try to acquire the mutex and don't resume if it's not available. - if (!mutex->ShouldWait(thread.get())) { - mutex->Acquire(thread.get()); - thread->SetWaitSynchronizationResult(RESULT_SUCCESS); - return true; - } - - if (nano_seconds == 0) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return true; - } - - thread->wait_objects = {mutex}; - mutex->AddWaitingThread(thread); - thread->status = THREADSTATUS_WAIT_SYNCH_ANY; - - // Create an event to wake the thread up after the - // specified nanosecond delay has passed - thread->WakeAfterDelay(nano_seconds); - thread->wakeup_callback = DefaultThreadWakeupCallback; - - Core::System::GetInstance().PrepareReschedule(); - - return false; - }; - CASCADE_CODE( - WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback)); + current_thread->WakeAfterDelay(nano_seconds); + Core::System::GetInstance().PrepareReschedule(); return RESULT_SUCCESS; } @@ -695,24 +636,46 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x%llx, target=0x%08x", condition_variable_addr, target); - // Wakeup all or one thread - Any other value is unimplemented - ASSERT(target == -1 || target == 1); + u32 processed = 0; + auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList(); - SharedPtr condition_variable = - g_object_address_table.Get(condition_variable_addr); - if (!condition_variable) { - // Create a new condition_variable for the specified address if one does not already exist - condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap(); - condition_variable->name = - Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); - } + for (auto& thread : thread_list) { + if (thread->condvar_wait_address != condition_variable_addr) + continue; - CASCADE_CODE(condition_variable->Release(target)); + // Only process up to 'target' threads, unless 'target' is -1, in which case process + // them all. + if (target != -1 && processed >= target) + break; - if (condition_variable->mutex_addr) { - // If a mutex was created for this condition_variable, wait the current thread on it - SharedPtr mutex = g_object_address_table.Get(condition_variable->mutex_addr); - return WaitSynchronization1(mutex, GetCurrentThread()); + // If the mutex is not yet acquired, acquire it. + u32 mutex_val = Memory::Read32(thread->mutex_wait_address); + + if (mutex_val == 0) { + // We were able to acquire the mutex, resume this thread. + Memory::Write32(thread->mutex_wait_address, thread->wait_handle); + ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); + thread->ResumeFromWait(); + + thread->mutex_wait_address = 0; + thread->condvar_wait_address = 0; + thread->wait_handle = 0; + } else { + // Couldn't acquire the mutex, block the thread. + Handle owner_handle = static_cast(mutex_val & Mutex::MutexOwnerMask); + auto owner = g_handle_table.Get(owner_handle); + ASSERT(owner); + ASSERT(thread->status != THREADSTATUS_RUNNING); + thread->status = THREADSTATUS_WAIT_MUTEX; + thread->wakeup_callback = nullptr; + + // Signal that the mutex now has a waiting thread. + Memory::Write32(thread->mutex_wait_address, mutex_val | Mutex::MutexHasWaitersFlag); + + Core::System::GetInstance().PrepareReschedule(); + } + + ++processed; } return RESULT_SUCCESS; From 5fdfbfe25adafd2734a19fe94cccc58993cb12e7 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 20 Apr 2018 14:42:29 -0500 Subject: [PATCH 03/74] Kernel: Remove old and unused Mutex code. --- src/core/hle/kernel/mutex.cpp | 120 --------------------------------- src/core/hle/kernel/mutex.h | 82 +--------------------- src/core/hle/kernel/thread.cpp | 3 - src/core/hle/kernel/thread.h | 7 -- 4 files changed, 3 insertions(+), 209 deletions(-) diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 50a9a0805f..5cc0bd2665 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -40,126 +40,6 @@ static std::pair, u32> GetHighestPriorityMutexWaitingThread(VA return {highest_priority_thread, num_waiters}; } -void ReleaseThreadMutexes(Thread* thread) { - for (auto& mtx : thread->held_mutexes) { - mtx->SetHasWaiters(false); - mtx->SetHoldingThread(nullptr); - mtx->WakeupAllWaitingThreads(); - } - thread->held_mutexes.clear(); -} - -Mutex::Mutex() {} -Mutex::~Mutex() {} - -SharedPtr Mutex::Create(SharedPtr holding_thread, VAddr guest_addr, - std::string name) { - SharedPtr mutex(new Mutex); - - mutex->guest_addr = guest_addr; - mutex->name = std::move(name); - - // If mutex was initialized with a holding thread, acquire it by the holding thread - if (holding_thread) { - mutex->Acquire(holding_thread.get()); - } - - // Mutexes are referenced by guest address, so track this in the kernel - g_object_address_table.Insert(guest_addr, mutex); - - return mutex; -} - -bool Mutex::ShouldWait(Thread* thread) const { - auto holding_thread = GetHoldingThread(); - return holding_thread != nullptr && thread != holding_thread; -} - -void Mutex::Acquire(Thread* thread) { - ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); - - priority = thread->current_priority; - thread->held_mutexes.insert(this); - SetHoldingThread(thread); - thread->UpdatePriority(); - Core::System::GetInstance().PrepareReschedule(); -} - -ResultCode Mutex::Release(Thread* thread) { - auto holding_thread = GetHoldingThread(); - ASSERT(holding_thread); - - // We can only release the mutex if it's held by the calling thread. - ASSERT(thread == holding_thread); - - holding_thread->held_mutexes.erase(this); - holding_thread->UpdatePriority(); - SetHoldingThread(nullptr); - SetHasWaiters(!GetWaitingThreads().empty()); - WakeupAllWaitingThreads(); - Core::System::GetInstance().PrepareReschedule(); - - return RESULT_SUCCESS; -} - -void Mutex::AddWaitingThread(SharedPtr thread) { - WaitObject::AddWaitingThread(thread); - thread->pending_mutexes.insert(this); - SetHasWaiters(true); - UpdatePriority(); -} - -void Mutex::RemoveWaitingThread(Thread* thread) { - WaitObject::RemoveWaitingThread(thread); - thread->pending_mutexes.erase(this); - if (!GetHasWaiters()) - SetHasWaiters(!GetWaitingThreads().empty()); - UpdatePriority(); -} - -void Mutex::UpdatePriority() { - if (!GetHoldingThread()) - return; - - u32 best_priority = THREADPRIO_LOWEST; - for (auto& waiter : GetWaitingThreads()) { - if (waiter->current_priority < best_priority) - best_priority = waiter->current_priority; - } - - if (best_priority != priority) { - priority = best_priority; - GetHoldingThread()->UpdatePriority(); - } -} - -Handle Mutex::GetOwnerHandle() const { - GuestState guest_state{Memory::Read32(guest_addr)}; - return guest_state.holding_thread_handle; -} - -SharedPtr Mutex::GetHoldingThread() const { - GuestState guest_state{Memory::Read32(guest_addr)}; - return g_handle_table.Get(guest_state.holding_thread_handle); -} - -void Mutex::SetHoldingThread(SharedPtr thread) { - GuestState guest_state{Memory::Read32(guest_addr)}; - guest_state.holding_thread_handle.Assign(thread ? thread->guest_handle : 0); - Memory::Write32(guest_addr, guest_state.raw); -} - -bool Mutex::GetHasWaiters() const { - GuestState guest_state{Memory::Read32(guest_addr)}; - return guest_state.has_waiters != 0; -} - -void Mutex::SetHasWaiters(bool has_waiters) { - GuestState guest_state{Memory::Read32(guest_addr)}; - guest_state.has_waiters.Assign(has_waiters ? 1 : 0); - Memory::Write32(guest_addr, guest_state.raw); -} - ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, Handle requesting_thread_handle) { // The mutex address must be 4-byte aligned diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 3109230874..3117e7c709 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -15,68 +15,8 @@ namespace Kernel { class Thread; -class Mutex final : public WaitObject { +class Mutex final { public: - /** - * Creates a mutex. - * @param holding_thread Specifies a thread already holding the mutex. If not nullptr, this - * thread will acquire the mutex. - * @param guest_addr Address of the object tracking the mutex in guest memory. If specified, - * this mutex will update the guest object when its state changes. - * @param name Optional name of mutex - * @return Pointer to new Mutex object - */ - static SharedPtr Create(SharedPtr holding_thread, VAddr guest_addr = 0, - std::string name = "Unknown"); - - std::string GetTypeName() const override { - return "Mutex"; - } - std::string GetName() const override { - return name; - } - - static const HandleType HANDLE_TYPE = HandleType::Mutex; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - - u32 priority; ///< The priority of the mutex, used for priority inheritance. - std::string name; ///< Name of mutex (optional) - VAddr guest_addr; ///< Address of the guest mutex value - - /** - * Elevate the mutex priority to the best priority - * among the priorities of all its waiting threads. - */ - void UpdatePriority(); - - bool ShouldWait(Thread* thread) const override; - void Acquire(Thread* thread) override; - - void AddWaitingThread(SharedPtr thread) override; - void RemoveWaitingThread(Thread* thread) override; - - /** - * Attempts to release the mutex from the specified thread. - * @param thread Thread that wants to release the mutex. - * @returns The result code of the operation. - */ - ResultCode Release(Thread* thread); - - /// Gets the handle to the holding process stored in the guest state. - Handle GetOwnerHandle() const; - - /// Gets the Thread pointed to by the owner handle - SharedPtr GetHoldingThread() const; - /// Sets the holding process handle in the guest state. - void SetHoldingThread(SharedPtr thread); - - /// Returns the has_waiters bit in the guest state. - bool GetHasWaiters() const; - /// Sets the has_waiters bit in the guest state. - void SetHasWaiters(bool has_waiters); - /// Flag that indicates that a mutex still has threads waiting for it. static constexpr u32 MutexHasWaitersFlag = 0x40000000; /// Mask of the bits in a mutex address value that contain the mutex owner. @@ -90,24 +30,8 @@ public: static ResultCode Release(VAddr address); private: - Mutex(); - ~Mutex() override; - - /// Object in guest memory used to track the mutex state - union GuestState { - u32_le raw; - /// Handle of the thread that currently holds the mutex, 0 if available - BitField<0, 30, u32_le> holding_thread_handle; - /// 1 when there are threads waiting for this mutex, otherwise 0 - BitField<30, 1, u32_le> has_waiters; - }; - static_assert(sizeof(GuestState) == 4, "GuestState size is incorrect"); + Mutex() = default; + ~Mutex() = default; }; -/** - * Releases all the mutexes held by the specified thread - * @param thread Thread that is holding the mutexes - */ -void ReleaseThreadMutexes(Thread* thread); - } // namespace Kernel diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 0a0ad7cfb4..8093c44960 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -77,9 +77,6 @@ void Thread::Stop() { } wait_objects.clear(); - // Release all the mutexes that this thread holds - ReleaseThreadMutexes(this); - // Mark the TLS slot in the thread's page as free. u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; u64 tls_slot = diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index a3a6e6a643..74d5904b8f 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -55,7 +55,6 @@ enum class ThreadWakeupReason { namespace Kernel { -class Mutex; class Process; class Thread final : public WaitObject { @@ -206,12 +205,6 @@ public: VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread - /// Mutexes currently held by this thread, which will be released when it exits. - boost::container::flat_set> held_mutexes; - - /// Mutexes that this thread is currently waiting for. - boost::container::flat_set> pending_mutexes; - SharedPtr owner_process; ///< Process that owns this thread /// Objects that the thread is waiting on, in the same order as they were From be155f4d9d410886853c25ffa032ce41a7428337 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 20 Apr 2018 14:45:52 -0500 Subject: [PATCH 04/74] Kernel: Remove unused ConditionVariable class. --- src/core/CMakeLists.txt | 2 - src/core/hle/kernel/condition_variable.cpp | 64 ---------------------- src/core/hle/kernel/condition_variable.h | 63 --------------------- src/core/hle/kernel/svc.cpp | 6 -- src/core/hle/kernel/thread.cpp | 9 --- src/core/hle/kernel/thread.h | 6 -- 6 files changed, 150 deletions(-) delete mode 100644 src/core/hle/kernel/condition_variable.cpp delete mode 100644 src/core/hle/kernel/condition_variable.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c1a645460c..b3807c2040 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -42,8 +42,6 @@ add_library(core STATIC hle/kernel/client_port.h hle/kernel/client_session.cpp hle/kernel/client_session.h - hle/kernel/condition_variable.cpp - hle/kernel/condition_variable.h hle/kernel/errors.h hle/kernel/event.cpp hle/kernel/event.h diff --git a/src/core/hle/kernel/condition_variable.cpp b/src/core/hle/kernel/condition_variable.cpp deleted file mode 100644 index a786d7f740..0000000000 --- a/src/core/hle/kernel/condition_variable.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "common/assert.h" -#include "core/hle/kernel/condition_variable.h" -#include "core/hle/kernel/errors.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/object_address_table.h" -#include "core/hle/kernel/thread.h" - -namespace Kernel { - -ConditionVariable::ConditionVariable() {} -ConditionVariable::~ConditionVariable() {} - -ResultVal> ConditionVariable::Create(VAddr guest_addr, - std::string name) { - SharedPtr condition_variable(new ConditionVariable); - - condition_variable->name = std::move(name); - condition_variable->guest_addr = guest_addr; - condition_variable->mutex_addr = 0; - - // Condition variables are referenced by guest address, so track this in the kernel - g_object_address_table.Insert(guest_addr, condition_variable); - - return MakeResult>(std::move(condition_variable)); -} - -bool ConditionVariable::ShouldWait(Thread* thread) const { - return GetAvailableCount() <= 0; -} - -void ConditionVariable::Acquire(Thread* thread) { - if (GetAvailableCount() <= 0) - return; - - SetAvailableCount(GetAvailableCount() - 1); -} - -ResultCode ConditionVariable::Release(s32 target) { - if (target == -1) { - // When -1, wake up all waiting threads - SetAvailableCount(static_cast(GetWaitingThreads().size())); - WakeupAllWaitingThreads(); - } else { - // Otherwise, wake up just a single thread - SetAvailableCount(target); - WakeupWaitingThread(GetHighestPriorityReadyThread()); - } - - return RESULT_SUCCESS; -} - -s32 ConditionVariable::GetAvailableCount() const { - return Memory::Read32(guest_addr); -} - -void ConditionVariable::SetAvailableCount(s32 value) const { - Memory::Write32(guest_addr, value); -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/condition_variable.h b/src/core/hle/kernel/condition_variable.h deleted file mode 100644 index 1c9f067694..0000000000 --- a/src/core/hle/kernel/condition_variable.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include -#include -#include "common/common_types.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/wait_object.h" -#include "core/hle/result.h" - -namespace Kernel { - -class ConditionVariable final : public WaitObject { -public: - /** - * Creates a condition variable. - * @param guest_addr Address of the object tracking the condition variable in guest memory. If - * specified, this condition variable will update the guest object when its state changes. - * @param name Optional name of condition variable. - * @return The created condition variable. - */ - static ResultVal> Create(VAddr guest_addr, - std::string name = "Unknown"); - - std::string GetTypeName() const override { - return "ConditionVariable"; - } - std::string GetName() const override { - return name; - } - - static const HandleType HANDLE_TYPE = HandleType::ConditionVariable; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - - s32 GetAvailableCount() const; - void SetAvailableCount(s32 value) const; - - std::string name; ///< Name of condition variable (optional) - VAddr guest_addr; ///< Address of the guest condition variable value - VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this condition - ///< variable, used for implementing events - - bool ShouldWait(Thread* thread) const override; - void Acquire(Thread* thread) override; - - /** - * Releases a slot from a condition variable. - * @param target The number of threads to wakeup, -1 is all. - * @return ResultCode indicating if the operation succeeded. - */ - ResultCode Release(s32 target); - -private: - ConditionVariable(); - ~ConditionVariable() override; -}; - -} // namespace Kernel diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 99c1c2d2a1..082c36cafd 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -13,7 +13,6 @@ #include "core/core_timing.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" -#include "core/hle/kernel/condition_variable.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/mutex.h" @@ -394,11 +393,6 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { } thread->SetPriority(priority); - thread->UpdatePriority(); - - // Update the mutexes that this thread is waiting for - for (auto& mutex : thread->pending_mutexes) - mutex->UpdatePriority(); Core::System::GetInstance().PrepareReschedule(); return RESULT_SUCCESS; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 8093c44960..16d9b9e365 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -329,15 +329,6 @@ void Thread::SetPriority(u32 priority) { nominal_priority = current_priority = priority; } -void Thread::UpdatePriority() { - u32 best_priority = nominal_priority; - for (auto& mutex : held_mutexes) { - if (mutex->priority < best_priority) - best_priority = mutex->priority; - } - BoostPriority(best_priority); -} - void Thread::BoostPriority(u32 priority) { Core::System::GetInstance().Scheduler().SetThreadPriority(this, priority); current_priority = priority; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 74d5904b8f..ee13d20f1a 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -103,12 +103,6 @@ public: */ void SetPriority(u32 priority); - /** - * Boost's a thread's priority to the best priority among the thread's held mutexes. - * This prevents priority inversion via priority inheritance. - */ - void UpdatePriority(); - /** * Temporarily boosts the thread's priority until the next time it is scheduled * @param priority The new priority From 013778aa21bad3769b739d14843b8ef2bb3185c9 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 20 Apr 2018 15:52:06 -0500 Subject: [PATCH 05/74] Qt: Update the WaitTree widget to show info about the current mutex of each thread. --- src/core/hle/kernel/kernel.h | 4 - .../hle/service/nvflinger/buffer_queue.cpp | 6 +- src/core/hle/service/nvflinger/buffer_queue.h | 6 +- src/yuzu/debugger/wait_tree.cpp | 86 +++++++------------ src/yuzu/debugger/wait_tree.h | 43 +++------- 5 files changed, 55 insertions(+), 90 deletions(-) diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 053bf4e17e..402ae900f4 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -18,12 +18,10 @@ using Handle = u32; enum class HandleType : u32 { Unknown, Event, - Mutex, SharedMemory, Thread, Process, AddressArbiter, - ConditionVariable, Timer, ResourceLimit, CodeSet, @@ -63,9 +61,7 @@ public: bool IsWaitable() const { switch (GetHandleType()) { case HandleType::Event: - case HandleType::Mutex: case HandleType::Thread: - case HandleType::ConditionVariable: case HandleType::Timer: case HandleType::ServerPort: case HandleType::ServerSession: diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 03a4fed590..e4ff2e2677 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -9,7 +9,8 @@ #include "core/core_timing.h" #include "core/hle/service/nvflinger/buffer_queue.h" -namespace Service::NVFlinger { +namespace Service { +namespace NVFlinger { BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { native_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "BufferQueue NativeHandle"); @@ -110,4 +111,5 @@ void BufferQueue::SetBufferWaitEvent(Kernel::SharedPtr&& wait_eve buffer_wait_event = std::move(wait_event); } -} // namespace Service::NVFlinger +} // namespace NVFlinger +} // namespace Service diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 95adc47068..1de5767cbe 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -13,7 +13,8 @@ namespace CoreTiming { struct EventType; } -namespace Service::NVFlinger { +namespace Service { +namespace NVFlinger { struct IGBPBuffer { u32_le magic; @@ -97,4 +98,5 @@ private: Kernel::SharedPtr buffer_wait_event; }; -} // namespace Service::NVFlinger +} // namespace NVFlinger +} // namespace Service diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index cae2864e57..acc4c2e0be 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -6,8 +6,8 @@ #include "yuzu/util/util.h" #include "core/core.h" -#include "core/hle/kernel/condition_variable.h" #include "core/hle/kernel/event.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/timer.h" @@ -67,6 +67,29 @@ QString WaitTreeText::GetText() const { return text; } +WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address) : mutex_address(mutex_address) { + mutex_value = Memory::Read32(mutex_address); + owner_handle = static_cast(mutex_value & Kernel::Mutex::MutexOwnerMask); + owner = Kernel::g_handle_table.Get(owner_handle); +} + +QString WaitTreeMutexInfo::GetText() const { + return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char('0')); +} + +std::vector> WaitTreeMutexInfo::GetChildren() const { + std::vector> list; + + bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0; + + list.push_back(std::make_unique(tr("has waiters: %1").arg(has_waiters))); + list.push_back(std::make_unique( + tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char('0')))); + if (owner != nullptr) + list.push_back(std::make_unique(*owner)); + return list; +} + WaitTreeWaitObject::WaitTreeWaitObject(const Kernel::WaitObject& o) : object(o) {} bool WaitTreeExpandableItem::IsExpandable() const { @@ -84,11 +107,6 @@ std::unique_ptr WaitTreeWaitObject::make(const Kernel::WaitO switch (object.GetHandleType()) { case Kernel::HandleType::Event: return std::make_unique(static_cast(object)); - case Kernel::HandleType::Mutex: - return std::make_unique(static_cast(object)); - case Kernel::HandleType::ConditionVariable: - return std::make_unique( - static_cast(object)); case Kernel::HandleType::Timer: return std::make_unique(static_cast(object)); case Kernel::HandleType::Thread: @@ -160,6 +178,9 @@ QString WaitTreeThread::GetText() const { case THREADSTATUS_WAIT_SYNCH_ANY: status = tr("waiting for objects"); break; + case THREADSTATUS_WAIT_MUTEX: + status = tr("waiting for mutex"); + break; case THREADSTATUS_DORMANT: status = tr("dormant"); break; @@ -186,6 +207,7 @@ QColor WaitTreeThread::GetColor() const { return QColor(Qt::GlobalColor::darkYellow); case THREADSTATUS_WAIT_SYNCH_ALL: case THREADSTATUS_WAIT_SYNCH_ANY: + case THREADSTATUS_WAIT_MUTEX: return QColor(Qt::GlobalColor::red); case THREADSTATUS_DORMANT: return QColor(Qt::GlobalColor::darkCyan); @@ -225,11 +247,11 @@ std::vector> WaitTreeThread::GetChildren() const { list.push_back(std::make_unique( tr("last running ticks = %1").arg(thread.last_running_ticks))); - if (thread.held_mutexes.empty()) { - list.push_back(std::make_unique(tr("not holding mutex"))); - } else { - list.push_back(std::make_unique(thread.held_mutexes)); - } + if (thread.mutex_wait_address != 0) + list.push_back(std::make_unique(thread.mutex_wait_address)); + else + list.push_back(std::make_unique(tr("not waiting for mutex"))); + if (thread.status == THREADSTATUS_WAIT_SYNCH_ANY || thread.status == THREADSTATUS_WAIT_SYNCH_ALL) { list.push_back(std::make_unique(thread.wait_objects, @@ -250,33 +272,6 @@ std::vector> WaitTreeEvent::GetChildren() const { return list; } -WaitTreeMutex::WaitTreeMutex(const Kernel::Mutex& object) : WaitTreeWaitObject(object) {} - -std::vector> WaitTreeMutex::GetChildren() const { - std::vector> list(WaitTreeWaitObject::GetChildren()); - - const auto& mutex = static_cast(object); - if (mutex.GetHasWaiters()) { - list.push_back(std::make_unique(tr("locked by thread:"))); - list.push_back(std::make_unique(*mutex.GetHoldingThread())); - } else { - list.push_back(std::make_unique(tr("free"))); - } - return list; -} - -WaitTreeConditionVariable::WaitTreeConditionVariable(const Kernel::ConditionVariable& object) - : WaitTreeWaitObject(object) {} - -std::vector> WaitTreeConditionVariable::GetChildren() const { - std::vector> list(WaitTreeWaitObject::GetChildren()); - - const auto& condition_variable = static_cast(object); - list.push_back(std::make_unique( - tr("available count = %1").arg(condition_variable.GetAvailableCount()))); - return list; -} - WaitTreeTimer::WaitTreeTimer(const Kernel::Timer& object) : WaitTreeWaitObject(object) {} std::vector> WaitTreeTimer::GetChildren() const { @@ -293,21 +288,6 @@ std::vector> WaitTreeTimer::GetChildren() const { return list; } -WaitTreeMutexList::WaitTreeMutexList( - const boost::container::flat_set>& list) - : mutex_list(list) {} - -QString WaitTreeMutexList::GetText() const { - return tr("holding mutexes"); -} - -std::vector> WaitTreeMutexList::GetChildren() const { - std::vector> list(mutex_list.size()); - std::transform(mutex_list.begin(), mutex_list.end(), list.begin(), - [](const auto& t) { return std::make_unique(*t); }); - return list; -} - WaitTreeThreadList::WaitTreeThreadList(const std::vector>& list) : thread_list(list) {} diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index e538174ebb..300ba9ae46 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -16,8 +16,6 @@ class EmuThread; namespace Kernel { class WaitObject; class Event; -class Mutex; -class ConditionVariable; class Thread; class Timer; } // namespace Kernel @@ -61,6 +59,20 @@ public: bool IsExpandable() const override; }; +class WaitTreeMutexInfo : public WaitTreeExpandableItem { + Q_OBJECT +public: + explicit WaitTreeMutexInfo(VAddr mutex_address); + QString GetText() const override; + std::vector> GetChildren() const override; + +private: + VAddr mutex_address; + u32 mutex_value; + Kernel::Handle owner_handle; + Kernel::SharedPtr owner; +}; + class WaitTreeWaitObject : public WaitTreeExpandableItem { Q_OBJECT public: @@ -104,20 +116,6 @@ public: std::vector> GetChildren() const override; }; -class WaitTreeMutex : public WaitTreeWaitObject { - Q_OBJECT -public: - explicit WaitTreeMutex(const Kernel::Mutex& object); - std::vector> GetChildren() const override; -}; - -class WaitTreeConditionVariable : public WaitTreeWaitObject { - Q_OBJECT -public: - explicit WaitTreeConditionVariable(const Kernel::ConditionVariable& object); - std::vector> GetChildren() const override; -}; - class WaitTreeTimer : public WaitTreeWaitObject { Q_OBJECT public: @@ -125,19 +123,6 @@ public: std::vector> GetChildren() const override; }; -class WaitTreeMutexList : public WaitTreeExpandableItem { - Q_OBJECT -public: - explicit WaitTreeMutexList( - const boost::container::flat_set>& list); - - QString GetText() const override; - std::vector> GetChildren() const override; - -private: - const boost::container::flat_set>& mutex_list; -}; - class WaitTreeThreadList : public WaitTreeExpandableItem { Q_OBJECT public: From a70ed9c8ae034a1035d1b099161ad740840c5a94 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 20 Apr 2018 17:41:11 -0500 Subject: [PATCH 06/74] Kernel: Use 0x2C as default main thread priority for homebrew and lone NRO/NSOs --- src/core/hle/kernel/thread.h | 2 +- src/core/loader/nro.cpp | 2 +- src/core/loader/nso.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index ee13d20f1a..0e0eae28d6 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -18,7 +18,7 @@ enum ThreadPriority : u32 { THREADPRIO_HIGHEST = 0, ///< Highest thread priority THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps - THREADPRIO_DEFAULT = 48, ///< Default thread priority for userland apps + THREADPRIO_DEFAULT = 44, ///< Default thread priority for userland apps THREADPRIO_LOWEST = 63, ///< Lowest thread priority }; diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index b5133e4d64..3853cfa1a9 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -137,7 +137,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr& process) { process->address_mappings = default_address_mappings; process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); - process->Run(base_addr, 48, Memory::DEFAULT_STACK_SIZE); + process->Run(base_addr, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); is_loaded = true; return ResultStatus::Success; diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 3bc10ed0d5..962bed2ab4 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -165,7 +165,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr& process) { process->address_mappings = default_address_mappings; process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); - process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Memory::DEFAULT_STACK_SIZE); + process->Run(Memory::PROCESS_IMAGE_VADDR, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); is_loaded = true; return ResultStatus::Success; From 010227e1490c01484903d4e9cf9038e74906ec7c Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 10:50:28 -0500 Subject: [PATCH 07/74] GPU: Implement the RGB10_A2 RenderTarget format, it will use the same format as the A2BGR10 texture format. --- src/video_core/renderer_opengl/gl_rasterizer_cache.h | 2 ++ src/yuzu/debugger/graphics/graphics_surface.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index e4cb3390fe..bf0fabb293 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -106,6 +106,8 @@ struct SurfaceParams { switch (format) { case Tegra::RenderTargetFormat::RGBA8_UNORM: return PixelFormat::ABGR8; + case Tegra::RenderTargetFormat::RGB10_A2_UNORM: + return PixelFormat::A2B10G10R10; default: NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast(format)); UNREACHABLE(); diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index 1e4844b578..5fada74be9 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp @@ -25,6 +25,8 @@ static Tegra::Texture::TextureFormat ConvertToTextureFormat( switch (render_target_format) { case Tegra::RenderTargetFormat::RGBA8_UNORM: return Tegra::Texture::TextureFormat::A8R8G8B8; + case Tegra::RenderTargetFormat::RGB10_A2_UNORM: + return Tegra::Texture::TextureFormat::A2B10G10R10; default: UNIMPLEMENTED_MSG("Unimplemented RT format"); } From f823c1d5991657a3d91f97c345e1f01a1162fca7 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 10:57:12 -0500 Subject: [PATCH 08/74] GPU: Make the GPU virtual memory manager use 16 page bits and 10 page table bits. Also removed some dead code and added memory map consistency asserts. --- src/video_core/memory_manager.cpp | 53 ++++++++++++------------------- src/video_core/memory_manager.h | 6 +++- 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 2789a4ca12..2e1edee030 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/alignment.h" #include "common/assert.h" #include "video_core/memory_manager.h" @@ -11,7 +12,8 @@ PAddr MemoryManager::AllocateSpace(u64 size, u64 align) { boost::optional paddr = FindFreeBlock(size, align); ASSERT(paddr); - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { + for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { + ASSERT(PageSlot(*paddr + offset) == static_cast(PageStatus::Unmapped)); PageSlot(*paddr + offset) = static_cast(PageStatus::Allocated); } @@ -19,13 +21,8 @@ PAddr MemoryManager::AllocateSpace(u64 size, u64 align) { } PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) { - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { - if (IsPageMapped(paddr + offset)) { - return AllocateSpace(size, align); - } - } - - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { + for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { + ASSERT(PageSlot(paddr + offset) == static_cast(PageStatus::Unmapped)); PageSlot(paddr + offset) = static_cast(PageStatus::Allocated); } @@ -33,12 +30,11 @@ PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) { } PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) { - vaddr &= ~Memory::PAGE_MASK; - - boost::optional paddr = FindFreeBlock(size); + boost::optional paddr = FindFreeBlock(size, PAGE_SIZE); ASSERT(paddr); - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { + for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { + ASSERT(PageSlot(*paddr + offset) == static_cast(PageStatus::Unmapped)); PageSlot(*paddr + offset) = vaddr + offset; } @@ -46,16 +42,10 @@ PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) { } PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) { - vaddr &= ~Memory::PAGE_MASK; - paddr &= ~Memory::PAGE_MASK; + ASSERT((paddr & PAGE_MASK) == 0); - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { - if (PageSlot(paddr + offset) != static_cast(PageStatus::Allocated)) { - return MapBufferEx(vaddr, size); - } - } - - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { + for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { + ASSERT(PageSlot(paddr + offset) == static_cast(PageStatus::Allocated)); PageSlot(paddr + offset) = vaddr + offset; } @@ -63,23 +53,20 @@ PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) { } boost::optional MemoryManager::FindFreeBlock(u64 size, u64 align) { - PAddr paddr{}; - u64 free_space{}; - align = (align + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; + PAddr paddr = 0; + u64 free_space = 0; + align = (align + PAGE_MASK) & ~PAGE_MASK; while (paddr + free_space < MAX_ADDRESS) { if (!IsPageMapped(paddr + free_space)) { - free_space += Memory::PAGE_SIZE; + free_space += PAGE_SIZE; if (free_space >= size) { return paddr; } } else { - paddr += free_space + Memory::PAGE_SIZE; + paddr += free_space + PAGE_SIZE; free_space = 0; - const u64 remainder{paddr % align}; - if (!remainder) { - paddr = (paddr - remainder) + align; - } + paddr = Common::AlignUp(paddr, align); } } @@ -89,7 +76,7 @@ boost::optional MemoryManager::FindFreeBlock(u64 size, u64 align) { VAddr MemoryManager::PhysicalToVirtualAddress(PAddr paddr) { VAddr base_addr = PageSlot(paddr); ASSERT(base_addr != static_cast(PageStatus::Unmapped)); - return base_addr + (paddr & Memory::PAGE_MASK); + return base_addr + (paddr & PAGE_MASK); } bool MemoryManager::IsPageMapped(PAddr paddr) { @@ -97,14 +84,14 @@ bool MemoryManager::IsPageMapped(PAddr paddr) { } VAddr& MemoryManager::PageSlot(PAddr paddr) { - auto& block = page_table[(paddr >> (Memory::PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; + auto& block = page_table[(paddr >> (PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; if (!block) { block = std::make_unique(); for (unsigned index = 0; index < PAGE_BLOCK_SIZE; index++) { (*block)[index] = static_cast(PageStatus::Unmapped); } } - return (*block)[(paddr >> Memory::PAGE_BITS) & PAGE_BLOCK_MASK]; + return (*block)[(paddr >> PAGE_BITS) & PAGE_BLOCK_MASK]; } } // namespace Tegra diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 47da7acd65..b73e283f84 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h @@ -24,6 +24,10 @@ public: PAddr MapBufferEx(VAddr vaddr, PAddr paddr, u64 size); VAddr PhysicalToVirtualAddress(PAddr paddr); + static constexpr u64 PAGE_BITS = 16; + static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS; + static constexpr u64 PAGE_MASK = PAGE_SIZE - 1; + private: boost::optional FindFreeBlock(u64 size, u64 align = 1); bool IsPageMapped(PAddr paddr); @@ -35,7 +39,7 @@ private: }; static constexpr u64 MAX_ADDRESS{0x10000000000ULL}; - static constexpr u64 PAGE_TABLE_BITS{14}; + static constexpr u64 PAGE_TABLE_BITS{10}; static constexpr u64 PAGE_TABLE_SIZE{1 << PAGE_TABLE_BITS}; static constexpr u64 PAGE_TABLE_MASK{PAGE_TABLE_SIZE - 1}; static constexpr u64 PAGE_BLOCK_BITS{14}; From e862c50a7072110a1f3dafec8a42fd71ecaba706 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 11:13:53 -0500 Subject: [PATCH 09/74] Nvdrv: Assert when receiving an unimplemented ioctl in the nv* handlers. --- src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 2 +- src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 2 +- src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 2 +- src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | 2 +- src/core/hle/service/nvdrv/devices/nvmap.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 61f22b1a5a..aa6c7e8dc9 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -13,7 +13,7 @@ namespace Service::Nvidia::Devices { u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector& input, std::vector& output) { - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 660a0f6652..6e1ba1ac7e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -18,7 +18,7 @@ u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector& input, std::vector< case IoctlCommand::IocCtrlEventWaitCommand: return IocCtrlEventWait(input, output); } - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 18ea12ef55..b715723d31 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -25,7 +25,7 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector& input, std::vec case IoctlCommand::IocZcullGetInfo: return ZCullGetInfo(input, output); } - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index a16e904570..dab6d0533d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -40,7 +40,7 @@ u32 nvhost_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& input, std::vector& o return IocParam(input, output); } - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } From e4bd0bddeaaec31a13484bc791e181052211d9ad Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 11:06:07 -0500 Subject: [PATCH 10/74] Nvdrv/nvhost-as-gpu: Implemented the ioctl REMAP command. It takes a previously-reserved (AllocateSpace) GPU memory address and maps it to the address of the nvmap object passed to Remap. --- .../service/nvdrv/devices/nvhost_as_gpu.cpp | 35 +++++++++++++++++++ .../hle/service/nvdrv/devices/nvhost_as_gpu.h | 12 +++++++ 2 files changed, 47 insertions(+) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 71e8449598..8c56fa1506 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -27,6 +27,11 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector& input, std::vecto case IoctlCommand::IocGetVaRegionsCommand: return GetVARegions(input, output); } + + if (static_cast(command.cmd.Value()) == IoctlCommand::IocRemapCommand) + return Remap(input, output); + + UNIMPLEMENTED_MSG("Unimplemented ioctl command"); return 0; } @@ -56,6 +61,36 @@ u32 nvhost_as_gpu::AllocateSpace(const std::vector& input, std::vector& return 0; } +u32 nvhost_as_gpu::Remap(const std::vector& input, std::vector& output) { + size_t num_entries = input.size() / sizeof(IoctlRemapEntry); + + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries=0x{:X}", num_entries); + + std::vector entries(num_entries); + std::memcpy(entries.data(), input.data(), input.size()); + + auto& gpu = Core::System::GetInstance().GPU(); + + for (const auto& entry : entries) { + NGLOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}", + entry.offset, entry.nvmap_handle, entry.pages); + Tegra::GPUVAddr offset = static_cast(entry.offset) << 0x10; + + auto object = nvmap_dev->GetObject(entry.nvmap_handle); + ASSERT(object); + + ASSERT(object->status == nvmap::Object::Status::Allocated); + + u64 size = static_cast(entry.pages) << 0x10; + ASSERT(size <= object->size); + + Tegra::GPUVAddr returned = gpu.memory_manager->MapBufferEx(object->addr, offset, size); + ASSERT(returned == offset); + } + std::memcpy(output.data(), entries.data(), output.size()); + return 0; +} + u32 nvhost_as_gpu::MapBufferEx(const std::vector& input, std::vector& output) { IoctlMapBufferEx params{}; std::memcpy(¶ms, input.data(), input.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index d86c3ebd92..f2dd0c3b33 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h @@ -26,6 +26,7 @@ private: enum class IoctlCommand : u32_le { IocInitalizeExCommand = 0x40284109, IocAllocateSpaceCommand = 0xC0184102, + IocRemapCommand = 0x00000014, IocMapBufferExCommand = 0xC0284106, IocBindChannelCommand = 0x40044101, IocGetVaRegionsCommand = 0xC0404108, @@ -54,6 +55,16 @@ private: }; static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size"); + struct IoctlRemapEntry { + u16_le flags; + u16_le kind; + u32_le nvmap_handle; + INSERT_PADDING_WORDS(1); + u32_le offset; + u32_le pages; + }; + static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size"); + struct IoctlMapBufferEx { u32_le flags; // bit0: fixed_offset, bit2: cacheable u32_le kind; // -1 is default @@ -91,6 +102,7 @@ private: u32 InitalizeEx(const std::vector& input, std::vector& output); u32 AllocateSpace(const std::vector& input, std::vector& output); + u32 Remap(const std::vector& input, std::vector& output); u32 MapBufferEx(const std::vector& input, std::vector& output); u32 BindChannel(const std::vector& input, std::vector& output); u32 GetVARegions(const std::vector& input, std::vector& output); From 0d6eafe11a12863295e05fb7d9d18302b667d583 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 11:10:00 -0500 Subject: [PATCH 11/74] NvDrv/nvhost-as-gpu: Ensure that the object passed to MapBufferEx has already been allocated. Also added a consistency check and a comment for the case when the object id is different than its handle. The real nvservices doesn't make a distinction between ids and handles, each object gets an unique handle which doubles as its id. --- src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 8c56fa1506..8e7ca61235 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -108,6 +108,16 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector& input, std::vector& ou auto object = nvmap_dev->GetObject(params.nvmap_handle); ASSERT(object); + // We can only map objects that have already been assigned a CPU address. + ASSERT(object->status == nvmap::Object::Status::Allocated); + + ASSERT(params.buffer_offset == 0); + + // The real nvservices doesn't make a distinction between handles and ids, and + // object can only have one handle and it will be the same as its id. Assert that this is the + // case to prevent unexpected behavior. + ASSERT(object->id == params.nvmap_handle); + auto& gpu = Core::System::GetInstance().GPU(); if (params.flags & 1) { From 46572d027dc9620ed2b2a50277e6afd2a115ab81 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 20 Apr 2018 20:15:16 -0500 Subject: [PATCH 12/74] Kernel: Implemented mutex priority inheritance. Verified with a hwtest and implemented based on reverse engineering. Thread A's priority will get bumped to the highest priority among all the threads that are waiting for a mutex that A holds. Once A releases the mutex and ownership is transferred to B, A's priority will return to normal and B's priority will be bumped. --- src/core/hle/kernel/mutex.cpp | 39 +++++++++++++++++++++++++------- src/core/hle/kernel/svc.cpp | 9 ++++++++ src/core/hle/kernel/thread.cpp | 41 ++++++++++++++++++++++++++++++++-- src/core/hle/kernel/thread.h | 15 +++++++++++++ 4 files changed, 94 insertions(+), 10 deletions(-) diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 5cc0bd2665..63733ad79e 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -18,13 +18,13 @@ namespace Kernel { /// Returns the number of threads that are waiting for a mutex, and the highest priority one among /// those. -static std::pair, u32> GetHighestPriorityMutexWaitingThread(VAddr mutex_addr) { - auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList(); +static std::pair, u32> GetHighestPriorityMutexWaitingThread( + SharedPtr current_thread, VAddr mutex_addr) { SharedPtr highest_priority_thread; u32 num_waiters = 0; - for (auto& thread : thread_list) { + for (auto& thread : current_thread->wait_mutex_threads) { if (thread->mutex_wait_address != mutex_addr) continue; @@ -40,6 +40,21 @@ static std::pair, u32> GetHighestPriorityMutexWaitingThread(VA return {highest_priority_thread, num_waiters}; } +/// Update the mutex owner field of all threads waiting on the mutex to point to the new owner. +static void TransferMutexOwnership(VAddr mutex_addr, SharedPtr current_thread, + SharedPtr new_owner) { + auto threads = current_thread->wait_mutex_threads; + for (auto& thread : threads) { + if (thread->mutex_wait_address != mutex_addr) + continue; + + ASSERT(thread->lock_owner == current_thread); + current_thread->RemoveMutexWaiter(thread); + if (new_owner != thread) + new_owner->AddMutexWaiter(thread); + } +} + ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, Handle requesting_thread_handle) { // The mutex address must be 4-byte aligned @@ -65,11 +80,14 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, return ERR_INVALID_HANDLE; // Wait until the mutex is released - requesting_thread->mutex_wait_address = address; - requesting_thread->wait_handle = requesting_thread_handle; + GetCurrentThread()->mutex_wait_address = address; + GetCurrentThread()->wait_handle = requesting_thread_handle; - requesting_thread->status = THREADSTATUS_WAIT_MUTEX; - requesting_thread->wakeup_callback = nullptr; + GetCurrentThread()->status = THREADSTATUS_WAIT_MUTEX; + GetCurrentThread()->wakeup_callback = nullptr; + + // Update the lock holder thread's priority to prevent priority inversion. + holding_thread->AddMutexWaiter(GetCurrentThread()); Core::System::GetInstance().PrepareReschedule(); @@ -82,14 +100,18 @@ ResultCode Mutex::Release(VAddr address) { return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress); } - auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(address); + auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(GetCurrentThread(), address); // There are no more threads waiting for the mutex, release it completely. if (thread == nullptr) { + ASSERT(GetCurrentThread()->wait_mutex_threads.empty()); Memory::Write32(address, 0); return RESULT_SUCCESS; } + // Transfer the ownership of the mutex from the previous owner to the new one. + TransferMutexOwnership(address, GetCurrentThread(), thread); + u32 mutex_value = thread->wait_handle; if (num_waiters >= 2) { @@ -103,6 +125,7 @@ ResultCode Mutex::Release(VAddr address) { ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); thread->ResumeFromWait(); + thread->lock_owner = nullptr; thread->condvar_wait_address = 0; thread->mutex_wait_address = 0; thread->wait_handle = 0; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 082c36cafd..a3015cf7a7 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -621,6 +621,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var current_thread->WakeAfterDelay(nano_seconds); + // Note: Deliberately don't attempt to inherit the lock owner's priority. + Core::System::GetInstance().PrepareReschedule(); return RESULT_SUCCESS; } @@ -651,6 +653,11 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); thread->ResumeFromWait(); + auto lock_owner = thread->lock_owner; + if (lock_owner) + lock_owner->RemoveMutexWaiter(thread); + + thread->lock_owner = nullptr; thread->mutex_wait_address = 0; thread->condvar_wait_address = 0; thread->wait_handle = 0; @@ -666,6 +673,8 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target // Signal that the mutex now has a waiting thread. Memory::Write32(thread->mutex_wait_address, mutex_val | Mutex::MutexHasWaitersFlag); + owner->AddMutexWaiter(thread); + Core::System::GetInstance().PrepareReschedule(); } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 16d9b9e365..36222d45fe 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -129,6 +129,11 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { thread->mutex_wait_address = 0; thread->condvar_wait_address = 0; thread->wait_handle = 0; + + auto lock_owner = thread->lock_owner; + // Threads waking up by timeout from WaitProcessWideKey do not perform priority inheritance + // and don't have a lock owner. + ASSERT(lock_owner == nullptr); } if (resume) @@ -325,8 +330,8 @@ ResultVal> Thread::Create(std::string name, VAddr entry_point, void Thread::SetPriority(u32 priority) { ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST, "Invalid priority value."); - Core::System::GetInstance().Scheduler().SetThreadPriority(this, priority); - nominal_priority = current_priority = priority; + nominal_priority = priority; + UpdatePriority(); } void Thread::BoostPriority(u32 priority) { @@ -376,6 +381,38 @@ VAddr Thread::GetCommandBufferAddress() const { return GetTLSAddress() + CommandHeaderOffset; } +void Thread::AddMutexWaiter(SharedPtr thread) { + thread->lock_owner = this; + wait_mutex_threads.emplace_back(std::move(thread)); + UpdatePriority(); +} + +void Thread::RemoveMutexWaiter(SharedPtr thread) { + boost::remove_erase(wait_mutex_threads, thread); + thread->lock_owner = nullptr; + UpdatePriority(); +} + +void Thread::UpdatePriority() { + // Find the highest priority among all the threads that are waiting for this thread's lock + u32 new_priority = nominal_priority; + for (const auto& thread : wait_mutex_threads) { + if (thread->nominal_priority < new_priority) + new_priority = thread->nominal_priority; + } + + if (new_priority == current_priority) + return; + + Core::System::GetInstance().Scheduler().SetThreadPriority(this, new_priority); + + current_priority = new_priority; + + // Recursively update the priority of the thread that depends on the priority of this one. + if (lock_owner) + lock_owner->UpdatePriority(); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// /** diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 0e0eae28d6..e0a3c09345 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -109,6 +109,15 @@ public: */ void BoostPriority(u32 priority); + /// Adds a thread to the list of threads that are waiting for a lock held by this thread. + void AddMutexWaiter(SharedPtr thread); + + /// Removes a thread from the list of threads that are waiting for a lock held by this thread. + void RemoveMutexWaiter(SharedPtr thread); + + /// Recalculates the current priority taking into account priority inheritance. + void UpdatePriority(); + /** * Gets the thread's thread ID * @return The thread's ID @@ -205,6 +214,12 @@ public: // passed to WaitSynchronization1/N. std::vector> wait_objects; + /// List of threads that are waiting for a mutex that is held by this thread. + std::vector> wait_mutex_threads; + + /// Thread that owns the lock that this thread is waiting for. + SharedPtr lock_owner; + // If waiting on a ConditionVariable, this is the ConditionVariable address VAddr condvar_wait_address; VAddr mutex_wait_address; ///< If waiting on a Mutex, this is the mutex address From 9531a2928369bcc094c28b77408811d47c46c7f2 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 21 Apr 2018 19:19:33 -0500 Subject: [PATCH 13/74] GPU: Support multiple enabled vertex arrays. The vertex arrays will be copied to the stream buffer one after the other, and the attributes will be set using the ARB_vertex_attrib_binding extension. yuzu now thus requires OpenGL 4.3 or the ARB_vertex_attrib_binding extension. --- src/video_core/engines/maxwell_3d.h | 5 + .../renderer_opengl/gl_rasterizer.cpp | 121 ++++++++++++------ .../renderer_opengl/gl_rasterizer.h | 6 +- 3 files changed, 89 insertions(+), 43 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index d4fcedace5..6095047958 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -500,6 +500,11 @@ public: return static_cast((static_cast(start_high) << 32) | start_low); } + + bool IsEnabled() const { + return enable != 0 && StartAddress() != 0; + } + } vertex_array[NumVertexArrays]; Blend blend; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2d4a0d6db9..82001e7b41 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -127,7 +127,8 @@ RasterizerOpenGL::~RasterizerOpenGL() { } } -void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { +std::pair RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, + GLintptr buffer_offset) { MICROPROFILE_SCOPE(OpenGL_VAO); const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; @@ -136,43 +137,59 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { state.draw.vertex_buffer = stream_buffer->GetHandle(); state.Apply(); - // TODO(bunnei): Add support for 1+ vertex arrays - const auto& vertex_array{regs.vertex_array[0]}; - const auto& vertex_array_limit{regs.vertex_array_limit[0]}; - ASSERT_MSG(vertex_array.enable, "vertex array 0 is disabled?"); - ASSERT_MSG(!vertex_array.divisor, "vertex array 0 divisor is unimplemented!"); - for (unsigned index = 1; index < Maxwell::NumVertexArrays; ++index) { - ASSERT_MSG(!regs.vertex_array[index].enable, "vertex array %d is unimplemented!", index); + // Upload all guest vertex arrays sequentially to our buffer + for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { + const auto& vertex_array = regs.vertex_array[index]; + if (!vertex_array.IsEnabled()) + continue; + + const Tegra::GPUVAddr start = vertex_array.StartAddress(); + const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); + + ASSERT(end > start); + u64 size = end - start + 1; + + // Copy vertex array data + const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(start)}; + res_cache.FlushRegion(data_addr, size, nullptr); + Memory::ReadBlock(data_addr, array_ptr, size); + + // Bind the vertex array to the buffer at the current offset. + glBindVertexBuffer(index, stream_buffer->GetHandle(), buffer_offset, vertex_array.stride); + + ASSERT_MSG(vertex_array.divisor == 0, "Vertex buffer divisor unimplemented"); + + array_ptr += size; + buffer_offset += size; } // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. // Enables the first 16 vertex attributes always, as we don't know which ones are actually used - // until shader time. Note, Tegra technically supports 32, but we're cappinig this to 16 for now + // until shader time. Note, Tegra technically supports 32, but we're capping this to 16 for now // to avoid OpenGL errors. + // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't + // assume every shader uses them all. for (unsigned index = 0; index < 16; ++index) { auto& attrib = regs.vertex_attrib_format[index]; NGLOG_DEBUG(HW_GPU, "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}", index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(), attrib.offset.Value(), attrib.IsNormalized()); - glVertexAttribPointer(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), - attrib.IsNormalized() ? GL_TRUE : GL_FALSE, vertex_array.stride, - reinterpret_cast(buffer_offset + attrib.offset)); + auto& buffer = regs.vertex_array[attrib.buffer]; + ASSERT(buffer.IsEnabled()); + glEnableVertexAttribArray(index); + glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), + attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); + glVertexAttribBinding(index, attrib.buffer); + hw_vao_enabled_attributes[index] = true; } - // Copy vertex array data - const u64 data_size{vertex_array_limit.LimitAddress() - vertex_array.StartAddress() + 1}; - const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(vertex_array.StartAddress())}; - res_cache.FlushRegion(data_addr, data_size, nullptr); - Memory::ReadBlock(data_addr, array_ptr, data_size); - - array_ptr += data_size; - buffer_offset += data_size; + return {array_ptr, buffer_offset}; } -void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size_t ptr_pos) { +void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { // Helper function for uploading uniform data const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) { if (has_ARB_direct_state_access) { @@ -190,8 +207,6 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size u32 current_constbuffer_bindpoint = 0; for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) { - ptr_pos += sizeof(GLShader::MaxwellUniformData); - auto& shader_config = gpu.regs.shader_config[index]; const Maxwell::ShaderProgram program{static_cast(index)}; @@ -205,13 +220,16 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size } // Upload uniform data as one UBO per stage - const GLintptr ubo_offset = buffer_offset + static_cast(ptr_pos); + const GLintptr ubo_offset = buffer_offset; copy_buffer(uniform_buffers[stage].handle, ubo_offset, sizeof(GLShader::MaxwellUniformData)); GLShader::MaxwellUniformData* ub_ptr = - reinterpret_cast(&buffer_ptr[ptr_pos]); + reinterpret_cast(buffer_ptr); ub_ptr->SetFromRegs(gpu.state.shader_stages[stage]); + buffer_ptr += sizeof(GLShader::MaxwellUniformData); + buffer_offset += sizeof(GLShader::MaxwellUniformData); + // Fetch program code from memory GLShader::ProgramCode program_code; const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset}; @@ -252,6 +270,24 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size shader_program_manager->UseTrivialGeometryShader(); } +size_t RasterizerOpenGL::CalculateVertexArraysSize() const { + const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + + size_t size = 0; + for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { + if (!regs.vertex_array[index].IsEnabled()) + continue; + + const Tegra::GPUVAddr start = regs.vertex_array[index].StartAddress(); + const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); + + ASSERT(end > start); + size += end - start + 1; + } + + return size; +} + bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays; DrawArrays(); @@ -329,44 +365,49 @@ void RasterizerOpenGL::DrawArrays() { const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; const unsigned vertex_num{is_indexed ? regs.index_array.count : regs.vertex_buffer.count}; - // TODO(bunnei): Add support for 1+ vertex arrays - vs_input_size = vertex_num * regs.vertex_array[0].stride; - state.draw.vertex_buffer = stream_buffer->GetHandle(); state.Apply(); - size_t buffer_size = static_cast(vs_input_size); + size_t buffer_size = CalculateVertexArraysSize(); + if (is_indexed) { - buffer_size = Common::AlignUp(buffer_size, 4) + index_buffer_size; + buffer_size = Common::AlignUp(buffer_size, 4) + index_buffer_size; } // Uniform space for the 5 shader stages - buffer_size += sizeof(GLShader::MaxwellUniformData) * Maxwell::MaxShaderStage; + buffer_size = Common::AlignUp(buffer_size, 4) + + sizeof(GLShader::MaxwellUniformData) * Maxwell::MaxShaderStage; - size_t ptr_pos = 0; u8* buffer_ptr; GLintptr buffer_offset; std::tie(buffer_ptr, buffer_offset) = stream_buffer->Map(static_cast(buffer_size), 4); - SetupVertexArray(buffer_ptr, buffer_offset); - ptr_pos += vs_input_size; + u8* offseted_buffer; + std::tie(offseted_buffer, buffer_offset) = SetupVertexArrays(buffer_ptr, buffer_offset); + + offseted_buffer = + reinterpret_cast(Common::AlignUp(reinterpret_cast(offseted_buffer), 4)); + buffer_offset = Common::AlignUp(buffer_offset, 4); // If indexed mode, copy the index buffer GLintptr index_buffer_offset = 0; if (is_indexed) { - ptr_pos = Common::AlignUp(ptr_pos, 4); - const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; const VAddr index_data_addr{ memory_manager->PhysicalToVirtualAddress(regs.index_array.StartAddress())}; - Memory::ReadBlock(index_data_addr, &buffer_ptr[ptr_pos], index_buffer_size); + Memory::ReadBlock(index_data_addr, offseted_buffer, index_buffer_size); - index_buffer_offset = buffer_offset + static_cast(ptr_pos); - ptr_pos += index_buffer_size; + index_buffer_offset = buffer_offset; + offseted_buffer += index_buffer_size; + buffer_offset += index_buffer_size; } - SetupShaders(buffer_ptr, buffer_offset, ptr_pos); + offseted_buffer = + reinterpret_cast(Common::AlignUp(reinterpret_cast(offseted_buffer), 4)); + buffer_offset = Common::AlignUp(buffer_offset, 4); + + SetupShaders(offseted_buffer, buffer_offset); stream_buffer->Unmap(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 03e02b52af..544714b953 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -148,13 +148,13 @@ private: static constexpr size_t STREAM_BUFFER_SIZE = 4 * 1024 * 1024; std::unique_ptr stream_buffer; - GLsizeiptr vs_input_size; + size_t CalculateVertexArraysSize() const; - void SetupVertexArray(u8* array_ptr, GLintptr buffer_offset); + std::pair SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset); std::array uniform_buffers; - void SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size_t ptr_pos); + void SetupShaders(u8* buffer_ptr, GLintptr buffer_offset); enum class AccelDraw { Disabled, Arrays, Indexed }; AccelDraw accelerate_draw; From f20895358525f3a8abaefe3a5c2ebe7d30eadc78 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 17:06:57 -0500 Subject: [PATCH 14/74] GPU: Added asserts to our code for handling the QUERY_GET GPU command. This is based on research from nouveau. Many things are currently unknown and will require hwtests in the future. This commit also stubs QueryMode::Write2 to do the same as Write. Nouveau code treats them interchangeably, it is currently unknown what the difference is. --- src/video_core/engines/maxwell_3d.cpp | 27 +++++++++++++++++++++++++- src/video_core/engines/maxwell_3d.h | 28 ++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2a3ff234ab..35773a6956 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -147,11 +147,36 @@ void Maxwell3D::ProcessQueryGet() { // VAddr before writing. VAddr address = memory_manager.PhysicalToVirtualAddress(sequence_address); + // TODO(Subv): Support the other query units. + ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, + "Units other than CROP are unimplemented"); + ASSERT_MSG(regs.query.query_get.short_query, + "Writing the entire query result structure is unimplemented"); + + u32 value = Memory::Read32(address); + u32 result = 0; + + // TODO(Subv): Support the other query variables + switch (regs.query.query_get.select) { + case Regs::QuerySelect::Zero: + result = 0; + break; + default: + UNIMPLEMENTED_MSG("Unimplemented query select type %u", + static_cast(regs.query.query_get.select.Value())); + } + + // TODO(Subv): Research and implement how query sync conditions work. + switch (regs.query.query_get.mode) { - case Regs::QueryMode::Write: { + case Regs::QueryMode::Write: + case Regs::QueryMode::Write2: { // Write the current query sequence to the sequence address. u32 sequence = regs.query.query_sequence; Memory::Write32(address, sequence); + + // TODO(Subv): Write the proper query response structure to the address when not using short + // mode. break; } default: diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index d4fcedace5..5ee581acfb 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -46,6 +46,29 @@ public: enum class QueryMode : u32 { Write = 0, Sync = 1, + // TODO(Subv): It is currently unknown what the difference between method 2 and method 0 + // is. + Write2 = 2, + }; + + enum class QueryUnit : u32 { + VFetch = 1, + VP = 2, + Rast = 4, + StrmOut = 5, + GP = 6, + ZCull = 7, + Prop = 10, + Crop = 15, + }; + + enum class QuerySelect : u32 { + Zero = 0, + }; + + enum class QuerySyncCondition : u32 { + NotEqual = 0, + GreaterThan = 1, }; enum class ShaderProgram : u32 { @@ -476,7 +499,10 @@ public: u32 raw; BitField<0, 2, QueryMode> mode; BitField<4, 1, u32> fence; - BitField<12, 4, u32> unit; + BitField<12, 4, QueryUnit> unit; + BitField<16, 1, QuerySyncCondition> sync_cond; + BitField<23, 5, QuerySelect> select; + BitField<28, 1, u32> short_query; } query_get; GPUVAddr QueryAddress() const { From a0179e5ca5bc54491f03ff60d2f971197eb03e88 Mon Sep 17 00:00:00 2001 From: mailwl Date: Tue, 24 Apr 2018 10:56:05 +0300 Subject: [PATCH 15/74] Service/FS: implement IFileSystem::RenameFile --- src/core/file_sys/disk_filesystem.cpp | 12 ++++++++--- src/core/file_sys/disk_filesystem.h | 2 +- src/core/file_sys/filesystem.h | 3 ++- src/core/file_sys/romfs_filesystem.cpp | 3 ++- src/core/file_sys/romfs_filesystem.h | 2 +- src/core/hle/service/filesystem/fsp_srv.cpp | 22 ++++++++++++++++++++- 6 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp index ca13238736..4d00249fa8 100644 --- a/src/core/file_sys/disk_filesystem.cpp +++ b/src/core/file_sys/disk_filesystem.cpp @@ -67,10 +67,16 @@ ResultCode Disk_FileSystem::DeleteFile(const std::string& path) const { return RESULT_SUCCESS; } -ResultCode Disk_FileSystem::RenameFile(const Path& src_path, const Path& dest_path) const { - LOG_WARNING(Service_FS, "(STUBBED) called"); +ResultCode Disk_FileSystem::RenameFile(const std::string& src_path, + const std::string& dest_path) const { + const std::string full_src_path = base_directory + src_path; + const std::string full_dest_path = base_directory + dest_path; + + if (!FileUtil::Exists(full_src_path)) { + return ERROR_PATH_NOT_FOUND; + } // TODO(wwylele): Use correct error code - return ResultCode(-1); + return FileUtil::Rename(full_src_path, full_dest_path) ? RESULT_SUCCESS : ResultCode(-1); } ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const { diff --git a/src/core/file_sys/disk_filesystem.h b/src/core/file_sys/disk_filesystem.h index 8f9e1145a9..591e39fdac 100644 --- a/src/core/file_sys/disk_filesystem.h +++ b/src/core/file_sys/disk_filesystem.h @@ -26,7 +26,7 @@ public: ResultVal> OpenFile(const std::string& path, Mode mode) const override; ResultCode DeleteFile(const std::string& path) const override; - ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override; + ResultCode RenameFile(const std::string& src_path, const std::string& dest_path) const override; ResultCode DeleteDirectory(const Path& path) const override; ResultCode DeleteDirectoryRecursively(const Path& path) const override; ResultCode CreateFile(const std::string& path, u64 size) const override; diff --git a/src/core/file_sys/filesystem.h b/src/core/file_sys/filesystem.h index beefcfdb2c..295a3133e7 100644 --- a/src/core/file_sys/filesystem.h +++ b/src/core/file_sys/filesystem.h @@ -126,7 +126,8 @@ public: * @param dest_path Destination path relative to the archive * @return Result of the operation */ - virtual ResultCode RenameFile(const Path& src_path, const Path& dest_path) const = 0; + virtual ResultCode RenameFile(const std::string& src_path, + const std::string& dest_path) const = 0; /** * Rename a Directory specified by its path diff --git a/src/core/file_sys/romfs_filesystem.cpp b/src/core/file_sys/romfs_filesystem.cpp index 3d77e2d5fb..b9982e6fae 100644 --- a/src/core/file_sys/romfs_filesystem.cpp +++ b/src/core/file_sys/romfs_filesystem.cpp @@ -27,7 +27,8 @@ ResultCode RomFS_FileSystem::DeleteFile(const std::string& path) const { return ResultCode(-1); } -ResultCode RomFS_FileSystem::RenameFile(const Path& src_path, const Path& dest_path) const { +ResultCode RomFS_FileSystem::RenameFile(const std::string& src_path, + const std::string& dest_path) const { LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive (%s).", GetName().c_str()); // TODO(wwylele): Use correct error code diff --git a/src/core/file_sys/romfs_filesystem.h b/src/core/file_sys/romfs_filesystem.h index 1b5cac4098..ba9d85823b 100644 --- a/src/core/file_sys/romfs_filesystem.h +++ b/src/core/file_sys/romfs_filesystem.h @@ -32,7 +32,7 @@ public: ResultVal> OpenFile(const std::string& path, Mode mode) const override; ResultCode DeleteFile(const std::string& path) const override; - ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override; + ResultCode RenameFile(const std::string& src_path, const std::string& dest_path) const override; ResultCode DeleteDirectory(const Path& path) const override; ResultCode DeleteDirectoryRecursively(const Path& path) const override; ResultCode CreateFile(const std::string& path, u64 size) const override; diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 2f476c8697..02e270f266 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -239,7 +239,7 @@ public: {2, &IFileSystem::CreateDirectory, "CreateDirectory"}, {3, nullptr, "DeleteDirectory"}, {4, nullptr, "DeleteDirectoryRecursively"}, - {5, nullptr, "RenameFile"}, + {5, &IFileSystem::RenameFile, "RenameFile"}, {6, nullptr, "RenameDirectory"}, {7, &IFileSystem::GetEntryType, "GetEntryType"}, {8, &IFileSystem::OpenFile, "OpenFile"}, @@ -300,6 +300,26 @@ public: rb.Push(backend->CreateDirectory(name)); } + void RenameFile(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + std::vector buffer; + buffer.resize(ctx.BufferDescriptorX()[0].Size()); + Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address(), buffer.data(), buffer.size()); + auto end = std::find(buffer.begin(), buffer.end(), '\0'); + std::string src_name(buffer.begin(), end); + + buffer.resize(ctx.BufferDescriptorX()[1].Size()); + Memory::ReadBlock(ctx.BufferDescriptorX()[1].Address(), buffer.data(), buffer.size()); + end = std::find(buffer.begin(), buffer.end(), '\0'); + std::string dst_name(buffer.begin(), end); + + LOG_DEBUG(Service_FS, "called file '%s' to file '%s'", src_name.c_str(), dst_name.c_str()); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(backend->RenameFile(src_name, dst_name)); + } + void OpenFile(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; From f85d880ac6990d3ccffd267ac75a81c89ec80b71 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:04:22 -0400 Subject: [PATCH 16/74] acc: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/acc/acc.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 6bafb2dce5..f2fffa7606 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -47,7 +47,7 @@ public: private: void GetBase(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); ProfileBase profile_base{}; IPC::ResponseBuilder rb{ctx, 16}; rb.Push(RESULT_SUCCESS); @@ -72,14 +72,14 @@ public: private: void CheckAvailability(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(true); // TODO: Check when this is supposed to return true and when not } void GetAccountId(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(0x12345678ABCDEF); @@ -87,14 +87,14 @@ private: }; void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(true); // TODO: Check when this is supposed to return true and when not } void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); constexpr std::array user_ids{DEFAULT_USER_ID}; ctx.WriteBuffer(user_ids.data(), user_ids.size()); IPC::ResponseBuilder rb{ctx, 2}; @@ -102,7 +102,7 @@ void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { } void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); constexpr std::array user_ids{DEFAULT_USER_ID}; ctx.WriteBuffer(user_ids.data(), user_ids.size()); IPC::ResponseBuilder rb{ctx, 2}; @@ -113,11 +113,11 @@ void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_ACC, "called"); + NGLOG_DEBUG(Service_ACC, "called"); } void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -126,11 +126,11 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_ACC, "called"); + NGLOG_DEBUG(Service_ACC, "called"); } void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 6}; rb.Push(RESULT_SUCCESS); rb.PushRaw(DEFAULT_USER_ID); From 5483c08b44c3f63155fa269bcbb7b5229e94719c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:12:53 -0400 Subject: [PATCH 17/74] am: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/am/am.cpp | 64 +++++++++++++-------------- src/core/hle/service/am/applet_ae.cpp | 18 ++++---- src/core/hle/service/am/applet_oe.cpp | 18 ++++---- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index f41a59afeb..19fadcb8e6 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -28,14 +28,14 @@ IWindowController::IWindowController() : ServiceFramework("IWindowController") { } void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(0); } void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -54,20 +54,20 @@ IAudioController::IAudioController() : ServiceFramework("IAudioController") { } void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(volume); } void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(volume); @@ -139,14 +139,14 @@ void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) { @@ -157,14 +157,14 @@ void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestCo IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called flag=%u", static_cast(flag)); + NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag); } void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) { @@ -175,7 +175,7 @@ void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestCont IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called flag=%u", static_cast(flag)); + NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag); } void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) { @@ -188,21 +188,21 @@ void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called enabled=%u", static_cast(enabled)); + NGLOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled); } void ISelfController::LockExit(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { @@ -212,7 +212,7 @@ void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(launchable_event); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) { @@ -225,7 +225,7 @@ void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) rb.Push(RESULT_SUCCESS); rb.Push(layer_id); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") { @@ -269,7 +269,7 @@ void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(event); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { @@ -277,7 +277,7 @@ void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push(15); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { @@ -285,7 +285,7 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push(static_cast(FocusState::InFocus)); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { @@ -294,7 +294,7 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push(static_cast(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld)); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { @@ -304,7 +304,7 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { rb.Push(static_cast(use_docked_mode ? APM::PerformanceMode::Docked : APM::PerformanceMode::Handheld)); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } class ILibraryAppletAccessor final : public ServiceFramework { @@ -344,7 +344,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(state_changed_event); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } Kernel::SharedPtr state_changed_event; @@ -368,7 +368,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } class IStorageAccessor final : public ServiceFramework { @@ -392,7 +392,7 @@ private: rb.Push(RESULT_SUCCESS); rb.Push(static_cast(buffer.size())); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void Read(Kernel::HLERequestContext& ctx) { @@ -410,7 +410,7 @@ private: rb.Push(RESULT_SUCCESS); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } }; @@ -434,7 +434,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(buffer); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } }; @@ -498,14 +498,14 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(buffer); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; u128 uid = rp.PopRaw(); - LOG_WARNING(Service, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]); + NGLOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); IPC::ResponseBuilder rb{ctx, 4}; @@ -533,27 +533,27 @@ void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called, result=0x%08X", result); + NGLOG_WARNING(Service_AM, "(STUBBED) called, result={:#010}", result); } void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(SystemLanguage::English); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) { @@ -561,7 +561,7 @@ void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push(0); // Unknown, seems to be ignored by official processes - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void InstallInterfaces(SM::ServiceManager& service_manager, diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp index 4f0698a8a9..8951980cff 100644 --- a/src/core/hle/service/am/applet_ae.cpp +++ b/src/core/hle/service/am/applet_ae.cpp @@ -33,56 +33,56 @@ private: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetSelfController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(nvflinger); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetWindowController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetAudioController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetDisplayController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetDebugFunctions(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } std::shared_ptr nvflinger; @@ -92,7 +92,7 @@ void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(nvflinger); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } AppletAE::AppletAE(std::shared_ptr nvflinger) diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index 674b4d7535..68388bf5e8 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp @@ -33,56 +33,56 @@ private: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetDisplayController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetDebugFunctions(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetWindowController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetSelfController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(nvflinger); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } std::shared_ptr nvflinger; @@ -92,7 +92,7 @@ void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(nvflinger); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } AppletOE::AppletOE(std::shared_ptr nvflinger) From e74dbfc5729a5daf44cd1057d39ebe45863d33d4 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:14:52 -0400 Subject: [PATCH 18/74] aoc: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/aoc/aoc_u.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 6e7438580c..5b6dfb48f9 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp @@ -27,14 +27,14 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(0); - LOG_WARNING(Service_AOC, "(STUBBED) called"); + NGLOG_WARNING(Service_AOC, "(STUBBED) called"); } void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(0); - LOG_WARNING(Service_AOC, "(STUBBED) called"); + NGLOG_WARNING(Service_AOC, "(STUBBED) called"); } void InstallInterfaces(SM::ServiceManager& service_manager) { From d652e413654d736d85edbed8b6a387ab526c6d2b Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:16:03 -0400 Subject: [PATCH 19/74] apm: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/apm/interface.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index 4e11f3f14a..3a03188ce1 100644 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp @@ -29,8 +29,8 @@ private: IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_APM, "(STUBBED) called mode=%u config=%u", static_cast(mode), - config); + NGLOG_WARNING(Service_APM, "(STUBBED) called mode={} config={}", static_cast(mode), + config); } void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { @@ -42,7 +42,7 @@ private: rb.Push(RESULT_SUCCESS); rb.Push(0); // Performance configuration - LOG_WARNING(Service_APM, "(STUBBED) called mode=%u", static_cast(mode)); + NGLOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast(mode)); } }; From 8d32bf9a96bf8eea855d3ad1614e3f7f4f27ff8d Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:18:09 -0400 Subject: [PATCH 20/74] audio: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/audio/audout_u.cpp | 16 +++++++-------- src/core/hle/service/audio/audren_u.cpp | 26 ++++++++++++------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 2d7f8cb04d..6297dc450a 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -60,14 +60,14 @@ public: private: void GetAudioOutState(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); + NGLOG_DEBUG(Service_Audio, "called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(static_cast(audio_out_state)); } void StartAudioOut(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); // Start audio audio_out_state = AudioState::Started; @@ -77,7 +77,7 @@ private: } void StopAudioOut(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); // Stop audio audio_out_state = AudioState::Stopped; @@ -89,7 +89,7 @@ private: } void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); @@ -97,7 +97,7 @@ private: } void AppendAudioOutBuffer(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::RequestParser rp{ctx}; const u64 key{rp.Pop()}; @@ -108,7 +108,7 @@ private: } void GetReleasedAudioOutBuffer(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); // TODO(st4rk): This is how libtransistor currently implements the // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address @@ -164,7 +164,7 @@ private: }; void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::RequestParser rp{ctx}; const std::string audio_interface = "AudioInterface"; @@ -180,7 +180,7 @@ void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { } void AudOutU::OpenAudioOut(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); if (!audio_out_interface) { audio_out_interface = std::make_shared(); diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index d9245cb192..72810b436f 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -56,7 +56,7 @@ private: } void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "%s", ctx.Description().c_str()); + NGLOG_DEBUG(Service_Audio, "{}", ctx.Description()); AudioRendererResponseData response_data{}; response_data.section_0_size = @@ -79,7 +79,7 @@ private: rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); } void StartAudioRenderer(Kernel::HLERequestContext& ctx) { @@ -87,7 +87,7 @@ private: rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); } void StopAudioRenderer(Kernel::HLERequestContext& ctx) { @@ -95,7 +95,7 @@ private: rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); } void QuerySystemEvent(Kernel::HLERequestContext& ctx) { @@ -105,7 +105,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(system_event); - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); } struct AudioRendererStateEntry { @@ -176,7 +176,7 @@ public: private: void ListAudioDeviceName(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::RequestParser rp{ctx}; const std::string audio_interface = "AudioInterface"; @@ -188,7 +188,7 @@ private: } void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::RequestParser rp{ctx}; f32 volume = static_cast(rp.Pop()); @@ -201,7 +201,7 @@ private: } void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::RequestParser rp{ctx}; const std::string audio_interface = "AudioDevice"; @@ -213,7 +213,7 @@ private: } void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); buffer_event->Signal(); @@ -223,7 +223,7 @@ private: } void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(1); @@ -250,7 +250,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_Audio, "called"); + NGLOG_DEBUG(Service_Audio, "called"); } void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { @@ -259,7 +259,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push(0x400); - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); } void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { @@ -268,7 +268,7 @@ void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_Audio, "called"); + NGLOG_DEBUG(Service_Audio, "called"); } } // namespace Service::Audio From c6a740d7c2838887aab9e3aff56e5420a2d558e1 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:18:58 -0400 Subject: [PATCH 21/74] fatal: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/fatal/fatal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 41d58f9995..d7ad0600a6 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp @@ -16,13 +16,13 @@ Module::Interface::Interface(std::shared_ptr module, const char* name) void Module::Interface::FatalSimple(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx); u32 error_code = rp.Pop(); - LOG_WARNING(Service_Fatal, "(STUBBED) called, error_code=0x%X", error_code); + NGLOG_WARNING(Service_Fatal, "(STUBBED) called, error_code={:#X}", error_code); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void Module::Interface::TransitionToFatalError(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Fatal, "(STUBBED) called"); + NGLOG_WARNING(Service_Fatal, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } From d1b23b2b51bcfd0d006e1e6a62065074e3eed2ea Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 11:12:11 -0400 Subject: [PATCH 22/74] renderer_opengl: Silence a -Wdangling-else warning in DrawScreenTriangles() --- src/video_core/renderer_opengl/renderer_opengl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index ab0acb20ad..baff2c7af9 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -295,7 +295,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, const auto& texcoords = screen_info.display_texcoords; auto left = texcoords.left; auto right = texcoords.right; - if (framebuffer_transform_flags != Tegra::FramebufferConfig::TransformFlags::Unset) + if (framebuffer_transform_flags != Tegra::FramebufferConfig::TransformFlags::Unset) { if (framebuffer_transform_flags == Tegra::FramebufferConfig::TransformFlags::FlipV) { // Flip the framebuffer vertically left = texcoords.right; @@ -306,6 +306,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, framebuffer_transform_flags); UNIMPLEMENTED(); } + } std::array vertices = {{ ScreenRectVertex(x, y, texcoords.top, left), From b5b613ea29d7d6d2ea2c11396c6464078082c62d Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:20:50 -0400 Subject: [PATCH 23/74] filesystem: Move logging macros over to new fmt-compatible ones --- .../hle/service/filesystem/filesystem.cpp | 8 +-- src/core/hle/service/filesystem/fsp_srv.cpp | 51 +++++++++---------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 9e504992f4..c2951c5605 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -25,14 +25,14 @@ ResultCode RegisterFileSystem(std::unique_ptr&& fact ASSERT_MSG(inserted, "Tried to register more than one system with same id code"); auto& filesystem = result.first->second; - LOG_DEBUG(Service_FS, "Registered file system %s with id code 0x%08X", - filesystem->GetName().c_str(), static_cast(type)); + NGLOG_DEBUG(Service_FS, "Registered file system {} with id code {:#010X}", + filesystem->GetName(), static_cast(type)); return RESULT_SUCCESS; } ResultVal> OpenFileSystem(Type type, FileSys::Path& path) { - LOG_TRACE(Service_FS, "Opening FileSystem with type=%d", type); + NGLOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast(type)); auto itr = filesystem_map.find(type); if (itr == filesystem_map.end()) { @@ -44,7 +44,7 @@ ResultVal> OpenFileSystem(Type type, } ResultCode FormatFileSystem(Type type) { - LOG_TRACE(Service_FS, "Formatting FileSystem with type=%d", type); + NGLOG_TRACE(Service_FS, "Formatting FileSystem with type={}", static_cast(type)); auto itr = filesystem_map.find(type); if (itr == filesystem_map.end()) { diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 02e270f266..ed9f2ef723 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -35,7 +35,7 @@ private: const s64 offset = rp.Pop(); const s64 length = rp.Pop(); - LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length); + NGLOG_DEBUG(Service_FS, "called, offset={:#X}, length={}", offset, length); // Error checking if (length < 0) { @@ -87,7 +87,7 @@ private: const s64 offset = rp.Pop(); const s64 length = rp.Pop(); - LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length); + NGLOG_DEBUG(Service_FS, "called, offset={:#X}, length={}", offset, length); // Error checking if (length < 0) { @@ -124,7 +124,7 @@ private: const s64 offset = rp.Pop(); const s64 length = rp.Pop(); - LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length); + NGLOG_DEBUG(Service_FS, "called, offset={:#X}, length={}", offset, length); // Error checking if (length < 0) { @@ -152,7 +152,7 @@ private: } void Flush(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); + NGLOG_DEBUG(Service_FS, "called"); backend->Flush(); IPC::ResponseBuilder rb{ctx, 2}; @@ -163,7 +163,7 @@ private: IPC::RequestParser rp{ctx}; const u64 size = rp.Pop(); backend->SetSize(size); - LOG_DEBUG(Service_FS, "called, size=%" PRIu64, size); + NGLOG_DEBUG(Service_FS, "called, size={}", size); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -171,7 +171,7 @@ private: void GetSize(Kernel::HLERequestContext& ctx) { const u64 size = backend->GetSize(); - LOG_DEBUG(Service_FS, "called, size=%" PRIu64, size); + NGLOG_DEBUG(Service_FS, "called, size={}", size); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); @@ -197,7 +197,7 @@ private: IPC::RequestParser rp{ctx}; const u64 unk = rp.Pop(); - LOG_DEBUG(Service_FS, "called, unk=0x%llx", unk); + NGLOG_DEBUG(Service_FS, "called, unk={:#X}", unk); // Calculate how many entries we can fit in the output buffer u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry); @@ -219,7 +219,7 @@ private: } void GetEntryCount(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); + NGLOG_DEBUG(Service_FS, "called"); u64 count = backend->GetEntryCount(); @@ -265,8 +265,7 @@ public: u64 mode = rp.Pop(); u32 size = rp.Pop(); - LOG_DEBUG(Service_FS, "called file %s mode 0x%" PRIX64 " size 0x%08X", name.c_str(), mode, - size); + NGLOG_DEBUG(Service_FS, "called file {} mode {:#X} size {:#010X}", name, mode, size); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(backend->CreateFile(name, size)); @@ -280,7 +279,7 @@ public: std::string name(file_buffer.begin(), end); - LOG_DEBUG(Service_FS, "called file %s", name.c_str()); + NGLOG_DEBUG(Service_FS, "called file {}", name); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(backend->DeleteFile(name)); @@ -294,7 +293,7 @@ public: std::string name(file_buffer.begin(), end); - LOG_DEBUG(Service_FS, "called directory %s", name.c_str()); + NGLOG_DEBUG(Service_FS, "called directory {}", name); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(backend->CreateDirectory(name)); @@ -314,7 +313,7 @@ public: end = std::find(buffer.begin(), buffer.end(), '\0'); std::string dst_name(buffer.begin(), end); - LOG_DEBUG(Service_FS, "called file '%s' to file '%s'", src_name.c_str(), dst_name.c_str()); + NGLOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(backend->RenameFile(src_name, dst_name)); @@ -330,7 +329,7 @@ public: auto mode = static_cast(rp.Pop()); - LOG_DEBUG(Service_FS, "called file %s mode %u", name.c_str(), static_cast(mode)); + NGLOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast(mode)); auto result = backend->OpenFile(name, mode); if (result.Failed()) { @@ -357,7 +356,7 @@ public: // TODO(Subv): Implement this filter. u32 filter_flags = rp.Pop(); - LOG_DEBUG(Service_FS, "called directory %s filter %u", name.c_str(), filter_flags); + NGLOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags); auto result = backend->OpenDirectory(name); if (result.Failed()) { @@ -381,7 +380,7 @@ public: std::string name(file_buffer.begin(), end); - LOG_DEBUG(Service_FS, "called file %s", name.c_str()); + NGLOG_DEBUG(Service_FS, "called file {}", name); auto result = backend->GetEntryType(name); if (result.Failed()) { @@ -396,7 +395,7 @@ public: } void Commit(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -512,14 +511,14 @@ void FSP_SRV::TryLoadRomFS() { } void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); + NGLOG_DEBUG(Service_FS, "called"); FileSys::Path unused; auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap(); @@ -536,14 +535,14 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) { auto save_create_struct = rp.PopRaw>(); u128 uid = rp.PopRaw(); - LOG_WARNING(Service_FS, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]); + NGLOG_WARNING(Service_FS, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); FileSys::Path unused; auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap(); @@ -554,7 +553,7 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { } void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); @@ -562,12 +561,12 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { } void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); + NGLOG_DEBUG(Service_FS, "called"); TryLoadRomFS(); if (!romfs) { // TODO (bunnei): Find the right error code to use here - LOG_CRITICAL(Service_FS, "no file system interface available!"); + NGLOG_CRITICAL(Service_FS, "no file system interface available!"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultCode(-1)); return; @@ -576,7 +575,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { // Attempt to open a StorageBackend interface to the RomFS auto storage = romfs->OpenFile({}, {}); if (storage.Failed()) { - LOG_CRITICAL(Service_FS, "no storage interface available!"); + NGLOG_CRITICAL(Service_FS, "no storage interface available!"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(storage.Code()); return; @@ -588,7 +587,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { } void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess"); + NGLOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess"); OpenDataStorageByCurrentProcess(ctx); } From 8fc4003dabab37eb004aa23f46b618330ef837bc Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:27:20 -0400 Subject: [PATCH 24/74] friend: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/friend/friend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index c98a46e053..94d9fbf253 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -13,7 +13,7 @@ namespace Service::Friend { void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Friend, "(STUBBED) called"); + NGLOG_WARNING(Service_Friend, "(STUBBED) called"); } Module::Interface::Interface(std::shared_ptr module, const char* name) From 9cd7485cd738cd2936dc31a34fda76860ff9d190 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:28:49 -0400 Subject: [PATCH 25/74] hid: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/hid/hid.cpp | 50 ++++++++++++++++---------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index aad5e688bd..736180b633 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -53,7 +53,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(shared_mem); - LOG_DEBUG(Service_HID, "called"); + NGLOG_DEBUG(Service_HID, "called"); } void LoadInputDevices() { @@ -184,7 +184,7 @@ private: void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } }; @@ -286,144 +286,144 @@ private: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(applet_resource); - LOG_DEBUG(Service_HID, "called"); + NGLOG_DEBUG(Service_HID, "called"); } void ActivateDebugPad(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void ActivateTouchScreen(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void ActivateMouse(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void ActivateKeyboard(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void StartSixAxisSensor(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(0); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void ActivateNpad(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(event); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(joy_hold_type); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SendVibrationValue(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void GetActualVibrationValue(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(0); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_HID, "called"); + NGLOG_DEBUG(Service_HID, "called"); } void SendVibrationValues(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } }; From dabfd90dfe0e8d38e1a2016b79a49023756ec135 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:29:21 -0400 Subject: [PATCH 26/74] lm: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/lm/lm.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index b87172dffc..46194643e8 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -141,19 +141,19 @@ private: if (header.IsTailLog()) { switch (header.severity) { case MessageHeader::Severity::Trace: - LOG_TRACE(Debug_Emulated, "%s", log_stream.str().c_str()); + NGLOG_TRACE(Debug_Emulated, "{}", log_stream.str()); break; case MessageHeader::Severity::Info: - LOG_INFO(Debug_Emulated, "%s", log_stream.str().c_str()); + NGLOG_INFO(Debug_Emulated, "{}", log_stream.str()); break; case MessageHeader::Severity::Warning: - LOG_WARNING(Debug_Emulated, "%s", log_stream.str().c_str()); + NGLOG_WARNING(Debug_Emulated, "{}", log_stream.str()); break; case MessageHeader::Severity::Error: - LOG_ERROR(Debug_Emulated, "%s", log_stream.str().c_str()); + NGLOG_ERROR(Debug_Emulated, "{}", log_stream.str()); break; case MessageHeader::Severity::Critical: - LOG_CRITICAL(Debug_Emulated, "%s", log_stream.str().c_str()); + NGLOG_CRITICAL(Debug_Emulated, "{}", log_stream.str()); break; } } @@ -178,7 +178,7 @@ void LM::Initialize(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_LM, "called"); + NGLOG_DEBUG(Service_LM, "called"); } LM::LM() : ServiceFramework("lm") { From 28b92db7fd5301b7968188b82349129550ec660c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:29:39 -0400 Subject: [PATCH 27/74] nfp: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/nfp/nfp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index 91e5f527aa..6627aaddcf 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp @@ -13,7 +13,7 @@ Module::Interface::Interface(std::shared_ptr module, const char* name) : ServiceFramework(name), module(std::move(module)) {} void Module::Interface::Unknown(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NFP, "(STUBBED) called"); + NGLOG_WARNING(Service_NFP, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } From 47054327c2760faca023c3169e0d6ef8f98b737e Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:30:27 -0400 Subject: [PATCH 28/74] nifm: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/nifm/nifm.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index df1e7f8fea..eee92cfcde 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -62,24 +62,24 @@ public: private: void GetRequestState(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(0); } void GetResult(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 2}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(event1, event2); } void Cancel(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -105,7 +105,7 @@ public: private: void GetClientId(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(0); @@ -116,7 +116,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_NIFM, "called"); + NGLOG_DEBUG(Service_NIFM, "called"); } void CreateRequest(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -124,10 +124,10 @@ private: rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_NIFM, "called"); + NGLOG_DEBUG(Service_NIFM, "called"); } void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -137,7 +137,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_NIFM, "called"); + NGLOG_DEBUG(Service_NIFM, "called"); } }; @@ -187,14 +187,14 @@ void Module::Interface::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_NIFM, "called"); + NGLOG_DEBUG(Service_NIFM, "called"); } void Module::Interface::CreateGeneralService(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_NIFM, "called"); + NGLOG_DEBUG(Service_NIFM, "called"); } Module::Interface::Interface(std::shared_ptr module, const char* name) From 022fc59dcd5e4baf2ccfd949425b28d835fe20c6 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:31:34 -0400 Subject: [PATCH 29/74] ns: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/ns/pl_u.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index c416ad7203..c2a647e899 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -52,7 +52,7 @@ PL_U::PL_U() : ServiceFramework("pl:u") { ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE); file.ReadBytes(shared_font->data(), shared_font->size()); } else { - LOG_WARNING(Service_NS, "Unable to load shared font: %s", filepath.c_str()); + NGLOG_WARNING(Service_NS, "Unable to load shared font: {}", filepath); } } @@ -60,7 +60,7 @@ void PL_U::RequestLoad(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u32 shared_font_type{rp.Pop()}; - LOG_DEBUG(Service_NS, "called, shared_font_type=%d", shared_font_type); + NGLOG_DEBUG(Service_NS, "called, shared_font_type={}", shared_font_type); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -69,7 +69,7 @@ void PL_U::GetLoadState(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u32 font_id{rp.Pop()}; - LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); + NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(static_cast(LoadState::Done)); @@ -79,7 +79,7 @@ void PL_U::GetSize(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u32 font_id{rp.Pop()}; - LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); + NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(SHARED_FONT_REGIONS[font_id].size); @@ -89,7 +89,7 @@ void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u32 font_id{rp.Pop()}; - LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); + NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(SHARED_FONT_REGIONS[font_id].offset); @@ -110,7 +110,7 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE, "PL_U:shared_font_mem"); - LOG_DEBUG(Service_NS, "called"); + NGLOG_DEBUG(Service_NS, "called"); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(shared_font_mem); From 285d8d8b7d6d22202f87d60f67768be69b7f0bd1 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:33:33 -0400 Subject: [PATCH 30/74] nvdrv: Move logging macros over to new fmt-compatible ones --- .../service/nvdrv/devices/nvdisp_disp0.cpp | 6 +-- .../service/nvdrv/devices/nvhost_as_gpu.cpp | 26 ++++++------- .../hle/service/nvdrv/devices/nvhost_ctrl.cpp | 12 +++--- .../service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 16 ++++---- .../hle/service/nvdrv/devices/nvhost_gpu.cpp | 37 ++++++++++--------- src/core/hle/service/nvdrv/devices/nvmap.cpp | 10 ++--- src/core/hle/service/nvdrv/interface.cpp | 14 +++---- 7 files changed, 61 insertions(+), 60 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index aa6c7e8dc9..103e66d0c3 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -20,9 +20,9 @@ u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector& input, std::vector void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) { VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); - LOG_WARNING(Service, - "Drawing from address %lx offset %08X Width %u Height %u Stride %u Format %u", addr, - offset, width, height, stride, format); + NGLOG_WARNING(Service, + "Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}", + addr, offset, width, height, stride, format); using PixelFormat = Tegra::FramebufferConfig::PixelFormat; const Tegra::FramebufferConfig framebuffer{ diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 8e7ca61235..36d7f837b4 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -12,8 +12,8 @@ namespace Service::Nvidia::Devices { u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& output) { - LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", - command.raw, input.size(), output.size()); + NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", + command.raw, input.size(), output.size()); switch (static_cast(command.raw)) { case IoctlCommand::IocInitalizeExCommand: @@ -38,7 +38,7 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector& input, std::vecto u32 nvhost_as_gpu::InitalizeEx(const std::vector& input, std::vector& output) { IoctlInitalizeEx params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x%x", params.big_page_size); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size={:#X}", params.big_page_size); std::memcpy(output.data(), ¶ms, output.size()); return 0; } @@ -46,8 +46,8 @@ u32 nvhost_as_gpu::InitalizeEx(const std::vector& input, std::vector& ou u32 nvhost_as_gpu::AllocateSpace(const std::vector& input, std::vector& output) { IoctlAllocSpace params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, "called, pages=%x, page_size=%x, flags=%x", params.pages, - params.page_size, params.flags); + NGLOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages, + params.page_size, params.flags); auto& gpu = Core::System::GetInstance().GPU(); const u64 size{static_cast(params.pages) * static_cast(params.page_size)}; @@ -95,11 +95,11 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector& input, std::vector& ou IoctlMapBufferEx params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, - "called, flags=%x, nvmap_handle=%x, buffer_offset=%" PRIu64 ", mapping_size=%" PRIu64 - ", offset=%" PRIu64, - params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size, - params.offset); + NGLOG_DEBUG(Service_NVDRV, + "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" + ", offset={}", + params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size, + params.offset); if (!params.nvmap_handle) { return 0; @@ -133,7 +133,7 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector& input, std::vector& ou u32 nvhost_as_gpu::BindChannel(const std::vector& input, std::vector& output) { IoctlBindChannel params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, "called, fd=%x", params.fd); + NGLOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); channel = params.fd; std::memcpy(output.data(), ¶ms, output.size()); return 0; @@ -142,8 +142,8 @@ u32 nvhost_as_gpu::BindChannel(const std::vector& input, std::vector& ou u32 nvhost_as_gpu::GetVARegions(const std::vector& input, std::vector& output) { IoctlGetVaRegions params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr=%" PRIu64 ", buf_size=%x", - params.buf_addr, params.buf_size); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr={:X}, buf_size={:X}", params.buf_addr, + params.buf_size); params.buf_size = 0x30; params.regions[0].offset = 0x04000000; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 6e1ba1ac7e..46f0b68628 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -9,8 +9,8 @@ namespace Service::Nvidia::Devices { u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector& input, std::vector& output) { - LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", - command.raw, input.size(), output.size()); + NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", + command.raw, input.size(), output.size()); switch (static_cast(command.raw)) { case IoctlCommand::IocGetConfigCommand: @@ -25,8 +25,8 @@ u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector& input, std::vector< u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector& input, std::vector& output) { IocGetConfigParams params{}; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_DEBUG(Service_NVDRV, "called, setting=%s!%s", params.domain_str.data(), - params.param_str.data()); + NGLOG_DEBUG(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), + params.param_str.data()); if (!strcmp(params.domain_str.data(), "nv")) { if (!strcmp(params.param_str.data(), "NV_MEMORY_PROFILER")) { @@ -48,8 +48,8 @@ u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector& input, std::vector& u32 nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector& output) { IocCtrlEventWaitParams params{}; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, syncpt_id=%u threshold=%u timeout=%d", - params.syncpt_id, params.threshold, params.timeout); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, syncpt_id={} threshold={} timeout={}", + params.syncpt_id, params.threshold, params.timeout); // TODO(Subv): Implement actual syncpt waiting. params.value = 0; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index b715723d31..1e457ae6ef 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -10,8 +10,8 @@ namespace Service::Nvidia::Devices { u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& output) { - LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", - command.raw, input.size(), output.size()); + NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", + command.raw, input.size(), output.size()); switch (static_cast(command.raw)) { case IoctlCommand::IocGetCharacteristicsCommand: @@ -30,7 +30,7 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector& input, std::vec } u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector& input, std::vector& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlCharacteristics params{}; std::memcpy(¶ms, input.data(), input.size()); params.gc.arch = 0x120; @@ -77,14 +77,14 @@ u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector& input, std::vecto u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector& input, std::vector& output) { IoctlGpuGetTpcMasksArgs params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, mask=0x%x, mask_buf_addr=0x%" PRIx64, - params.mask_buf_size, params.mask_buf_addr); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, mask={:#X}, mask_buf_addr={:#X}", + params.mask_buf_size, params.mask_buf_addr); std::memcpy(output.data(), ¶ms, sizeof(params)); return 0; } u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector& input, std::vector& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlActiveSlotMask params{}; std::memcpy(¶ms, input.data(), input.size()); params.slot = 0x07; @@ -94,7 +94,7 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector& input, std::vector } u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector& input, std::vector& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlZcullGetCtxSize params{}; std::memcpy(¶ms, input.data(), input.size()); params.size = 0x1; @@ -103,7 +103,7 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector& input, std::vector& input, std::vector& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlNvgpuGpuZcullGetInfoArgs params{}; std::memcpy(¶ms, input.data(), input.size()); params.width_align_pixels = 0x20; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index dab6d0533d..70625211ee 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -12,8 +12,8 @@ namespace Service::Nvidia::Devices { u32 nvhost_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& output) { - LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", - command.raw, input.size(), output.size()); + NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", + command.raw, input.size(), output.size()); switch (static_cast(command.raw)) { case IoctlCommand::IocSetNVMAPfdCommand: @@ -47,14 +47,14 @@ u32 nvhost_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& input, std::vector& output) { IoctlSetNvmapFD params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, "called, fd=%x", params.nvmap_fd); + NGLOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); nvmap_fd = params.nvmap_fd; std::memcpy(output.data(), ¶ms, output.size()); return 0; } u32 nvhost_gpu::SetClientData(const std::vector& input, std::vector& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlClientData params{}; std::memcpy(¶ms, input.data(), input.size()); user_data = params.data; @@ -63,7 +63,7 @@ u32 nvhost_gpu::SetClientData(const std::vector& input, std::vector& out } u32 nvhost_gpu::GetClientData(const std::vector& input, std::vector& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlClientData params{}; std::memcpy(¶ms, input.data(), input.size()); params.data = user_data; @@ -73,8 +73,8 @@ u32 nvhost_gpu::GetClientData(const std::vector& input, std::vector& out u32 nvhost_gpu::ZCullBind(const std::vector& input, std::vector& output) { std::memcpy(&zcull_params, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, "called, gpu_va=%" PRIx64 ", mode=%x", zcull_params.gpu_va, - zcull_params.mode); + NGLOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, + zcull_params.mode); std::memcpy(output.data(), &zcull_params, output.size()); return 0; } @@ -82,15 +82,15 @@ u32 nvhost_gpu::ZCullBind(const std::vector& input, std::vector& output) u32 nvhost_gpu::SetErrorNotifier(const std::vector& input, std::vector& output) { IoctlSetErrorNotifier params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset=%" PRIx64 ", size=%" PRIx64 ", mem=%x", - params.offset, params.size, params.mem); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", + params.offset, params.size, params.mem); std::memcpy(output.data(), ¶ms, output.size()); return 0; } u32 nvhost_gpu::SetChannelPriority(const std::vector& input, std::vector& output) { std::memcpy(&channel_priority, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority=%x", channel_priority); + NGLOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); std::memcpy(output.data(), &channel_priority, output.size()); return 0; } @@ -98,10 +98,11 @@ u32 nvhost_gpu::SetChannelPriority(const std::vector& input, std::vector u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector& input, std::vector& output) { IoctlAllocGpfifoEx2 params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, - "(STUBBED) called, num_entries=%x, flags=%x, unk0=%x, unk1=%x, unk2=%x, unk3=%x", - params.num_entries, params.flags, params.unk0, params.unk1, params.unk2, - params.unk3); + NGLOG_WARNING(Service_NVDRV, + "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " + "unk1={:X}, unk2={:X}, unk3={:X}", + params.num_entries, params.flags, params.unk0, params.unk1, params.unk2, + params.unk3); params.fence_out.id = 0; params.fence_out.value = 0; std::memcpy(output.data(), ¶ms, output.size()); @@ -111,8 +112,8 @@ u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector& input, std::vector& ou u32 nvhost_gpu::AllocateObjectContext(const std::vector& input, std::vector& output) { IoctlAllocObjCtx params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num=%x, flags=%x", params.class_num, - params.flags); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, + params.flags); params.obj_id = 0x0; std::memcpy(output.data(), ¶ms, output.size()); return 0; @@ -123,8 +124,8 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector& input, std::vector& outp UNIMPLEMENTED(); IoctlSubmitGpfifo params{}; std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo=%" PRIx64 ", num_entries=%x, flags=%x", - params.gpfifo, params.num_entries, params.flags); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", + params.gpfifo, params.num_entries, params.flags); auto entries = std::vector(); entries.resize(params.num_entries); diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index dcf079d918..11df8849d0 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -49,7 +49,7 @@ u32 nvmap::IocCreate(const std::vector& input, std::vector& output) { u32 handle = next_handle++; handles[handle] = std::move(object); - LOG_DEBUG(Service_NVDRV, "size=0x%08X", params.size); + NGLOG_DEBUG(Service_NVDRV, "size={:#010X}", params.size); params.handle = handle; @@ -70,7 +70,7 @@ u32 nvmap::IocAlloc(const std::vector& input, std::vector& output) { object->addr = params.addr; object->status = Object::Status::Allocated; - LOG_DEBUG(Service_NVDRV, "called, addr=0x%" PRIx64, params.addr); + NGLOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr); std::memcpy(output.data(), ¶ms, sizeof(params)); return 0; @@ -80,7 +80,7 @@ u32 nvmap::IocGetId(const std::vector& input, std::vector& output) { IocGetIdParams params; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "called"); + NGLOG_WARNING(Service_NVDRV, "called"); auto object = GetObject(params.handle); ASSERT(object); @@ -95,7 +95,7 @@ u32 nvmap::IocFromId(const std::vector& input, std::vector& output) { IocFromIdParams params; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); auto itr = std::find_if(handles.begin(), handles.end(), [&](const auto& entry) { return entry.second->id == params.id; }); @@ -114,7 +114,7 @@ u32 nvmap::IocParam(const std::vector& input, std::vector& output) { IocParamParams params; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "(STUBBED) called type=%u", params.type); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.type); auto object = GetObject(params.handle); ASSERT(object); diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index d0d64a840b..38b3a9a844 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp @@ -12,7 +12,7 @@ namespace Service::Nvidia { void NVDRV::Open(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); const auto& buffer = ctx.ReadBuffer(); std::string device_name(buffer.begin(), buffer.end()); @@ -25,7 +25,7 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) { } void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IPC::RequestParser rp{ctx}; u32 fd = rp.Pop(); @@ -41,7 +41,7 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { } void NVDRV::Close(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IPC::RequestParser rp{ctx}; u32 fd = rp.Pop(); @@ -53,7 +53,7 @@ void NVDRV::Close(Kernel::HLERequestContext& ctx) { } void NVDRV::Initialize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(0); @@ -63,7 +63,7 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; u32 fd = rp.Pop(); u32 event_id = rp.Pop(); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, fd=%x, event_id=%x", fd, event_id); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, fd={:X}, event_id={:X}", fd, event_id); IPC::ResponseBuilder rb{ctx, 3, 1}; rb.Push(RESULT_SUCCESS); @@ -75,14 +75,14 @@ void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; pid = rp.Pop(); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x%" PRIx64, pid); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, pid={:#X}", pid); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(0); } void NVDRV::FinishInitialize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } From 72b497e8766fe1b75195da80967ab890f90eeb2b Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:47:53 -0400 Subject: [PATCH 31/74] nvflinger: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/nvflinger/buffer_queue.cpp | 4 ++-- src/core/hle/service/nvflinger/nvflinger.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index e4ff2e2677..49e88b3948 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -23,7 +23,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { buffer.igbp_buffer = igbp_buffer; buffer.status = Buffer::Status::Free; - LOG_WARNING(Service, "Adding graphics buffer %u", slot); + NGLOG_WARNING(Service, "Adding graphics buffer {}", slot); queue.emplace_back(buffer); @@ -94,7 +94,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) { } u32 BufferQueue::Query(QueryType type) { - LOG_WARNING(Service, "(STUBBED) called type=%u", static_cast(type)); + NGLOG_WARNING(Service, "(STUBBED) called type={}", static_cast(type)); switch (type) { case QueryType::NativeWindowFormat: // TODO(Subv): Use an enum for this diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index a99ebc8e6f..3481e48d0a 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -48,7 +48,7 @@ NVFlinger::~NVFlinger() { } u64 NVFlinger::OpenDisplay(const std::string& name) { - LOG_WARNING(Service, "Opening display %s", name.c_str()); + NGLOG_WARNING(Service, "Opening display {}", name); // TODO(Subv): Currently we only support the Default display. ASSERT(name == "Default"); From 13f9cf2bd00c79a52cc8b8148db8890ec28fe059 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:49:29 -0400 Subject: [PATCH 32/74] pctl: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/pctl/pctl_a.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/service/pctl/pctl_a.cpp b/src/core/hle/service/pctl/pctl_a.cpp index 9fb4628ada..24a6cf3103 100644 --- a/src/core/hle/service/pctl/pctl_a.cpp +++ b/src/core/hle/service/pctl/pctl_a.cpp @@ -113,7 +113,7 @@ void PCTL_A::CreateService(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_PCTL, "called"); + NGLOG_DEBUG(Service_PCTL, "called"); } PCTL_A::PCTL_A() : ServiceFramework("pctl:a") { From 32ece18bb68a3d3a7c8d9c23456a7447dff1e817 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:50:04 -0400 Subject: [PATCH 33/74] set: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/set/set.cpp | 2 +- src/core/hle/service/set/set_sys.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index fc3e424d04..ece29aa705 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -22,7 +22,7 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_SET, "(STUBBED) called"); + NGLOG_WARNING(Service_SET, "(STUBBED) called"); } SET::SET() : ServiceFramework("set") { diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp index fa85277fe9..762a664c52 100644 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/set_sys.cpp @@ -16,7 +16,7 @@ void SET_SYS::GetColorSetId(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push(0); - LOG_WARNING(Service_SET, "(STUBBED) called"); + NGLOG_WARNING(Service_SET, "(STUBBED) called"); } SET_SYS::SET_SYS() : ServiceFramework("set:sys") { From 2a3f3bf977e1f3f6fe4a188b2194074c3399b5f2 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:51:09 -0400 Subject: [PATCH 34/74] sm: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/sm/controller.cpp | 8 ++++---- src/core/hle/service/sm/sm.cpp | 9 ++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index 13e31620d2..fe5097cdcd 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp @@ -17,7 +17,7 @@ void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push(1); // Converted sessions start with 1 request handler - LOG_DEBUG(Service, "called, server_session=%d", ctx.Session()->GetObjectId()); + NGLOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId()); } void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { @@ -29,11 +29,11 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { Kernel::SharedPtr session{ctx.Session()->parent->client}; rb.PushMoveObjects(session); - LOG_DEBUG(Service, "called, session=%u", session->GetObjectId()); + NGLOG_DEBUG(Service, "called, session={}", session->GetObjectId()); } void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called, using DuplicateSession"); + NGLOG_WARNING(Service, "(STUBBED) called, using DuplicateSession"); DuplicateSession(ctx); } @@ -43,7 +43,7 @@ void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push(0x500); - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); } Controller::Controller() : ServiceFramework("IpcController") { diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 4578fc05f9..073277ade5 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -86,7 +86,7 @@ SM::~SM() = default; void SM::Initialize(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_DEBUG(Service_SM, "called"); + NGLOG_DEBUG(Service_SM, "called"); } void SM::GetService(Kernel::HLERequestContext& ctx) { @@ -102,8 +102,8 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { if (client_port.Failed()) { IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); rb.Push(client_port.Code()); - LOG_ERROR(Service_SM, "called service=%s -> error 0x%08X", name.c_str(), - client_port.Code().raw); + NGLOG_ERROR(Service_SM, "called service={} -> error {:#010X}", name, + client_port.Code().raw); if (name.length() == 0) return; // LibNX Fix UNIMPLEMENTED(); @@ -113,8 +113,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { auto session = client_port.Unwrap()->Connect(); ASSERT(session.Succeeded()); if (session.Succeeded()) { - LOG_DEBUG(Service_SM, "called service=%s -> session=%u", name.c_str(), - (*session)->GetObjectId()); + NGLOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId()); IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles); rb.Push(session.Code()); From 62c69f4a1e6367f0400cf5d3ea8ec640b232b159 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:53:44 -0400 Subject: [PATCH 35/74] sockets: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/sockets/bsd.cpp | 13 +++++++------ src/core/hle/service/sockets/sfdnsres.cpp | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index f99809bede..ab909fdaa3 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -8,7 +8,7 @@ namespace Service::Sockets { void BSD::RegisterClient(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; @@ -17,7 +17,7 @@ void BSD::RegisterClient(Kernel::HLERequestContext& ctx) { } void BSD::StartMonitoring(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; @@ -32,7 +32,8 @@ void BSD::Socket(Kernel::HLERequestContext& ctx) { u32 type = rp.Pop(); u32 protocol = rp.Pop(); - LOG_WARNING(Service, "(STUBBED) called domain=%u type=%u protocol=%u", domain, type, protocol); + NGLOG_WARNING(Service, "(STUBBED) called domain={} type={} protocol={}", domain, type, + protocol); u32 fd = next_fd++; @@ -44,7 +45,7 @@ void BSD::Socket(Kernel::HLERequestContext& ctx) { } void BSD::Connect(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; @@ -54,7 +55,7 @@ void BSD::Connect(Kernel::HLERequestContext& ctx) { } void BSD::SendTo(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; @@ -64,7 +65,7 @@ void BSD::SendTo(Kernel::HLERequestContext& ctx) { } void BSD::Close(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index d235c4cfd0..f377e59f2c 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -10,7 +10,7 @@ namespace Service::Sockets { void SFDNSRES::GetAddrInfo(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; From 82413a6c89481cf943676965e953a73a48be2fa9 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:54:26 -0400 Subject: [PATCH 36/74] spl: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/spl/module.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp index 3f5a342a7b..76ba97156b 100644 --- a/src/core/hle/service/spl/module.cpp +++ b/src/core/hle/service/spl/module.cpp @@ -28,7 +28,7 @@ void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_DEBUG(Service_SPL, "called"); + NGLOG_DEBUG(Service_SPL, "called"); } void InstallInterfaces(SM::ServiceManager& service_manager) { From bfe49edb2af86c2cf82e20a75b14710ceeb4f657 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:54:49 -0400 Subject: [PATCH 37/74] ssl: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/ssl/ssl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 11d438728f..c7788da5c9 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -65,7 +65,7 @@ public: private: void SetOption(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_SSL, "(STUBBED) called"); + NGLOG_WARNING(Service_SSL, "(STUBBED) called"); IPC::RequestParser rp{ctx}; IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); @@ -73,7 +73,7 @@ private: } void CreateConnection(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_SSL, "(STUBBED) called"); + NGLOG_WARNING(Service_SSL, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -82,7 +82,7 @@ private: }; void SSL::CreateContext(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_SSL, "(STUBBED) called"); + NGLOG_WARNING(Service_SSL, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); From bd9c2aa51fca20b4f756b2fbe87b6640b301f28b Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:55:53 -0400 Subject: [PATCH 38/74] time: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/time/time.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 2604ecc1cf..2784653587 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -32,14 +32,14 @@ private: const s64 time_since_epoch{std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()) .count()}; - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(time_since_epoch); } void GetSystemClockContext(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Time, "(STUBBED) called"); + NGLOG_WARNING(Service_Time, "(STUBBED) called"); SystemClockContext system_clock_ontext{}; IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2}; rb.Push(RESULT_SUCCESS); @@ -58,7 +58,7 @@ public: private: void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); SteadyClockTimePoint steady_clock_time_point{cyclesToMs(CoreTiming::GetTicks()) / 1000}; IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2}; rb.Push(RESULT_SUCCESS); @@ -86,7 +86,7 @@ public: private: void GetDeviceLocationName(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Time, "(STUBBED) called"); + NGLOG_WARNING(Service_Time, "(STUBBED) called"); LocationName location_name{}; IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2}; rb.Push(RESULT_SUCCESS); @@ -94,14 +94,14 @@ private: } void GetTotalLocationNameCount(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Time, "(STUBBED) called"); + NGLOG_WARNING(Service_Time, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(0); } void LoadTimeZoneRule(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Time, "(STUBBED) called"); + NGLOG_WARNING(Service_Time, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -110,7 +110,7 @@ private: IPC::RequestParser rp{ctx}; u64 posix_time = rp.Pop(); - LOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x%016lX", posix_time); + NGLOG_WARNING(Service_Time, "(STUBBED) called, posix_time={:#018X}", posix_time); CalendarTime calendar_time{2018, 1, 1, 0, 0, 0}; CalendarAdditionalInfo additional_info{}; @@ -125,35 +125,35 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); } void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); } void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); } void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); } void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(); - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); } Module::Interface::Interface(std::shared_ptr time, const char* name) From 88eb6127183f3334b4ab56873706f142b597d322 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 10:58:52 -0400 Subject: [PATCH 39/74] vi: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/vi/vi.cpp | 53 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 36ae2215f1..45f3568d21 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -470,7 +470,7 @@ private: u32 flags = rp.Pop(); auto buffer_queue = nv_flinger->GetBufferQueue(id); - LOG_DEBUG(Service_VI, "called, transaction=%x", static_cast(transaction)); + NGLOG_DEBUG(Service_VI, "called, transaction={:X}", static_cast(transaction)); if (transaction == TransactionId::Connect) { IGBPConnectRequestParcel request{ctx.ReadBuffer()}; @@ -532,7 +532,7 @@ private: IGBPQueryResponseParcel response{value}; ctx.WriteBuffer(response.Serialize()); } else if (transaction == TransactionId::CancelBuffer) { - LOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); + NGLOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); } else { ASSERT_MSG(false, "Unimplemented"); } @@ -547,7 +547,8 @@ private: s32 addval = rp.PopRaw(); u32 type = rp.Pop(); - LOG_WARNING(Service_VI, "(STUBBED) called id=%u, addval=%08X, type=%08X", id, addval, type); + NGLOG_WARNING(Service_VI, "(STUBBED) called id={}, addval={:08X}, type={:08X}", id, addval, + type); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -561,7 +562,7 @@ private: // TODO(Subv): Find out what this actually is. - LOG_WARNING(Service_VI, "(STUBBED) called id=%u, unknown=%08X", id, unknown); + NGLOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(buffer_queue->GetNativeHandle()); @@ -624,7 +625,7 @@ public: private: void SetLayerZ(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 layer_id = rp.Pop(); u64 z_value = rp.Pop(); @@ -639,8 +640,8 @@ private: bool visibility = rp.Pop(); IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x%x, visibility=%u", layer_id, - visibility); + NGLOG_WARNING(Service_VI, "(STUBBED) called, layer_id={:#010X}, visibility={}", layer_id, + visibility); } }; @@ -722,7 +723,7 @@ public: private: void CloseDisplay(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 display = rp.Pop(); @@ -731,7 +732,7 @@ private: } void CreateManagedLayer(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u32 unknown = rp.Pop(); rp.Skip(1, false); @@ -746,7 +747,7 @@ private: } void AddToLayerStack(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u32 stack = rp.Pop(); u64 layer_id = rp.Pop(); @@ -761,8 +762,8 @@ private: bool visibility = rp.Pop(); IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x%x, visibility=%u", layer_id, - visibility); + NGLOG_WARNING(Service_VI, "(STUBBED) called, layer_id={:#X}, visibility={}", layer_id, + visibility); } std::shared_ptr nv_flinger; @@ -775,7 +776,7 @@ public: private: void GetRelayService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -783,7 +784,7 @@ private: } void GetSystemDisplayService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -791,7 +792,7 @@ private: } void GetManagerDisplayService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -799,7 +800,7 @@ private: } void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -807,7 +808,7 @@ private: } void OpenDisplay(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; auto name_buf = rp.PopRaw>(); auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); @@ -822,7 +823,7 @@ private: } void CloseDisplay(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 display_id = rp.Pop(); @@ -831,7 +832,7 @@ private: } void GetDisplayResolution(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 display_id = rp.Pop(); @@ -848,7 +849,7 @@ private: } void SetLayerScalingMode(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u32 scaling_mode = rp.Pop(); u64 unknown = rp.Pop(); @@ -864,11 +865,11 @@ private: IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); rb.Push(RESULT_SUCCESS); rb.Push(1); - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); } void OpenLayer(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_VI, "called"); + NGLOG_DEBUG(Service_VI, "called"); IPC::RequestParser rp{ctx}; auto name_buf = rp.PopRaw>(); auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); @@ -888,7 +889,7 @@ private: } void CreateStrayLayer(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_VI, "called"); + NGLOG_DEBUG(Service_VI, "called"); IPC::RequestParser rp{ctx}; u32 flags = rp.Pop(); @@ -908,7 +909,7 @@ private: } void DestroyStrayLayer(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 layer_id = rp.Pop(); @@ -918,7 +919,7 @@ private: } void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 display_id = rp.Pop(); @@ -967,7 +968,7 @@ Module::Interface::Interface(std::shared_ptr module, const char* name, : ServiceFramework(name), module(std::move(module)), nv_flinger(std::move(nv_flinger)) {} void Module::Interface::GetDisplayService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); From d08cfb55fe77599074a4d55cc10149257c1fcd84 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 11:05:22 -0400 Subject: [PATCH 40/74] service: Move logging macros over to new fmt-compatible ones --- src/core/hle/service/service.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 08ce296772..5817819fee 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -120,7 +120,7 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext } buf.push_back('}'); - LOG_ERROR(Service, "unknown / unimplemented %s", fmt::to_string(buf).c_str()); + NGLOG_ERROR(Service, "unknown / unimplemented {}", fmt::to_string(buf)); UNIMPLEMENTED(); } @@ -131,8 +131,8 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) { return ReportUnimplementedFunction(ctx, info); } - LOG_TRACE( - Service, "%s", + NGLOG_TRACE( + Service, "{}", MakeFunctionString(info->name, GetServiceName().c_str(), ctx.CommandBuffer()).c_str()); handler_invoker(this, info->handler_callback, ctx); } @@ -199,12 +199,12 @@ void Init(std::shared_ptr& sm) { VI::InstallInterfaces(*sm, nv_flinger); Set::InstallInterfaces(*sm); - LOG_DEBUG(Service, "initialized OK"); + NGLOG_DEBUG(Service, "initialized OK"); } /// Shutdown ServiceManager void Shutdown() { g_kernel_named_ports.clear(); - LOG_DEBUG(Service, "shutdown OK"); + NGLOG_DEBUG(Service, "shutdown OK"); } } // namespace Service From 9e11a76e926a7190880063d8fc8c3d97003b9938 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 21 Apr 2018 11:16:21 -0400 Subject: [PATCH 41/74] memory_manager: Use GPUVAdddr, not PAddr, for GPU addresses. --- src/video_core/command_processor.cpp | 4 +- src/video_core/engines/maxwell_3d.cpp | 11 ++- src/video_core/memory_manager.cpp | 72 +++++++++---------- src/video_core/memory_manager.h | 16 ++--- .../renderer_opengl/gl_rasterizer.cpp | 6 +- .../renderer_opengl/gl_rasterizer_cache.cpp | 4 +- .../debugger/graphics/graphics_surface.cpp | 4 +- 7 files changed, 57 insertions(+), 60 deletions(-) diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index d4cdb4ab2a..7850ae103f 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -90,9 +90,7 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) } void GPU::ProcessCommandList(GPUVAddr address, u32 size) { - // TODO(Subv): PhysicalToVirtualAddress is a misnomer, it converts a GPU VAddr into an - // application VAddr. - const VAddr head_address = memory_manager->PhysicalToVirtualAddress(address); + const VAddr head_address = memory_manager->GpuToCpuAddress(address); VAddr current_addr = head_address; while (current_addr < head_address + size * sizeof(CommandHeader)) { const CommandHeader header = {Memory::Read32(current_addr)}; diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 35773a6956..8d7d627b8b 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -145,7 +145,7 @@ void Maxwell3D::ProcessQueryGet() { GPUVAddr sequence_address = regs.query.QueryAddress(); // Since the sequence address is given as a GPU VAddr, we have to convert it to an application // VAddr before writing. - VAddr address = memory_manager.PhysicalToVirtualAddress(sequence_address); + VAddr address = memory_manager.GpuToCpuAddress(sequence_address); // TODO(Subv): Support the other query units. ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, @@ -225,8 +225,7 @@ void Maxwell3D::ProcessCBData(u32 value) { // Don't allow writing past the end of the buffer. ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); - VAddr address = - memory_manager.PhysicalToVirtualAddress(buffer_address + regs.const_buffer.cb_pos); + VAddr address = memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); Memory::Write32(address, value); @@ -238,7 +237,7 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { GPUVAddr tic_base_address = regs.tic.TICAddress(); GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry); - VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu); + VAddr tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); Texture::TICEntry tic_entry; Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); @@ -268,7 +267,7 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { GPUVAddr tsc_base_address = regs.tsc.TSCAddress(); GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry); - VAddr tsc_address_cpu = memory_manager.PhysicalToVirtualAddress(tsc_address_gpu); + VAddr tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); Texture::TSCEntry tsc_entry; Memory::ReadBlock(tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); @@ -293,7 +292,7 @@ std::vector Maxwell3D::GetStageTextures(Regs::ShaderSt current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) { Texture::TextureHandle tex_handle{ - Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))}; + Memory::Read32(memory_manager.GpuToCpuAddress(current_texture))}; Texture::FullTextureInfo tex_info{}; // TODO(Subv): Use the shader to determine which textures are actually accessed. diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 2e1edee030..3f21071c00 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -8,90 +8,90 @@ namespace Tegra { -PAddr MemoryManager::AllocateSpace(u64 size, u64 align) { - boost::optional paddr = FindFreeBlock(size, align); - ASSERT(paddr); +GPUVAddr MemoryManager::AllocateSpace(u64 size, u64 align) { + boost::optional gpu_addr = FindFreeBlock(size, align); + ASSERT(gpu_addr); for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { - ASSERT(PageSlot(*paddr + offset) == static_cast(PageStatus::Unmapped)); - PageSlot(*paddr + offset) = static_cast(PageStatus::Allocated); + ASSERT(PageSlot(*gpu_addr + offset) == static_cast(PageStatus::Unmapped)); + PageSlot(*gpu_addr + offset) = static_cast(PageStatus::Allocated); } - return *paddr; + return *gpu_addr; } -PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) { +GPUVAddr MemoryManager::AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align) { for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { - ASSERT(PageSlot(paddr + offset) == static_cast(PageStatus::Unmapped)); - PageSlot(paddr + offset) = static_cast(PageStatus::Allocated); + ASSERT(PageSlot(gpu_addr + offset) == static_cast(PageStatus::Unmapped)); + PageSlot(gpu_addr + offset) = static_cast(PageStatus::Allocated); } - return paddr; + return gpu_addr; } -PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) { - boost::optional paddr = FindFreeBlock(size, PAGE_SIZE); - ASSERT(paddr); +GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) { + boost::optional gpu_addr = FindFreeBlock(size, PAGE_SIZE); + ASSERT(gpu_addr); for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { - ASSERT(PageSlot(*paddr + offset) == static_cast(PageStatus::Unmapped)); - PageSlot(*paddr + offset) = vaddr + offset; + ASSERT(PageSlot(*gpu_addr + offset) == static_cast(PageStatus::Unmapped)); + PageSlot(*gpu_addr + offset) = cpu_addr + offset; } - return *paddr; + return *gpu_addr; } -PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) { - ASSERT((paddr & PAGE_MASK) == 0); +GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size) { + ASSERT((gpu_addr & PAGE_MASK) == 0); for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { - ASSERT(PageSlot(paddr + offset) == static_cast(PageStatus::Allocated)); - PageSlot(paddr + offset) = vaddr + offset; + ASSERT(PageSlot(gpu_addr + offset) == static_cast(PageStatus::Allocated)); + PageSlot(gpu_addr + offset) = cpu_addr + offset; } - return paddr; + return gpu_addr; } -boost::optional MemoryManager::FindFreeBlock(u64 size, u64 align) { - PAddr paddr = 0; +boost::optional MemoryManager::FindFreeBlock(u64 size, u64 align) { + GPUVAddr gpu_addr = 0; u64 free_space = 0; align = (align + PAGE_MASK) & ~PAGE_MASK; - while (paddr + free_space < MAX_ADDRESS) { - if (!IsPageMapped(paddr + free_space)) { + while (gpu_addr + free_space < MAX_ADDRESS) { + if (!IsPageMapped(gpu_addr + free_space)) { free_space += PAGE_SIZE; if (free_space >= size) { - return paddr; + return gpu_addr; } } else { - paddr += free_space + PAGE_SIZE; + gpu_addr += free_space + PAGE_SIZE; free_space = 0; - paddr = Common::AlignUp(paddr, align); + gpu_addr = Common::AlignUp(gpu_addr, align); } } return {}; } -VAddr MemoryManager::PhysicalToVirtualAddress(PAddr paddr) { - VAddr base_addr = PageSlot(paddr); +VAddr MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { + VAddr base_addr = PageSlot(gpu_addr); ASSERT(base_addr != static_cast(PageStatus::Unmapped)); - return base_addr + (paddr & PAGE_MASK); + return base_addr + (gpu_addr & PAGE_MASK); } -bool MemoryManager::IsPageMapped(PAddr paddr) { - return PageSlot(paddr) != static_cast(PageStatus::Unmapped); +bool MemoryManager::IsPageMapped(GPUVAddr gpu_addr) { + return PageSlot(gpu_addr) != static_cast(PageStatus::Unmapped); } -VAddr& MemoryManager::PageSlot(PAddr paddr) { - auto& block = page_table[(paddr >> (PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; +VAddr& MemoryManager::PageSlot(GPUVAddr gpu_addr) { + auto& block = page_table[(gpu_addr >> (PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; if (!block) { block = std::make_unique(); for (unsigned index = 0; index < PAGE_BLOCK_SIZE; index++) { (*block)[index] = static_cast(PageStatus::Unmapped); } } - return (*block)[(paddr >> PAGE_BITS) & PAGE_BLOCK_MASK]; + return (*block)[(gpu_addr >> PAGE_BITS) & PAGE_BLOCK_MASK]; } } // namespace Tegra diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index b73e283f84..4710cb21f6 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h @@ -18,20 +18,20 @@ class MemoryManager final { public: MemoryManager() = default; - PAddr AllocateSpace(u64 size, u64 align); - PAddr AllocateSpace(PAddr paddr, u64 size, u64 align); - PAddr MapBufferEx(VAddr vaddr, u64 size); - PAddr MapBufferEx(VAddr vaddr, PAddr paddr, u64 size); - VAddr PhysicalToVirtualAddress(PAddr paddr); + GPUVAddr AllocateSpace(u64 size, u64 align); + GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align); + GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size); + GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size); + VAddr GpuToCpuAddress(GPUVAddr gpu_addr); static constexpr u64 PAGE_BITS = 16; static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS; static constexpr u64 PAGE_MASK = PAGE_SIZE - 1; private: - boost::optional FindFreeBlock(u64 size, u64 align = 1); - bool IsPageMapped(PAddr paddr); - VAddr& PageSlot(PAddr paddr); + boost::optional FindFreeBlock(u64 size, u64 align = 1); + bool IsPageMapped(GPUVAddr gpu_addr); + VAddr& PageSlot(GPUVAddr gpu_addr); enum class PageStatus : u64 { Unmapped = 0xFFFFFFFFFFFFFFFFULL, diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 82001e7b41..8568d67627 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -233,7 +233,7 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { // Fetch program code from memory GLShader::ProgramCode program_code; const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset}; - const VAddr cpu_address{gpu.memory_manager.PhysicalToVirtualAddress(gpu_address)}; + const VAddr cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)}; Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64)); GLShader::ShaderSetup setup{std::move(program_code)}; @@ -395,7 +395,7 @@ void RasterizerOpenGL::DrawArrays() { if (is_indexed) { const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; const VAddr index_data_addr{ - memory_manager->PhysicalToVirtualAddress(regs.index_array.StartAddress())}; + memory_manager->GpuToCpuAddress(regs.index_array.StartAddress())}; Memory::ReadBlock(index_data_addr, offseted_buffer, index_buffer_size); index_buffer_offset = buffer_offset; @@ -659,7 +659,7 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr buffer_draw_state.enabled = true; buffer_draw_state.bindpoint = current_bindpoint + bindpoint; - VAddr addr = gpu.memory_manager->PhysicalToVirtualAddress(buffer.address); + VAddr addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); std::vector data(used_buffer.GetSize() * sizeof(float)); Memory::ReadBlock(addr, data.data(), data.size()); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 7410471cc6..46f0f25aaf 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1028,7 +1028,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu auto& gpu = Core::System::GetInstance().GPU(); SurfaceParams params; - params.addr = gpu.memory_manager->PhysicalToVirtualAddress(config.tic.Address()); + params.addr = gpu.memory_manager->GpuToCpuAddress(config.tic.Address()); params.width = config.tic.Width(); params.height = config.tic.Height(); params.is_tiled = config.tic.IsTiled(); @@ -1106,7 +1106,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; SurfaceParams depth_params = color_params; - color_params.addr = memory_manager->PhysicalToVirtualAddress(config.Address()); + color_params.addr = memory_manager->GpuToCpuAddress(config.Address()); color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format); color_params.UpdateParams(); diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index 5fada74be9..5cadb807ec 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp @@ -378,7 +378,7 @@ void GraphicsSurfaceWidget::OnUpdate() { // TODO: Implement a good way to visualize alpha components! QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); - VAddr address = gpu.memory_manager->PhysicalToVirtualAddress(surface_address); + VAddr address = gpu.memory_manager->GpuToCpuAddress(surface_address); auto unswizzled_data = Tegra::Texture::UnswizzleTexture(address, surface_format, surface_width, surface_height); @@ -437,7 +437,7 @@ void GraphicsSurfaceWidget::SaveSurface() { pixmap->save(&file, "PNG"); } else if (selectedFilter == bin_filter) { auto& gpu = Core::System::GetInstance().GPU(); - VAddr address = gpu.memory_manager->PhysicalToVirtualAddress(surface_address); + VAddr address = gpu.memory_manager->GpuToCpuAddress(surface_address); const u8* buffer = Memory::GetPointer(address); ASSERT_MSG(buffer != nullptr, "Memory not accessible"); From 239ac8abe228b9080741ba7d50d9e13cc4a1ceae Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 21 Apr 2018 12:31:30 -0400 Subject: [PATCH 42/74] memory_manager: Make GpuToCpuAddress return an optional. --- src/video_core/command_processor.cpp | 6 +++--- src/video_core/engines/maxwell_3d.cpp | 21 ++++++++++--------- src/video_core/memory_manager.cpp | 7 ++++++- src/video_core/memory_manager.h | 5 ++++- .../renderer_opengl/gl_rasterizer.cpp | 14 ++++++------- .../renderer_opengl/gl_rasterizer_cache.cpp | 4 ++-- .../debugger/graphics/graphics_surface.cpp | 8 +++---- 7 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 7850ae103f..2c04daba34 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -90,9 +90,9 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) } void GPU::ProcessCommandList(GPUVAddr address, u32 size) { - const VAddr head_address = memory_manager->GpuToCpuAddress(address); - VAddr current_addr = head_address; - while (current_addr < head_address + size * sizeof(CommandHeader)) { + const boost::optional head_address = memory_manager->GpuToCpuAddress(address); + VAddr current_addr = *head_address; + while (current_addr < *head_address + size * sizeof(CommandHeader)) { const CommandHeader header = {Memory::Read32(current_addr)}; current_addr += sizeof(u32); diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 8d7d627b8b..4e9aed380f 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -145,7 +145,7 @@ void Maxwell3D::ProcessQueryGet() { GPUVAddr sequence_address = regs.query.QueryAddress(); // Since the sequence address is given as a GPU VAddr, we have to convert it to an application // VAddr before writing. - VAddr address = memory_manager.GpuToCpuAddress(sequence_address); + boost::optional address = memory_manager.GpuToCpuAddress(sequence_address); // TODO(Subv): Support the other query units. ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, @@ -153,7 +153,7 @@ void Maxwell3D::ProcessQueryGet() { ASSERT_MSG(regs.query.query_get.short_query, "Writing the entire query result structure is unimplemented"); - u32 value = Memory::Read32(address); + u32 value = Memory::Read32(*address); u32 result = 0; // TODO(Subv): Support the other query variables @@ -173,7 +173,7 @@ void Maxwell3D::ProcessQueryGet() { case Regs::QueryMode::Write2: { // Write the current query sequence to the sequence address. u32 sequence = regs.query.query_sequence; - Memory::Write32(address, sequence); + Memory::Write32(*address, sequence); // TODO(Subv): Write the proper query response structure to the address when not using short // mode. @@ -225,9 +225,10 @@ void Maxwell3D::ProcessCBData(u32 value) { // Don't allow writing past the end of the buffer. ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); - VAddr address = memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); + boost::optional address = + memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); - Memory::Write32(address, value); + Memory::Write32(*address, value); // Increment the current buffer position. regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4; @@ -237,10 +238,10 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { GPUVAddr tic_base_address = regs.tic.TICAddress(); GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry); - VAddr tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); + boost::optional tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); Texture::TICEntry tic_entry; - Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); + Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); ASSERT_MSG(tic_entry.header_version == Texture::TICHeaderVersion::BlockLinear || tic_entry.header_version == Texture::TICHeaderVersion::Pitch, @@ -267,10 +268,10 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { GPUVAddr tsc_base_address = regs.tsc.TSCAddress(); GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry); - VAddr tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); + boost::optional tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); Texture::TSCEntry tsc_entry; - Memory::ReadBlock(tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); + Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); return tsc_entry; } @@ -292,7 +293,7 @@ std::vector Maxwell3D::GetStageTextures(Regs::ShaderSt current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) { Texture::TextureHandle tex_handle{ - Memory::Read32(memory_manager.GpuToCpuAddress(current_texture))}; + Memory::Read32(*memory_manager.GpuToCpuAddress(current_texture))}; Texture::FullTextureInfo tex_info{}; // TODO(Subv): Use the shader to determine which textures are actually accessed. diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 3f21071c00..9bbbb7e650 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -73,9 +73,14 @@ boost::optional MemoryManager::FindFreeBlock(u64 size, u64 align) { return {}; } -VAddr MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { +boost::optional MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { VAddr base_addr = PageSlot(gpu_addr); ASSERT(base_addr != static_cast(PageStatus::Unmapped)); + + if (base_addr == static_cast(PageStatus::Allocated)) { + return {}; + } + return base_addr + (gpu_addr & PAGE_MASK); } diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 4710cb21f6..246c8fb7e8 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h @@ -6,6 +6,9 @@ #include #include + +#include + #include "common/common_types.h" #include "core/memory.h" @@ -22,7 +25,7 @@ public: GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align); GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size); GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size); - VAddr GpuToCpuAddress(GPUVAddr gpu_addr); + boost::optional GpuToCpuAddress(GPUVAddr gpu_addr); static constexpr u64 PAGE_BITS = 16; static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 8568d67627..71612790be 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -150,7 +150,7 @@ std::pair RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, u64 size = end - start + 1; // Copy vertex array data - const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(start)}; + const VAddr data_addr{*memory_manager->GpuToCpuAddress(start)}; res_cache.FlushRegion(data_addr, size, nullptr); Memory::ReadBlock(data_addr, array_ptr, size); @@ -233,8 +233,8 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { // Fetch program code from memory GLShader::ProgramCode program_code; const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset}; - const VAddr cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)}; - Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64)); + const boost::optional cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)}; + Memory::ReadBlock(*cpu_address, program_code.data(), program_code.size() * sizeof(u64)); GLShader::ShaderSetup setup{std::move(program_code)}; GLShader::ShaderEntries shader_resources; @@ -394,9 +394,9 @@ void RasterizerOpenGL::DrawArrays() { GLintptr index_buffer_offset = 0; if (is_indexed) { const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; - const VAddr index_data_addr{ + const boost::optional index_data_addr{ memory_manager->GpuToCpuAddress(regs.index_array.StartAddress())}; - Memory::ReadBlock(index_data_addr, offseted_buffer, index_buffer_size); + Memory::ReadBlock(*index_data_addr, offseted_buffer, index_buffer_size); index_buffer_offset = buffer_offset; offseted_buffer += index_buffer_size; @@ -659,9 +659,9 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr buffer_draw_state.enabled = true; buffer_draw_state.bindpoint = current_bindpoint + bindpoint; - VAddr addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); + boost::optional addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); std::vector data(used_buffer.GetSize() * sizeof(float)); - Memory::ReadBlock(addr, data.data(), data.size()); + Memory::ReadBlock(*addr, data.data(), data.size()); glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo); glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 46f0f25aaf..ced648c123 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1028,7 +1028,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu auto& gpu = Core::System::GetInstance().GPU(); SurfaceParams params; - params.addr = gpu.memory_manager->GpuToCpuAddress(config.tic.Address()); + params.addr = *gpu.memory_manager->GpuToCpuAddress(config.tic.Address()); params.width = config.tic.Width(); params.height = config.tic.Height(); params.is_tiled = config.tic.IsTiled(); @@ -1106,7 +1106,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; SurfaceParams depth_params = color_params; - color_params.addr = memory_manager->GpuToCpuAddress(config.Address()); + color_params.addr = *memory_manager->GpuToCpuAddress(config.Address()); color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format); color_params.UpdateParams(); diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index 5cadb807ec..1fbca8ad09 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp @@ -378,10 +378,10 @@ void GraphicsSurfaceWidget::OnUpdate() { // TODO: Implement a good way to visualize alpha components! QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); - VAddr address = gpu.memory_manager->GpuToCpuAddress(surface_address); + boost::optional address = gpu.memory_manager->GpuToCpuAddress(surface_address); auto unswizzled_data = - Tegra::Texture::UnswizzleTexture(address, surface_format, surface_width, surface_height); + Tegra::Texture::UnswizzleTexture(*address, surface_format, surface_width, surface_height); auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, surface_width, surface_height); @@ -437,9 +437,9 @@ void GraphicsSurfaceWidget::SaveSurface() { pixmap->save(&file, "PNG"); } else if (selectedFilter == bin_filter) { auto& gpu = Core::System::GetInstance().GPU(); - VAddr address = gpu.memory_manager->GpuToCpuAddress(surface_address); + boost::optional address = gpu.memory_manager->GpuToCpuAddress(surface_address); - const u8* buffer = Memory::GetPointer(address); + const u8* buffer = Memory::GetPointer(*address); ASSERT_MSG(buffer != nullptr, "Memory not accessible"); QFile file(filename); From 10c6d891190e407cf4fbcf6eb8ce2506ddf388ec Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 21 Apr 2018 14:40:51 -0400 Subject: [PATCH 43/74] memory_manager: Add implement CpuToGpuAddress. --- src/video_core/memory_manager.cpp | 17 +++++++++++++++++ src/video_core/memory_manager.h | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 9bbbb7e650..25984439d6 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -38,6 +38,9 @@ GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) { PageSlot(*gpu_addr + offset) = cpu_addr + offset; } + MappedRegion region{cpu_addr, *gpu_addr, size}; + mapped_regions.push_back(region); + return *gpu_addr; } @@ -49,6 +52,9 @@ GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size) PageSlot(gpu_addr + offset) = cpu_addr + offset; } + MappedRegion region{cpu_addr, gpu_addr, size}; + mapped_regions.push_back(region); + return gpu_addr; } @@ -84,6 +90,17 @@ boost::optional MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { return base_addr + (gpu_addr & PAGE_MASK); } +std::vector MemoryManager::CpuToGpuAddress(VAddr cpu_addr) const { + std::vector results; + for (const auto& region : mapped_regions) { + if (cpu_addr >= region.cpu_addr && cpu_addr < (region.cpu_addr + region.size)) { + u64 offset = cpu_addr - region.cpu_addr; + results.push_back(region.gpu_addr + offset); + } + } + return results; +} + bool MemoryManager::IsPageMapped(GPUVAddr gpu_addr) { return PageSlot(gpu_addr) != static_cast(PageStatus::Unmapped); } diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 246c8fb7e8..7d745101fd 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h @@ -6,6 +6,7 @@ #include #include +#include #include @@ -26,6 +27,7 @@ public: GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size); GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size); boost::optional GpuToCpuAddress(GPUVAddr gpu_addr); + std::vector CpuToGpuAddress(VAddr cpu_addr) const; static constexpr u64 PAGE_BITS = 16; static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS; @@ -51,6 +53,14 @@ private: using PageBlock = std::array; std::array, PAGE_TABLE_SIZE> page_table{}; + + struct MappedRegion { + VAddr cpu_addr; + GPUVAddr gpu_addr; + u64 size; + }; + + std::vector mapped_regions; }; } // namespace Tegra From cc2e14ec2a2a0ae5217244237b112fdd1b464d6e Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 24 Apr 2018 20:17:03 -0400 Subject: [PATCH 44/74] loader: Move old logging macros over to new fmt-capable ones --- .../loader/deconstructed_rom_directory.cpp | 8 +++--- src/core/loader/elf.cpp | 26 +++++++++---------- src/core/loader/linker.cpp | 4 +-- src/core/loader/loader.cpp | 8 +++--- src/core/loader/nso.cpp | 5 ++-- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 8696c28bd2..40a81025fa 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -132,7 +132,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( const VAddr load_addr = next_load_addr; next_load_addr = AppLoader_NSO::LoadModule(path, load_addr); if (next_load_addr) { - LOG_DEBUG(Loader, "loaded module %s @ 0x%" PRIx64, module, load_addr); + NGLOG_DEBUG(Loader, "loaded module {} @ {:#X}", module, load_addr); } else { next_load_addr = load_addr; } @@ -163,7 +163,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS( std::shared_ptr& romfs_file, u64& offset, u64& size) { if (filepath_romfs.empty()) { - LOG_DEBUG(Loader, "No RomFS available"); + NGLOG_DEBUG(Loader, "No RomFS available"); return ResultStatus::ErrorNotUsed; } @@ -176,8 +176,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS( offset = 0; size = romfs_file->GetSize(); - LOG_DEBUG(Loader, "RomFS offset: 0x%016" PRIX64, offset); - LOG_DEBUG(Loader, "RomFS size: 0x%016" PRIX64, size); + NGLOG_DEBUG(Loader, "RomFS offset: {:#018X}", offset); + NGLOG_DEBUG(Loader, "RomFS size: {:#018X}", size); // Reset read pointer file.Seek(0, SEEK_SET); diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index e9f4621960..e42d3a8703 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -273,18 +273,18 @@ const char* ElfReader::GetSectionName(int section) const { } SharedPtr ElfReader::LoadInto(u32 vaddr) { - LOG_DEBUG(Loader, "String section: %i", header->e_shstrndx); + NGLOG_DEBUG(Loader, "String section: {}", header->e_shstrndx); // Should we relocate? relocate = (header->e_type != ET_EXEC); if (relocate) { - LOG_DEBUG(Loader, "Relocatable module"); + NGLOG_DEBUG(Loader, "Relocatable module"); entryPoint += vaddr; } else { - LOG_DEBUG(Loader, "Prerelocated executable"); + NGLOG_DEBUG(Loader, "Prerelocated executable"); } - LOG_DEBUG(Loader, "%i segments:", header->e_phnum); + NGLOG_DEBUG(Loader, "{} segments:", header->e_phnum); // First pass : Get the bits into RAM u32 base_addr = relocate ? vaddr : 0; @@ -304,8 +304,8 @@ SharedPtr ElfReader::LoadInto(u32 vaddr) { for (unsigned int i = 0; i < header->e_phnum; ++i) { Elf32_Phdr* p = &segments[i]; - LOG_DEBUG(Loader, "Type: %i Vaddr: %08X Filesz: %8X Memsz: %8X ", p->p_type, p->p_vaddr, - p->p_filesz, p->p_memsz); + NGLOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type, + p->p_vaddr, p->p_filesz, p->p_memsz); if (p->p_type == PT_LOAD) { CodeSet::Segment* codeset_segment; @@ -317,16 +317,16 @@ SharedPtr ElfReader::LoadInto(u32 vaddr) { } else if (permission_flags == (PF_R | PF_W)) { codeset_segment = &codeset->data; } else { - LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id %u with flags %X", i, - p->p_flags); + NGLOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, + p->p_flags); continue; } if (codeset_segment->size != 0) { - LOG_ERROR(Loader, - "ELF has more than one segment of the same type. Skipping extra " - "segment (id %i)", - i); + NGLOG_ERROR(Loader, + "ELF has more than one segment of the same type. Skipping extra " + "segment (id {})", + i); continue; } @@ -345,7 +345,7 @@ SharedPtr ElfReader::LoadInto(u32 vaddr) { codeset->entrypoint = base_addr + header->e_entry; codeset->memory = std::make_shared>(std::move(program_image)); - LOG_DEBUG(Loader, "Done loading."); + NGLOG_DEBUG(Loader, "Done loading."); return codeset; } diff --git a/src/core/loader/linker.cpp b/src/core/loader/linker.cpp index 69198e3e39..c7be5f2657 100644 --- a/src/core/loader/linker.cpp +++ b/src/core/loader/linker.cpp @@ -84,7 +84,7 @@ void Linker::WriteRelocations(std::vector& program_image, const std::vector< } break; default: - LOG_CRITICAL(Loader, "Unknown relocation type: %d", static_cast(rela.type)); + NGLOG_CRITICAL(Loader, "Unknown relocation type: {}", static_cast(rela.type)); break; } } @@ -141,7 +141,7 @@ void Linker::ResolveImports() { if (search != exports.end()) { Memory::Write64(import.second.ea, search->second + import.second.addend); } else { - LOG_ERROR(Loader, "Unresolved import: %s", import.first.c_str()); + NGLOG_ERROR(Loader, "Unresolved import: {}", import.first); } } } diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 2ec08506dd..6a4fd38cbe 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -41,7 +41,7 @@ FileType IdentifyFile(FileUtil::IOFile& file, const std::string& filepath) { FileType IdentifyFile(const std::string& file_name) { FileUtil::IOFile file(file_name, "rb"); if (!file.IsOpen()) { - LOG_ERROR(Loader, "Failed to load file %s", file_name.c_str()); + NGLOG_ERROR(Loader, "Failed to load file {}", file_name); return FileType::Unknown; } @@ -116,7 +116,7 @@ static std::unique_ptr GetFileLoader(FileUtil::IOFile&& file, FileTyp std::unique_ptr GetLoader(const std::string& filename) { FileUtil::IOFile file(filename, "rb"); if (!file.IsOpen()) { - LOG_ERROR(Loader, "Failed to load file %s", filename.c_str()); + NGLOG_ERROR(Loader, "Failed to load file {}", filename); return nullptr; } @@ -127,12 +127,12 @@ std::unique_ptr GetLoader(const std::string& filename) { FileType filename_type = GuessFromExtension(filename_extension); if (type != filename_type) { - LOG_WARNING(Loader, "File %s has a different type than its extension.", filename.c_str()); + NGLOG_WARNING(Loader, "File {} has a different type than its extension.", filename); if (FileType::Unknown == type) type = filename_type; } - LOG_DEBUG(Loader, "Loading file %s as %s...", filename.c_str(), GetFileTypeString(type)); + NGLOG_DEBUG(Loader, "Loading file {} as {}...", filename, GetFileTypeString(type)); return GetFileLoader(std::move(file), type, filename_filename, filename); } diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 962bed2ab4..1842bae209 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -73,7 +73,7 @@ static std::vector ReadSegment(FileUtil::IOFile& file, const NsoSegmentHeade file.Seek(header.offset, SEEK_SET); if (compressed_size != file.ReadBytes(compressed_data.data(), compressed_size)) { - LOG_CRITICAL(Loader, "Failed to read %d NSO LZ4 compressed bytes", compressed_size); + NGLOG_CRITICAL(Loader, "Failed to read {} NSO LZ4 compressed bytes", compressed_size); return {}; } @@ -158,8 +158,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr& process) { // Load module LoadModule(filepath, Memory::PROCESS_IMAGE_VADDR); - LOG_DEBUG(Loader, "loaded module %s @ 0x%" PRIx64, filepath.c_str(), - Memory::PROCESS_IMAGE_VADDR); + NGLOG_DEBUG(Loader, "loaded module {} @ {:#X}", filepath, Memory::PROCESS_IMAGE_VADDR); process->svc_access_mask.set(); process->address_mappings = default_address_mappings; From 4415e00181f71b35eea779157976773d9bccf638 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 24 Apr 2018 00:19:36 -0400 Subject: [PATCH 45/74] gl_rasterizer_cache: Update to be based on GPU addresses, not CPU addresses. --- src/core/memory.cpp | 64 ++++++++++++++----- src/core/memory.h | 3 +- src/video_core/memory_manager.h | 1 - src/video_core/rasterizer_interface.h | 7 +- .../renderer_opengl/gl_rasterizer.cpp | 13 ++-- .../renderer_opengl/gl_rasterizer.h | 7 +- .../renderer_opengl/gl_rasterizer_cache.cpp | 63 +++++++++++------- .../renderer_opengl/gl_rasterizer_cache.h | 27 ++++---- .../renderer_opengl/renderer_opengl.cpp | 3 +- src/video_core/textures/decoders.cpp | 1 + 10 files changed, 122 insertions(+), 67 deletions(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 291bf066f3..ff0420c562 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -325,15 +325,29 @@ u8* GetPhysicalPointer(PAddr address) { return target_pointer; } -void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached) { - if (start == 0) { +void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) { + if (gpu_addr == 0) { return; } - u64 num_pages = ((start + size - 1) >> PAGE_BITS) - (start >> PAGE_BITS) + 1; - VAddr vaddr = start; + // Iterate over a contiguous CPU address space, which corresponds to the specified GPU address + // space, marking the region as un/cached. The region is marked un/cached at a granularity of + // CPU pages, hence why we iterate on a CPU page basis (note: GPU page size is different). This + // assumes the specified GPU address region is contiguous as well. + + u64 num_pages = ((gpu_addr + size - 1) >> PAGE_BITS) - (gpu_addr >> PAGE_BITS) + 1; + for (unsigned i = 0; i < num_pages; ++i, gpu_addr += PAGE_SIZE) { + boost::optional maybe_vaddr = + Core::System::GetInstance().GPU().memory_manager->GpuToCpuAddress(gpu_addr); + // The GPU <-> CPU virtual memory mapping is not 1:1 + if (!maybe_vaddr) { + LOG_ERROR(HW_Memory, + "Trying to flush a cached region to an invalid physical address %08X", + gpu_addr); + continue; + } + VAddr vaddr = *maybe_vaddr; - for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) { PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; if (cached) { @@ -347,6 +361,10 @@ void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached) { page_type = PageType::RasterizerCachedMemory; current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; break; + case PageType::RasterizerCachedMemory: + // There can be more than one GPU region mapped per CPU region, so it's common that + // this area is already marked as cached. + break; default: UNREACHABLE(); } @@ -357,6 +375,10 @@ void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached) { // It is not necessary for a process to have this region mapped into its address // space, for example, a system module need not have a VRAM mapping. break; + case PageType::Memory: + // There can be more than one GPU region mapped per CPU region, so it's common that + // this area is already unmarked as cached. + break; case PageType::RasterizerCachedMemory: { u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); if (pointer == nullptr) { @@ -394,19 +416,29 @@ void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { VAddr overlap_start = std::max(start, region_start); VAddr overlap_end = std::min(end, region_end); + + std::vector gpu_addresses = + Core::System::GetInstance().GPU().memory_manager->CpuToGpuAddress(overlap_start); + + if (gpu_addresses.empty()) { + return; + } + u64 overlap_size = overlap_end - overlap_start; - auto* rasterizer = VideoCore::g_renderer->Rasterizer(); - switch (mode) { - case FlushMode::Flush: - rasterizer->FlushRegion(overlap_start, overlap_size); - break; - case FlushMode::Invalidate: - rasterizer->InvalidateRegion(overlap_start, overlap_size); - break; - case FlushMode::FlushAndInvalidate: - rasterizer->FlushAndInvalidateRegion(overlap_start, overlap_size); - break; + for (const auto& gpu_address : gpu_addresses) { + auto* rasterizer = VideoCore::g_renderer->Rasterizer(); + switch (mode) { + case FlushMode::Flush: + rasterizer->FlushRegion(gpu_address, overlap_size); + break; + case FlushMode::Invalidate: + rasterizer->InvalidateRegion(gpu_address, overlap_size); + break; + case FlushMode::FlushAndInvalidate: + rasterizer->FlushAndInvalidateRegion(gpu_address, overlap_size); + break; + } } }; diff --git a/src/core/memory.h b/src/core/memory.h index e9b8ca8739..3f56a2c6a6 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -14,6 +14,7 @@ #include #include "common/common_types.h" #include "core/memory_hook.h" +#include "video_core/memory_manager.h" namespace Kernel { class Process; @@ -258,7 +259,7 @@ enum class FlushMode { /** * Mark each page touching the region as cached. */ -void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached); +void RasterizerMarkRegionCached(Tegra::GPUVAddr start, u64 size, bool cached); /** * Flushes and invalidates any externally cached rasterizer resources touching the given virtual diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 7d745101fd..08140c83a3 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h @@ -11,7 +11,6 @@ #include #include "common/common_types.h" -#include "core/memory.h" namespace Tegra { diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 36629dd11d..f0e48a802a 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -6,6 +6,7 @@ #include "common/common_types.h" #include "video_core/gpu.h" +#include "video_core/memory_manager.h" struct ScreenInfo; @@ -25,14 +26,14 @@ public: virtual void FlushAll() = 0; /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory - virtual void FlushRegion(VAddr addr, u64 size) = 0; + virtual void FlushRegion(Tegra::GPUVAddr addr, u64 size) = 0; /// Notify rasterizer that any caches of the specified region should be invalidated - virtual void InvalidateRegion(VAddr addr, u64 size) = 0; + virtual void InvalidateRegion(Tegra::GPUVAddr addr, u64 size) = 0; /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory /// and invalidated - virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; + virtual void FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) = 0; /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0 virtual bool AccelerateDisplayTransfer(const void* config) { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 71612790be..bc93688771 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -150,9 +150,8 @@ std::pair RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, u64 size = end - start + 1; // Copy vertex array data - const VAddr data_addr{*memory_manager->GpuToCpuAddress(start)}; - res_cache.FlushRegion(data_addr, size, nullptr); - Memory::ReadBlock(data_addr, array_ptr, size); + res_cache.FlushRegion(start, size, nullptr); + Memory::ReadBlock(*memory_manager->GpuToCpuAddress(start), array_ptr, size); // Bind the vertex array to the buffer at the current offset. glBindVertexBuffer(index, stream_buffer->GetHandle(), buffer_offset, vertex_array.stride); @@ -519,17 +518,17 @@ void RasterizerOpenGL::FlushAll() { res_cache.FlushAll(); } -void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) { +void RasterizerOpenGL::FlushRegion(Tegra::GPUVAddr addr, u64 size) { MICROPROFILE_SCOPE(OpenGL_CacheManagement); res_cache.FlushRegion(addr, size); } -void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { +void RasterizerOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, u64 size) { MICROPROFILE_SCOPE(OpenGL_CacheManagement); res_cache.InvalidateRegion(addr, size, nullptr); } -void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { +void RasterizerOpenGL::FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) { MICROPROFILE_SCOPE(OpenGL_CacheManagement); res_cache.FlushRegion(addr, size); res_cache.InvalidateRegion(addr, size, nullptr); @@ -560,7 +559,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebu MICROPROFILE_SCOPE(OpenGL_CacheManagement); SurfaceParams src_params; - src_params.addr = framebuffer_addr; + src_params.cpu_addr = framebuffer_addr; src_params.width = std::min(framebuffer.width, pixel_stride); src_params.height = framebuffer.height; src_params.stride = pixel_stride; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 544714b953..9709e595e9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -11,6 +11,7 @@ #include #include "common/common_types.h" #include "video_core/engines/maxwell_3d.h" +#include "video_core/memory_manager.h" #include "video_core/rasterizer_interface.h" #include "video_core/renderer_opengl/gl_rasterizer_cache.h" #include "video_core/renderer_opengl/gl_resource_manager.h" @@ -29,9 +30,9 @@ public: void DrawArrays() override; void NotifyMaxwellRegisterChanged(u32 method) override; void FlushAll() override; - void FlushRegion(VAddr addr, u64 size) override; - void InvalidateRegion(VAddr addr, u64 size) override; - void FlushAndInvalidateRegion(VAddr addr, u64 size) override; + void FlushRegion(Tegra::GPUVAddr addr, u64 size) override; + void InvalidateRegion(Tegra::GPUVAddr addr, u64 size) override; + void FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) override; bool AccelerateDisplayTransfer(const void* config) override; bool AccelerateTextureCopy(const void* config) override; bool AccelerateFill(const void* config) override; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index ced648c123..d139d51e92 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -83,26 +83,30 @@ static u16 GetResolutionScaleFactor() { } template -void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, VAddr base, VAddr start, - VAddr end) { +void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::GPUVAddr base, + Tegra::GPUVAddr start, Tegra::GPUVAddr end) { constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / 8; constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); + const auto& gpu = Core::System::GetInstance().GPU(); if (morton_to_gl) { auto data = Tegra::Texture::UnswizzleTexture( - base, SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, - block_height); + *gpu.memory_manager->GpuToCpuAddress(base), + SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); std::memcpy(gl_buffer, data.data(), data.size()); } else { // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check // the configuration for this and perform more generic un/swizzle LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); - VideoCore::MortonCopyPixels128(stride, height, bytes_per_pixel, gl_bytes_per_pixel, - Memory::GetPointer(base), gl_buffer, morton_to_gl); + VideoCore::MortonCopyPixels128( + stride, height, bytes_per_pixel, gl_bytes_per_pixel, + Memory::GetPointer(*gpu.memory_manager->GpuToCpuAddress(base)), gl_buffer, + morton_to_gl); } } -static constexpr std::array morton_to_gl_fns = { MortonCopy, MortonCopy, @@ -110,7 +114,8 @@ static constexpr std::array, MortonCopy, }; -static constexpr std::array gl_to_morton_fns = { MortonCopy, @@ -219,9 +224,9 @@ SurfaceParams SurfaceParams::FromInterval(SurfaceInterval interval) const { SurfaceParams params = *this; const u32 tiled_size = is_tiled ? 8 : 1; const u64 stride_tiled_bytes = BytesInPixels(stride * tiled_size); - VAddr aligned_start = + Tegra::GPUVAddr aligned_start = addr + Common::AlignDown(boost::icl::first(interval) - addr, stride_tiled_bytes); - VAddr aligned_end = + Tegra::GPUVAddr aligned_end = addr + Common::AlignUp(boost::icl::last_next(interval) - addr, stride_tiled_bytes); if (aligned_end - aligned_start > stride_tiled_bytes) { @@ -342,6 +347,13 @@ bool SurfaceParams::CanTexCopy(const SurfaceParams& texcopy_params) const { return FromInterval(texcopy_params.GetInterval()).GetInterval() == texcopy_params.GetInterval(); } +VAddr SurfaceParams::GetCpuAddr() const { + // When this function is used, only cpu_addr or (GPU) addr should be set, not both + ASSERT(!(cpu_addr && addr)); + const auto& gpu = Core::System::GetInstance().GPU(); + return cpu_addr.get_value_or(*gpu.memory_manager->GpuToCpuAddress(addr)); +} + bool CachedSurface::CanFill(const SurfaceParams& dest_surface, SurfaceInterval fill_interval) const { if (type == SurfaceType::Fill && IsRegionValid(fill_interval) && @@ -456,10 +468,10 @@ void RasterizerCacheOpenGL::CopySurface(const Surface& src_surface, const Surfac } MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); -void CachedSurface::LoadGLBuffer(VAddr load_start, VAddr load_end) { +void CachedSurface::LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr load_end) { ASSERT(type != SurfaceType::Fill); - u8* const texture_src_data = Memory::GetPointer(addr); + u8* const texture_src_data = Memory::GetPointer(GetCpuAddr()); if (texture_src_data == nullptr) return; @@ -485,8 +497,8 @@ void CachedSurface::LoadGLBuffer(VAddr load_start, VAddr load_end) { } MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64)); -void CachedSurface::FlushGLBuffer(VAddr flush_start, VAddr flush_end) { - u8* const dst_buffer = Memory::GetPointer(addr); +void CachedSurface::FlushGLBuffer(Tegra::GPUVAddr flush_start, Tegra::GPUVAddr flush_end) { + u8* const dst_buffer = Memory::GetPointer(GetCpuAddr()); if (dst_buffer == nullptr) return; @@ -1028,7 +1040,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu auto& gpu = Core::System::GetInstance().GPU(); SurfaceParams params; - params.addr = *gpu.memory_manager->GpuToCpuAddress(config.tic.Address()); + params.addr = config.tic.Address(); params.width = config.tic.Width(); params.height = config.tic.Height(); params.is_tiled = config.tic.IsTiled(); @@ -1045,7 +1057,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu params.block_height = config.tic.BlockHeight(); } else { // Use the texture-provided stride value if the texture isn't tiled. - params.stride = params.PixelsInBytes(config.tic.Pitch()); + params.stride = static_cast(params.PixelsInBytes(config.tic.Pitch())); } params.UpdateParams(); @@ -1073,7 +1085,6 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle& viewport) { const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; - const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; const auto& config = regs.rt[0]; // TODO(bunnei): This is hard corded to use just the first render buffer @@ -1106,7 +1117,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; SurfaceParams depth_params = color_params; - color_params.addr = *memory_manager->GpuToCpuAddress(config.Address()); + color_params.addr = config.Address(); color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format); color_params.UpdateParams(); @@ -1222,7 +1233,8 @@ void RasterizerCacheOpenGL::DuplicateSurface(const Surface& src_surface, } } -void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, VAddr addr, u64 size) { +void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, Tegra::GPUVAddr addr, + u64 size) { if (size == 0) return; @@ -1261,7 +1273,7 @@ void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, VAddr addr, } } -void RasterizerCacheOpenGL::FlushRegion(VAddr addr, u64 size, Surface flush_surface) { +void RasterizerCacheOpenGL::FlushRegion(Tegra::GPUVAddr addr, u64 size, Surface flush_surface) { if (size == 0) return; @@ -1297,7 +1309,8 @@ void RasterizerCacheOpenGL::FlushAll() { FlushRegion(0, Kernel::VMManager::MAX_ADDRESS); } -void RasterizerCacheOpenGL::InvalidateRegion(VAddr addr, u64 size, const Surface& region_owner) { +void RasterizerCacheOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, u64 size, + const Surface& region_owner) { if (size == 0) return; @@ -1390,7 +1403,7 @@ void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) { surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}}); } -void RasterizerCacheOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { +void RasterizerCacheOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) { const u64 num_pages = ((addr + size - 1) >> Memory::PAGE_BITS) - (addr >> Memory::PAGE_BITS) + 1; const u64 page_start = addr >> Memory::PAGE_BITS; @@ -1406,8 +1419,10 @@ void RasterizerCacheOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int del const auto interval = pair.first & pages_interval; const int count = pair.second; - const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS; - const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS; + const Tegra::GPUVAddr interval_start_addr = boost::icl::first(interval) + << Memory::PAGE_BITS; + const Tegra::GPUVAddr interval_end_addr = boost::icl::last_next(interval) + << Memory::PAGE_BITS; const u64 interval_size = interval_end_addr - interval_start_addr; if (delta > 0 && count == delta) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index bf0fabb293..5f77f4e610 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -17,12 +17,14 @@ #ifdef __GNUC__ #pragma GCC diagnostic pop #endif +#include #include #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/math_util.h" #include "video_core/gpu.h" +#include "video_core/memory_manager.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/textures/texture.h" @@ -30,9 +32,9 @@ struct CachedSurface; using Surface = std::shared_ptr; using SurfaceSet = std::set; -using SurfaceRegions = boost::icl::interval_set; -using SurfaceMap = boost::icl::interval_map; -using SurfaceCache = boost::icl::interval_map; +using SurfaceRegions = boost::icl::interval_set; +using SurfaceMap = boost::icl::interval_map; +using SurfaceCache = boost::icl::interval_map; using SurfaceInterval = SurfaceCache::interval_type; static_assert(std::is_same() && @@ -277,6 +279,8 @@ struct SurfaceParams { return pixels * GetFormatBpp(pixel_format) / CHAR_BIT; } + VAddr GetCpuAddr() const; + bool ExactMatch(const SurfaceParams& other_surface) const; bool CanSubRect(const SurfaceParams& sub_surface) const; bool CanExpand(const SurfaceParams& expanded_surface) const; @@ -285,8 +289,9 @@ struct SurfaceParams { MathUtil::Rectangle GetSubRect(const SurfaceParams& sub_surface) const; MathUtil::Rectangle GetScaledSubRect(const SurfaceParams& sub_surface) const; - VAddr addr = 0; - VAddr end = 0; + Tegra::GPUVAddr addr = 0; + Tegra::GPUVAddr end = 0; + boost::optional cpu_addr; u64 size = 0; u32 width = 0; @@ -332,8 +337,8 @@ struct CachedSurface : SurfaceParams { size_t gl_buffer_size = 0; // Read/Write data in Switch memory to/from gl_buffer - void LoadGLBuffer(VAddr load_start, VAddr load_end); - void FlushGLBuffer(VAddr flush_start, VAddr flush_end); + void LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr load_end); + void FlushGLBuffer(Tegra::GPUVAddr flush_start, Tegra::GPUVAddr flush_end); // Upload/Download data in gl_buffer in/to this surface's texture void UploadGLTexture(const MathUtil::Rectangle& rect, GLuint read_fb_handle, @@ -381,10 +386,10 @@ public: SurfaceRect_Tuple GetTexCopySurface(const SurfaceParams& params); /// Write any cached resources overlapping the region back to memory (if dirty) - void FlushRegion(VAddr addr, u64 size, Surface flush_surface = nullptr); + void FlushRegion(Tegra::GPUVAddr addr, u64 size, Surface flush_surface = nullptr); /// Mark region as being invalidated by region_owner (nullptr if Switch memory) - void InvalidateRegion(VAddr addr, u64 size, const Surface& region_owner); + void InvalidateRegion(Tegra::GPUVAddr addr, u64 size, const Surface& region_owner); /// Flush all cached resources tracked by this cache manager void FlushAll(); @@ -393,7 +398,7 @@ private: void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface); /// Update surface's texture for given region when necessary - void ValidateSurface(const Surface& surface, VAddr addr, u64 size); + void ValidateSurface(const Surface& surface, Tegra::GPUVAddr addr, u64 size); /// Create a new surface Surface CreateSurface(const SurfaceParams& params); @@ -405,7 +410,7 @@ private: void UnregisterSurface(const Surface& surface); /// Increase/decrease the number of surface in pages touching the specified region - void UpdatePagesCachedCount(VAddr addr, u64 size, int delta); + void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta); SurfaceCache surface_cache; PageMap cached_pages; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index baff2c7af9..a266e21cf3 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -152,7 +152,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf screen_info.display_texture = screen_info.texture.resource.handle; screen_info.display_texcoords = MathUtil::Rectangle(0.f, 0.f, 1.f, 1.f); - Rasterizer()->FlushRegion(framebuffer_addr, size_in_bytes); + Memory::RasterizerFlushVirtualRegion(framebuffer_addr, size_in_bytes, + Memory::FlushMode::Flush); VideoCore::MortonCopyPixels128(framebuffer.width, framebuffer.height, bytes_per_pixel, 4, Memory::GetPointer(framebuffer_addr), diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index e0509f0ce2..9c3ae875c2 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -4,6 +4,7 @@ #include #include "common/assert.h" +#include "core/memory.h" #include "video_core/textures/decoders.h" #include "video_core/textures/texture.h" From bc0f1896fc1092bdc66fb66f977163de08672f01 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 23 Apr 2018 23:45:47 -0400 Subject: [PATCH 46/74] gl_rasterizer_cache: Handle compressed texture sizes. --- .../renderer_opengl/gl_rasterizer_cache.cpp | 37 ++++++------- .../renderer_opengl/gl_rasterizer_cache.h | 52 +++++++++++++++++-- 2 files changed, 65 insertions(+), 24 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index d139d51e92..e1ad00feb8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -41,18 +41,15 @@ struct FormatTuple { GLenum format; GLenum type; bool compressed; - // How many pixels in the original texture are equivalent to one pixel in the compressed - // texture. - u32 compression_factor; }; static constexpr std::array tex_format_tuples = {{ - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false, 1}, // ABGR8 - {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false, 1}, // B5G6R5 - {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false, 1}, // A2B10G10R10 - {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT1 - {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT23 - {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT45 + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8 + {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false}, // B5G6R5 + {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false}, // A2B10G10R10 + {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT1 + {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23 + {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45 }}; static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { @@ -476,7 +473,7 @@ void CachedSurface::LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr loa return; if (gl_buffer == nullptr) { - gl_buffer_size = width * height * GetGLBytesPerPixel(pixel_format); + gl_buffer_size = GetActualWidth() * GetActualHeight() * GetGLBytesPerPixel(pixel_format); gl_buffer.reset(new u8[gl_buffer_size]); } @@ -491,8 +488,9 @@ void CachedSurface::LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr loa std::memcpy(&gl_buffer[start_offset], texture_src_data + start_offset, bytes_per_pixel * width * height); } else { - morton_to_gl_fns[static_cast(pixel_format)]( - stride, block_height, height, &gl_buffer[0], addr, load_start, load_end); + morton_to_gl_fns[static_cast(pixel_format)](GetActualWidth(), block_height, + GetActualHeight(), &gl_buffer[0], addr, + load_start, load_end); } } @@ -548,7 +546,8 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle& rect, GLuint MICROPROFILE_SCOPE(OpenGL_TextureUL); - ASSERT(gl_buffer_size == width * height * GetGLBytesPerPixel(pixel_format)); + ASSERT(gl_buffer_size == + GetActualWidth() * GetActualHeight() * GetGLBytesPerPixel(pixel_format)); // Load data from memory to the surface GLint x0 = static_cast(rect.left); @@ -583,11 +582,9 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle& rect, GLuint glActiveTexture(GL_TEXTURE0); if (tuple.compressed) { glCompressedTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, - static_cast(rect.GetWidth()), - static_cast(rect.GetHeight()), 0, - rect.GetWidth() * rect.GetHeight() * - GetGLBytesPerPixel(pixel_format) / tuple.compression_factor, - &gl_buffer[buffer_offset]); + static_cast(rect.GetWidth() * GetCompresssionFactor()), + static_cast(rect.GetHeight() * GetCompresssionFactor()), 0, + size, &gl_buffer[buffer_offset]); } else { glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast(rect.GetWidth()), static_cast(rect.GetHeight()), tuple.format, tuple.type, @@ -1041,10 +1038,10 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu SurfaceParams params; params.addr = config.tic.Address(); - params.width = config.tic.Width(); - params.height = config.tic.Height(); params.is_tiled = config.tic.IsTiled(); params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format); + params.width = config.tic.Width() / params.GetCompresssionFactor(); + params.height = config.tic.Height() / params.GetCompresssionFactor(); // TODO(Subv): Different types per component are not supported. ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() && diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 5f77f4e610..08858bab43 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -84,23 +84,49 @@ struct SurfaceParams { Invalid = 4, }; - static constexpr unsigned int GetFormatBpp(PixelFormat format) { + /** + * Gets the compression factor for the specified PixelFormat. This applies to just the + * "compressed width" and "compressed height", not the overall compression factor of a + * compressed image. This is used for maintaining proper surface sizes for compressed texture + * formats. + */ + static constexpr u32 GetCompresssionFactor(PixelFormat format) { if (format == PixelFormat::Invalid) return 0; - constexpr std::array bpp_table = { + constexpr std::array compression_factor_table = {{ + 1, // ABGR8 + 1, // B5G6R5 + 1, // A2B10G10R10 + 4, // DXT1 + 4, // DXT23 + 4, // DXT45 + }}; + + ASSERT(static_cast(format) < compression_factor_table.size()); + return compression_factor_table[static_cast(format)]; + } + u32 GetCompresssionFactor() const { + return GetCompresssionFactor(pixel_format); + } + + static constexpr u32 GetFormatBpp(PixelFormat format) { + if (format == PixelFormat::Invalid) + return 0; + + constexpr std::array bpp_table = {{ 32, // ABGR8 16, // B5G6R5 32, // A2B10G10R10 64, // DXT1 128, // DXT23 128, // DXT45 - }; + }}; ASSERT(static_cast(format) < bpp_table.size()); return bpp_table[static_cast(format)]; } - unsigned int GetFormatBpp() const { + u32 GetFormatBpp() const { return GetFormatBpp(pixel_format); } @@ -255,6 +281,24 @@ struct SurfaceParams { // Returns the region of the biggest valid rectange within interval SurfaceInterval GetCopyableInterval(const Surface& src_surface) const; + /** + * Gets the actual width (in pixels) of the surface. This is provided because `width` is used + * for tracking the surface region in memory, which may be compressed for certain formats. In + * this scenario, `width` is actually the compressed width. + */ + u32 GetActualWidth() const { + return width * GetCompresssionFactor(); + } + + /** + * Gets the actual height (in pixels) of the surface. This is provided because `height` is used + * for tracking the surface region in memory, which may be compressed for certain formats. In + * this scenario, `height` is actually the compressed height. + */ + u32 GetActualHeight() const { + return height * GetCompresssionFactor(); + } + u32 GetScaledWidth() const { return width * res_scale; } From fbb3cd110c598003bf58a2aca5be489b5f3fb772 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 24 Apr 2018 00:46:51 -0400 Subject: [PATCH 47/74] gl_rasterizer_cache: Add a function for finding framebuffer GPU address. --- .../renderer_opengl/gl_rasterizer.cpp | 1 + .../renderer_opengl/gl_rasterizer_cache.cpp | 27 +++++++++++++++++++ .../renderer_opengl/gl_rasterizer_cache.h | 3 +++ 3 files changed, 31 insertions(+) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index bc93688771..b457b1fbe1 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -560,6 +560,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebu SurfaceParams src_params; src_params.cpu_addr = framebuffer_addr; + src_params.addr = res_cache.TryFindFramebufferGpuAddress(framebuffer_addr).get_value_or(0); src_params.width = std::min(framebuffer.width, pixel_stride); src_params.height = framebuffer.height; src_params.stride = pixel_stride; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index e1ad00feb8..b924f1b8e4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -954,6 +954,33 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, ScaleMatc return surface; } +boost::optional RasterizerCacheOpenGL::TryFindFramebufferGpuAddress( + VAddr cpu_addr) const { + // Tries to find the GPU address of a framebuffer based on the CPU address. This is because + // final output framebuffers are specified by CPU address, but internally our GPU cache uses GPU + // addresses. We iterate through all cached framebuffers, and compare their starting CPU address + // to the one provided. This is obviously not great, and won't work if the framebuffer overlaps + // surfaces. + + std::vector gpu_addresses; + for (const auto& pair : surface_cache) { + for (const auto& surface : pair.second) { + const VAddr surface_cpu_addr = surface->GetCpuAddr(); + if (cpu_addr >= surface_cpu_addr && cpu_addr < (surface_cpu_addr + surface->size)) { + ASSERT_MSG(cpu_addr == surface_cpu_addr, "overlapping surfaces are unsupported"); + gpu_addresses.push_back(surface->addr); + } + } + } + + if (gpu_addresses.empty()) { + return {}; + } + + ASSERT_MSG(gpu_addresses.size() == 1, ">1 surface is unsupported"); + return gpu_addresses[0]; +} + SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams& params, ScaleMatch match_res_scale, bool load_if_create) { diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 08858bab43..dfddcce909 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -411,6 +411,9 @@ public: Surface GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale, bool load_if_create); + /// Tries to find a framebuffer GPU address based on the provided CPU address + boost::optional TryFindFramebufferGpuAddress(VAddr cpu_addr) const; + /// Attempt to find a subrect (resolution scaled) of a surface, otherwise loads a texture from /// Switch memory to OpenGL and caches it (if not already cached) SurfaceRect_Tuple GetSurfaceSubRect(const SurfaceParams& params, ScaleMatch match_res_scale, From 9022d926eb8553f382e215c8b005b7a45358e87c Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 24 Apr 2018 14:45:15 -0400 Subject: [PATCH 48/74] gl_rasterizer_cache: Use new logger. --- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index b924f1b8e4..9348b0297b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -94,7 +94,7 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra:: } else { // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check // the configuration for this and perform more generic un/swizzle - LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); + NGLOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); VideoCore::MortonCopyPixels128( stride, height, bytes_per_pixel, gl_bytes_per_pixel, Memory::GetPointer(*gpu.memory_manager->GpuToCpuAddress(base)), gl_buffer, @@ -1112,7 +1112,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( const auto& config = regs.rt[0]; // TODO(bunnei): This is hard corded to use just the first render buffer - LOG_WARNING(Render_OpenGL, "hard-coded for render target 0!"); + NGLOG_WARNING(Render_OpenGL, "hard-coded for render target 0!"); // update resolution_scale_factor and reset cache if changed // TODO (bunnei): This code was ported as-is from Citra, and is technically not thread-safe. We @@ -1157,8 +1157,8 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( // Make sure that framebuffers don't overlap if both color and depth are being used if (using_color_fb && using_depth_fb && boost::icl::length(color_vp_interval & depth_vp_interval)) { - LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; " - "overlapping framebuffers not supported!"); + NGLOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; " + "overlapping framebuffers not supported!"); using_depth_fb = false; } From 0a023cfb4ff5631520ad8d4409dcf8e2a103fd98 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 24 Apr 2018 15:30:22 -0400 Subject: [PATCH 49/74] gl_rasterizer_cache: Use GPU PAGE_BITS/SIZE, not CPU. --- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 9348b0297b..aef1c59794 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1428,9 +1428,9 @@ void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) { } void RasterizerCacheOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) { - const u64 num_pages = - ((addr + size - 1) >> Memory::PAGE_BITS) - (addr >> Memory::PAGE_BITS) + 1; - const u64 page_start = addr >> Memory::PAGE_BITS; + const u64 num_pages = ((addr + size - 1) >> Tegra::MemoryManager::PAGE_BITS) - + (addr >> Tegra::MemoryManager::PAGE_BITS) + 1; + const u64 page_start = addr >> Tegra::MemoryManager::PAGE_BITS; const u64 page_end = page_start + num_pages; // Interval maps will erase segments if count reaches 0, so if delta is negative we have to @@ -1444,9 +1444,9 @@ void RasterizerCacheOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 siz const int count = pair.second; const Tegra::GPUVAddr interval_start_addr = boost::icl::first(interval) - << Memory::PAGE_BITS; + << Tegra::MemoryManager::PAGE_BITS; const Tegra::GPUVAddr interval_end_addr = boost::icl::last_next(interval) - << Memory::PAGE_BITS; + << Tegra::MemoryManager::PAGE_BITS; const u64 interval_size = interval_end_addr - interval_start_addr; if (delta > 0 && count == delta) From f1a4a004fb8423091b48ceffdbd1e696372d4dc4 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 24 Apr 2018 18:01:06 -0400 Subject: [PATCH 50/74] gl_rasterizer_cache: Use CHAR_BIT for bpp conversions instead of 8. --- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 6 +++--- src/video_core/renderer_opengl/gl_rasterizer_cache.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index aef1c59794..501d15e982 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -82,7 +82,7 @@ static u16 GetResolutionScaleFactor() { template void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::GPUVAddr base, Tegra::GPUVAddr start, Tegra::GPUVAddr end) { - constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / 8; + constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / CHAR_BIT; constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); const auto& gpu = Core::System::GetInstance().GPU(); @@ -358,9 +358,9 @@ bool CachedSurface::CanFill(const SurfaceParams& dest_surface, boost::icl::last_next(fill_interval) <= end && // dest_surface is within our fill range dest_surface.FromInterval(fill_interval).GetInterval() == fill_interval) { // make sure interval is a rectangle in dest surface - if (fill_size * 8 != dest_surface.GetFormatBpp()) { + if (fill_size * CHAR_BIT != dest_surface.GetFormatBpp()) { // Check if bits repeat for our fill_size - const u32 dest_bytes_per_pixel = std::max(dest_surface.GetFormatBpp() / 8, 1u); + const u32 dest_bytes_per_pixel = std::max(dest_surface.GetFormatBpp() / CHAR_BIT, 1u); std::vector fill_test(fill_size * dest_bytes_per_pixel); for (u32 i = 0; i < dest_bytes_per_pixel; ++i) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index dfddcce909..55f1bdee80 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -374,7 +374,7 @@ struct CachedSurface : SurfaceParams { if (format == PixelFormat::Invalid) return 0; - return SurfaceParams::GetFormatBpp(format) / 8; + return SurfaceParams::GetFormatBpp(format) / CHAR_BIT; } std::unique_ptr gl_buffer; From c30cd898fc122d1277583c5165d622e323faad07 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 24 Apr 2018 19:44:09 -0400 Subject: [PATCH 51/74] renderer_opengl: Use correct byte order for framebuffer pixel format ABGR8. --- src/video_core/renderer_opengl/renderer_opengl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index a266e21cf3..5ca9821b74 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -270,10 +270,9 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, GLint internal_format; switch (framebuffer.pixel_format) { case Tegra::FramebufferConfig::PixelFormat::ABGR8: - // Use RGBA8 and swap in the fragment shader internal_format = GL_RGBA; texture.gl_format = GL_RGBA; - texture.gl_type = GL_UNSIGNED_INT_8_8_8_8; + texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; gl_framebuffer_data.resize(texture.width * texture.height * 4); break; default: From 0369ee72484c42983185d8d50fe6db13607fb599 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 24 Apr 2018 22:42:54 -0500 Subject: [PATCH 52/74] Shaders: Added decodings for the FSET instructions. --- src/video_core/engines/shader_bytecode.h | 37 +++++++++++++++---- .../renderer_opengl/gl_shader_decompiler.cpp | 2 +- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 5a006aee52..6cae6ff45a 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -214,6 +214,20 @@ union Instruction { BitField<56, 1, u64> neg_b; } fsetp; + union { + BitField<39, 3, u64> pred39; + BitField<42, 1, u64> neg_pred; + BitField<43, 1, u64> neg_a; + BitField<44, 1, u64> abs_b; + BitField<45, 2, PredOperation> op; + BitField<48, 4, PredCondition> cond; + BitField<53, 1, u64> neg_b; + BitField<54, 1, u64> abs_a; + BitField<52, 1, u64> bf; + BitField<55, 1, u64> ftz; + BitField<56, 1, u64> neg_imm; + } fset; + BitField<61, 1, u64> is_b_imm; BitField<60, 1, u64> is_b_gpr; BitField<59, 1, u64> is_c_gpr; @@ -272,6 +286,9 @@ public: FSETP_C, // Set Predicate FSETP_R, FSETP_IMM, + FSET_C, + FSET_R, + FSET_IMM, ISETP_C, ISETP_IMM, ISETP_R, @@ -283,8 +300,9 @@ public: Ffma, Flow, Memory, - FloatPredicate, - IntegerPredicate, + FloatSet, + FloatSetPredicate, + IntegerSetPredicate, Unknown, }; @@ -417,12 +435,15 @@ private: INST("0100110000101---", Id::SHR_C, Type::Arithmetic, "SHR_C"), INST("0101110000101---", Id::SHR_R, Type::Arithmetic, "SHR_R"), INST("0011100-00101---", Id::SHR_IMM, Type::Arithmetic, "SHR_IMM"), - INST("010010111011----", Id::FSETP_C, Type::FloatPredicate, "FSETP_C"), - INST("010110111011----", Id::FSETP_R, Type::FloatPredicate, "FSETP_R"), - INST("0011011-1011----", Id::FSETP_IMM, Type::FloatPredicate, "FSETP_IMM"), - INST("010010110110----", Id::ISETP_C, Type::IntegerPredicate, "ISETP_C"), - INST("010110110110----", Id::ISETP_R, Type::IntegerPredicate, "ISETP_R"), - INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerPredicate, "ISETP_IMM"), + INST("01011000--------", Id::FSET_R, Type::FloatSet, "FSET_R"), + INST("0100100---------", Id::FSET_C, Type::FloatSet, "FSET_C"), + INST("0011000---------", Id::FSET_IMM, Type::FloatSet, "FSET_IMM"), + INST("010010111011----", Id::FSETP_C, Type::FloatSetPredicate, "FSETP_C"), + INST("010110111011----", Id::FSETP_R, Type::FloatSetPredicate, "FSETP_R"), + INST("0011011-1011----", Id::FSETP_IMM, Type::FloatSetPredicate, "FSETP_IMM"), + INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"), + INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"), + INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"), }; #undef INST std::stable_sort(table.begin(), table.end(), [](const auto& a, const auto& b) { diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 0864243958..896b6cd2cc 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -519,7 +519,7 @@ private: } break; } - case OpCode::Type::FloatPredicate: { + case OpCode::Type::FloatSetPredicate: { std::string op_a = instr.fsetp.neg_a ? "-" : ""; op_a += GetRegister(instr.gpr8); From 2ba4e2263c6e0e4d7bbb92cb203fdeb758a2637e Mon Sep 17 00:00:00 2001 From: mailwl Date: Tue, 24 Apr 2018 18:08:23 +0300 Subject: [PATCH 53/74] Service/PCTL: convert to module, add services, stub PCTL::CreateServiceWithoutInitialize and IParentalControlService::Initialize, required by Kirby Star Allies --- src/core/CMakeLists.txt | 4 +- .../service/pctl/{pctl_a.cpp => module.cpp} | 37 ++++++++++++++----- src/core/hle/service/pctl/module.h | 28 ++++++++++++++ src/core/hle/service/pctl/pctl.cpp | 11 ++++-- src/core/hle/service/pctl/pctl.h | 8 ++-- src/core/hle/service/pctl/pctl_a.h | 20 ---------- src/core/hle/service/service.cpp | 2 +- 7 files changed, 71 insertions(+), 39 deletions(-) rename src/core/hle/service/pctl/{pctl_a.cpp => module.cpp} (83%) create mode 100644 src/core/hle/service/pctl/module.h delete mode 100644 src/core/hle/service/pctl/pctl_a.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index b3807c2040..f4be926e4d 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -181,10 +181,10 @@ add_library(core STATIC hle/service/nvflinger/buffer_queue.h hle/service/nvflinger/nvflinger.cpp hle/service/nvflinger/nvflinger.h + hle/service/pctl/module.cpp + hle/service/pctl/module.h hle/service/pctl/pctl.cpp hle/service/pctl/pctl.h - hle/service/pctl/pctl_a.cpp - hle/service/pctl/pctl_a.h hle/service/service.cpp hle/service/service.h hle/service/set/set.cpp diff --git a/src/core/hle/service/pctl/pctl_a.cpp b/src/core/hle/service/pctl/module.cpp similarity index 83% rename from src/core/hle/service/pctl/pctl_a.cpp rename to src/core/hle/service/pctl/module.cpp index 24a6cf3103..dd20d5ae79 100644 --- a/src/core/hle/service/pctl/pctl_a.cpp +++ b/src/core/hle/service/pctl/module.cpp @@ -4,7 +4,8 @@ #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/service/pctl/pctl_a.h" +#include "core/hle/service/pctl/module.h" +#include "core/hle/service/pctl/pctl.h" namespace Service::PCTL { @@ -12,7 +13,7 @@ class IParentalControlService final : public ServiceFramework(); NGLOG_DEBUG(Service_PCTL, "called"); } -PCTL_A::PCTL_A() : ServiceFramework("pctl:a") { - static const FunctionInfo functions[] = { - {0, &PCTL_A::CreateService, "CreateService"}, - {1, nullptr, "CreateServiceWithoutInitialize"}, - }; - RegisterHandlers(functions); +void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface(); + NGLOG_DEBUG(Service_PCTL, "called"); +} + +Module::Interface::Interface(std::shared_ptr module, const char* name) + : ServiceFramework(name), module(std::move(module)) {} + +void InstallInterfaces(SM::ServiceManager& service_manager) { + auto module = std::make_shared(); + std::make_shared(module, "pctl")->InstallAsService(service_manager); + std::make_shared(module, "pctl:a")->InstallAsService(service_manager); + std::make_shared(module, "pctl:r")->InstallAsService(service_manager); + std::make_shared(module, "pctl:s")->InstallAsService(service_manager); } } // namespace Service::PCTL diff --git a/src/core/hle/service/pctl/module.h b/src/core/hle/service/pctl/module.h new file mode 100644 index 0000000000..68da628a83 --- /dev/null +++ b/src/core/hle/service/pctl/module.h @@ -0,0 +1,28 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::PCTL { + +class Module final { +public: + class Interface : public ServiceFramework { + public: + Interface(std::shared_ptr module, const char* name); + + void CreateService(Kernel::HLERequestContext& ctx); + void CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx); + + protected: + std::shared_ptr module; + }; +}; + +/// Registers all PCTL services with the specified service manager. +void InstallInterfaces(SM::ServiceManager& service_manager); + +} // namespace Service::PCTL diff --git a/src/core/hle/service/pctl/pctl.cpp b/src/core/hle/service/pctl/pctl.cpp index 6ee81866d4..de2741d66a 100644 --- a/src/core/hle/service/pctl/pctl.cpp +++ b/src/core/hle/service/pctl/pctl.cpp @@ -3,12 +3,15 @@ // Refer to the license.txt file included. #include "core/hle/service/pctl/pctl.h" -#include "core/hle/service/pctl/pctl_a.h" namespace Service::PCTL { -void InstallInterfaces(SM::ServiceManager& service_manager) { - std::make_shared()->InstallAsService(service_manager); +PCTL::PCTL(std::shared_ptr module, const char* name) + : Module::Interface(std::move(module), name) { + static const FunctionInfo functions[] = { + {0, &PCTL::CreateService, "CreateService"}, + {1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"}, + }; + RegisterHandlers(functions); } - } // namespace Service::PCTL diff --git a/src/core/hle/service/pctl/pctl.h b/src/core/hle/service/pctl/pctl.h index f0a84b1159..8ddf691287 100644 --- a/src/core/hle/service/pctl/pctl.h +++ b/src/core/hle/service/pctl/pctl.h @@ -4,11 +4,13 @@ #pragma once -#include "core/hle/service/service.h" +#include "core/hle/service/pctl/module.h" namespace Service::PCTL { -/// Registers all PCTL services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager); +class PCTL final : public Module::Interface { +public: + explicit PCTL(std::shared_ptr module, const char* name); +}; } // namespace Service::PCTL diff --git a/src/core/hle/service/pctl/pctl_a.h b/src/core/hle/service/pctl/pctl_a.h deleted file mode 100644 index 09ed82e1b0..0000000000 --- a/src/core/hle/service/pctl/pctl_a.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "core/hle/service/service.h" - -namespace Service::PCTL { - -class PCTL_A final : public ServiceFramework { -public: - PCTL_A(); - ~PCTL_A() = default; - -private: - void CreateService(Kernel::HLERequestContext& ctx); -}; - -} // namespace Service::PCTL diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 5817819fee..a85c406beb 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -29,7 +29,7 @@ #include "core/hle/service/nifm/nifm.h" #include "core/hle/service/ns/ns.h" #include "core/hle/service/nvdrv/nvdrv.h" -#include "core/hle/service/pctl/pctl.h" +#include "core/hle/service/pctl/module.h" #include "core/hle/service/service.h" #include "core/hle/service/set/settings.h" #include "core/hle/service/sm/controller.h" From b7551e457bacf972789136cfdc1e90c5a2e0dae6 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 25 Apr 2018 08:13:44 -0400 Subject: [PATCH 54/74] video-core: Move logging macros over to new fmt-capable ones --- src/video_core/command_processor.cpp | 12 +++++++----- src/video_core/engines/maxwell_3d.cpp | 4 ++-- src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 +++--- src/video_core/renderer_opengl/renderer_opengl.cpp | 10 +++++----- src/video_core/video_core.cpp | 6 +++--- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 2c04daba34..f6a88f031b 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -31,12 +31,14 @@ enum class BufferMethods { }; void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) { - LOG_WARNING(HW_GPU, "Processing method %08X on subchannel %u value %08X remaining params %u", - method, subchannel, value, remaining_params); + NGLOG_WARNING(HW_GPU, + "Processing method {:08X} on subchannel {} value " + "{:08X} remaining params {}", + method, subchannel, value, remaining_params); if (method == static_cast(BufferMethods::SetGraphMacroEntry)) { // Prepare to upload a new macro, reset the upload counter. - LOG_DEBUG(HW_GPU, "Uploading GPU macro %08X", value); + NGLOG_DEBUG(HW_GPU, "Uploading GPU macro {:08X}", value); current_macro_entry = value; current_macro_code.clear(); return; @@ -58,7 +60,7 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) if (method == static_cast(BufferMethods::BindObject)) { // Bind the current subchannel to the desired engine id. - LOG_DEBUG(HW_GPU, "Binding subchannel %u to engine %u", subchannel, value); + NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); ASSERT(bound_engines.find(subchannel) == bound_engines.end()); bound_engines[subchannel] = static_cast(value); return; @@ -66,7 +68,7 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) if (method < static_cast(BufferMethods::CountBufferMethods)) { // TODO(Subv): Research and implement these methods. - LOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented"); + NGLOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented"); return; } diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 4e9aed380f..2acbb9cd66 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -186,8 +186,8 @@ void Maxwell3D::ProcessQueryGet() { } void Maxwell3D::DrawArrays() { - LOG_DEBUG(HW_GPU, "called, topology=%d, count=%d", regs.draw.topology.Value(), - regs.vertex_buffer.count); + NGLOG_DEBUG(HW_GPU, "called, topology={}, count={}", + static_cast(regs.draw.topology.Value()), regs.vertex_buffer.count); ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?"); auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b457b1fbe1..9b3542e107 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -116,7 +116,7 @@ RasterizerOpenGL::RasterizerOpenGL() { glEnable(GL_BLEND); - LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!"); + NGLOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!"); } RasterizerOpenGL::~RasterizerOpenGL() { @@ -252,8 +252,8 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { break; } default: - LOG_CRITICAL(HW_GPU, "Unimplemented shader index=%d, enable=%d, offset=0x%08X", index, - shader_config.enable.Value(), shader_config.offset); + NGLOG_CRITICAL(HW_GPU, "Unimplemented shader index={}, enable={}, offset={:#010X}", + index, shader_config.enable.Value(), shader_config.offset); UNREACHABLE(); } diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 5ca9821b74..77d1692f40 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -302,8 +302,8 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, right = texcoords.left; } else { // Other transformations are unsupported - LOG_CRITICAL(Render_OpenGL, "Unsupported framebuffer_transform_flags=%d", - framebuffer_transform_flags); + NGLOG_CRITICAL(Render_OpenGL, "Unsupported framebuffer_transform_flags={}", + static_cast(framebuffer_transform_flags)); UNIMPLEMENTED(); } } @@ -428,9 +428,9 @@ bool RendererOpenGL::Init() { const char* gpu_vendor{reinterpret_cast(glGetString(GL_VENDOR))}; const char* gpu_model{reinterpret_cast(glGetString(GL_RENDERER))}; - LOG_INFO(Render_OpenGL, "GL_VERSION: %s", gl_version); - LOG_INFO(Render_OpenGL, "GL_VENDOR: %s", gpu_vendor); - LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", gpu_model); + NGLOG_INFO(Render_OpenGL, "GL_VERSION: {}", gl_version); + NGLOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor); + NGLOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model); Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Vendor", gpu_vendor); Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Model", gpu_model); diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 289140f31a..89dc8ed1e6 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -24,9 +24,9 @@ bool Init(EmuWindow* emu_window) { g_renderer = std::make_unique(); g_renderer->SetWindow(g_emu_window); if (g_renderer->Init()) { - LOG_DEBUG(Render, "initialized OK"); + NGLOG_DEBUG(Render, "initialized OK"); } else { - LOG_CRITICAL(Render, "initialization failed !"); + NGLOG_CRITICAL(Render, "initialization failed !"); return false; } return true; @@ -36,7 +36,7 @@ bool Init(EmuWindow* emu_window) { void Shutdown() { g_renderer.reset(); - LOG_DEBUG(Render, "shutdown OK"); + NGLOG_DEBUG(Render, "shutdown OK"); } } // namespace VideoCore From 59dae03dbe4bd0dfe715f012be3a848ffe91177e Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 25 Apr 2018 12:03:54 -0400 Subject: [PATCH 55/74] core/memory: Move logging macros over to new fmt-capable ones While we're at it, correct addresses to print all 64 bits where applicable, which were holdovers from citra. --- src/core/memory.cpp | 46 +++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index ff0420c562..9c207b74ae 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -39,8 +39,8 @@ PageTable* GetCurrentPageTable() { } static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, PageType type) { - LOG_DEBUG(HW_Memory, "Mapping %p onto %016" PRIX64 "-%016" PRIX64, memory, base * PAGE_SIZE, - (base + size) * PAGE_SIZE); + NGLOG_DEBUG(HW_Memory, "Mapping {} onto {:016X}-{:016X}", fmt::ptr(memory), base * PAGE_SIZE, + (base + size) * PAGE_SIZE); RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, FlushMode::FlushAndInvalidate); @@ -169,7 +169,7 @@ T Read(const VAddr vaddr) { PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; switch (type) { case PageType::Unmapped: - LOG_ERROR(HW_Memory, "unmapped Read%lu @ 0x%08X", sizeof(T) * 8, vaddr); + NGLOG_ERROR(HW_Memory, "Unmapped Read{} @ {:#010X}", sizeof(T) * 8, vaddr); return 0; case PageType::Memory: ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); @@ -201,8 +201,8 @@ void Write(const VAddr vaddr, const T data) { PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; switch (type) { case PageType::Unmapped: - LOG_ERROR(HW_Memory, "unmapped Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, - vaddr); + NGLOG_ERROR(HW_Memory, "Unmapped Write{} {:#010X} @ {:#018X}", sizeof(data) * 8, (u32)data, + vaddr); return; case PageType::Memory: ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); @@ -251,7 +251,7 @@ u8* GetPointer(const VAddr vaddr) { return GetPointerFromVMA(vaddr); } - LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x%08x", vaddr); + NGLOG_ERROR(HW_Memory, "Unknown GetPointer @ {:#018X}", vaddr); return nullptr; } @@ -288,13 +288,12 @@ u8* GetPhysicalPointer(PAddr address) { }); if (area == std::end(memory_areas)) { - LOG_ERROR(HW_Memory, "unknown GetPhysicalPointer @ 0x%016" PRIX64, address); + NGLOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ {:#018X}", address); return nullptr; } if (area->paddr_base == IO_AREA_PADDR) { - LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr=0x%016" PRIX64, - address); + NGLOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:018X}", address); return nullptr; } @@ -341,9 +340,9 @@ void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) Core::System::GetInstance().GPU().memory_manager->GpuToCpuAddress(gpu_addr); // The GPU <-> CPU virtual memory mapping is not 1:1 if (!maybe_vaddr) { - LOG_ERROR(HW_Memory, - "Trying to flush a cached region to an invalid physical address %08X", - gpu_addr); + NGLOG_ERROR(HW_Memory, + "Trying to flush a cached region to an invalid physical address {:016X}", + gpu_addr); continue; } VAddr vaddr = *maybe_vaddr; @@ -477,8 +476,9 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_ switch (page_table.attributes[page_index]) { case PageType::Unmapped: { - LOG_ERROR(HW_Memory, "unmapped ReadBlock @ 0x%08X (start address = 0x%08X, size = %zu)", - current_vaddr, src_addr, size); + NGLOG_ERROR(HW_Memory, + "Unmapped ReadBlock @ {:#018X} (start address = {:#018X}, size = {})", + current_vaddr, src_addr, size); std::memset(dest_buffer, 0, copy_amount); break; } @@ -540,9 +540,9 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi switch (page_table.attributes[page_index]) { case PageType::Unmapped: { - LOG_ERROR(HW_Memory, - "unmapped WriteBlock @ 0x%08X (start address = 0x%08X, size = %zu)", - current_vaddr, dest_addr, size); + NGLOG_ERROR(HW_Memory, + "Unmapped WriteBlock @ {:#018X} (start address = {:#018X}, size = {})", + current_vaddr, dest_addr, size); break; } case PageType::Memory: { @@ -588,8 +588,9 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const size switch (page_table.attributes[page_index]) { case PageType::Unmapped: { - LOG_ERROR(HW_Memory, "unmapped ZeroBlock @ 0x%08X (start address = 0x%08X, size = %zu)", - current_vaddr, dest_addr, size); + NGLOG_ERROR(HW_Memory, + "Unmapped ZeroBlock @ {:#018X} (start address = {#:018X}, size = {})", + current_vaddr, dest_addr, size); break; } case PageType::Memory: { @@ -628,8 +629,9 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, switch (page_table.attributes[page_index]) { case PageType::Unmapped: { - LOG_ERROR(HW_Memory, "unmapped CopyBlock @ 0x%08X (start address = 0x%08X, size = %zu)", - current_vaddr, src_addr, size); + NGLOG_ERROR(HW_Memory, + "Unmapped CopyBlock @ {:#018X} (start address = {:#018X}, size = {})", + current_vaddr, src_addr, size); ZeroBlock(process, dest_addr, copy_amount); break; } @@ -678,7 +680,7 @@ boost::optional TryVirtualToPhysicalAddress(const VAddr addr) { PAddr VirtualToPhysicalAddress(const VAddr addr) { auto paddr = TryVirtualToPhysicalAddress(addr); if (!paddr) { - LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%016" PRIX64, addr); + NGLOG_ERROR(HW_Memory, "Unknown virtual address @ {:#018X}", addr); // To help with debugging, set bit on address so that it's obviously invalid. return addr | 0x80000000; } From 6d0078004543567fb9d50c9c5e26540432ea7868 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 25 Apr 2018 12:17:25 -0400 Subject: [PATCH 56/74] core/memory: Amend address widths in asserts Addresses are 64-bit, these formatting specifiers are simply holdovers from citra. Adjust them to be the correct width. --- src/core/memory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 9c207b74ae..d7c0080fa6 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -172,7 +172,7 @@ T Read(const VAddr vaddr) { NGLOG_ERROR(HW_Memory, "Unmapped Read{} @ {:#010X}", sizeof(T) * 8, vaddr); return 0; case PageType::Memory: - ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); + ASSERT_MSG(false, "Mapped memory page without a pointer @ %016" PRIX64, vaddr); break; case PageType::RasterizerCachedMemory: { RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush); @@ -205,7 +205,7 @@ void Write(const VAddr vaddr, const T data) { vaddr); return; case PageType::Memory: - ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); + ASSERT_MSG(false, "Mapped memory page without a pointer @ %016" PRIX64, vaddr); break; case PageType::RasterizerCachedMemory: { RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Invalidate); From 5aafc83cc9ce67b2ee052c22934e63793f37c9a7 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 25 Apr 2018 11:37:33 -0400 Subject: [PATCH 57/74] file-sys: Move logging macros over to the new fmt-capable ones --- src/core/file_sys/disk_filesystem.cpp | 21 ++++++------ src/core/file_sys/filesystem.cpp | 6 ++-- src/core/file_sys/partition_filesystem.cpp | 3 +- src/core/file_sys/program_metadata.cpp | 39 +++++++++++----------- src/core/file_sys/romfs_factory.cpp | 6 ++-- src/core/file_sys/romfs_filesystem.cpp | 38 ++++++++++----------- src/core/file_sys/savedata_factory.cpp | 4 +-- src/core/file_sys/sdmc_factory.cpp | 5 ++- 8 files changed, 58 insertions(+), 64 deletions(-) diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp index 4d00249fa8..8aa0e0aa41 100644 --- a/src/core/file_sys/disk_filesystem.cpp +++ b/src/core/file_sys/disk_filesystem.cpp @@ -80,19 +80,19 @@ ResultCode Disk_FileSystem::RenameFile(const std::string& src_path, } ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode Disk_FileSystem::DeleteDirectoryRecursively(const Path& path) const { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); std::string full_path = base_directory + path; if (size == 0) { @@ -107,7 +107,7 @@ ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const return RESULT_SUCCESS; } - LOG_ERROR(Service_FS, "Too large file"); + NGLOG_ERROR(Service_FS, "Too large file"); // TODO(Subv): Find out the correct error code return ResultCode(-1); } @@ -120,13 +120,13 @@ ResultCode Disk_FileSystem::CreateDirectory(const std::string& path) const { return RESULT_SUCCESS; } - LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating %s", full_path.c_str()); + NGLOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", full_path); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); // TODO(wwylele): Use correct error code return ResultCode(-1); } @@ -146,7 +146,7 @@ ResultVal> Disk_FileSystem::OpenDirectory( } u64 Disk_FileSystem::GetFreeSpaceSize() const { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); return 0; } @@ -163,14 +163,14 @@ ResultVal Disk_FileSystem::GetEntryType(const std::string& p } ResultVal Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const { - LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length); + NGLOG_TRACE(Service_FS, "called offset={}, length={}", offset, length); file->Seek(offset, SEEK_SET); return MakeResult(file->ReadBytes(buffer, length)); } ResultVal Disk_Storage::Write(const u64 offset, const size_t length, const bool flush, const u8* buffer) const { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); file->Seek(offset, SEEK_SET); size_t written = file->WriteBytes(buffer, length); if (flush) { @@ -204,8 +204,7 @@ u64 Disk_Directory::Read(const u64 count, Entry* entries) { const std::string& filename = file.virtualName; Entry& entry = entries[entries_read]; - LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size, - file.isDirectory); + NGLOG_TRACE(Service_FS, "File {}: size={} dir={}", filename, file.size, file.isDirectory); // TODO(Link Mauve): use a proper conversion to UTF-16. for (size_t j = 0; j < FILENAME_LENGTH; ++j) { diff --git a/src/core/file_sys/filesystem.cpp b/src/core/file_sys/filesystem.cpp index 82fdb3c464..87083878b8 100644 --- a/src/core/file_sys/filesystem.cpp +++ b/src/core/file_sys/filesystem.cpp @@ -71,7 +71,7 @@ std::string Path::AsString() const { case Binary: default: // TODO(yuriks): Add assert - LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); + NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); return {}; } } @@ -87,7 +87,7 @@ std::u16string Path::AsU16Str() const { case Invalid: case Binary: // TODO(yuriks): Add assert - LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!"); + NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!"); return {}; } @@ -115,7 +115,7 @@ std::vector Path::AsBinary() const { case Invalid: default: // TODO(yuriks): Add assert - LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); + NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); return {}; } } diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp index 4a58a92916..808254ecc8 100644 --- a/src/core/file_sys/partition_filesystem.cpp +++ b/src/core/file_sys/partition_filesystem.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include #include #include "common/file_util.h" #include "common/logging/log.h" @@ -40,7 +39,7 @@ Loader::ResultStatus PartitionFilesystem::Load(const std::string& file_path, siz Loader::ResultStatus result = Load(file_data); if (result != Loader::ResultStatus::Success) - LOG_ERROR(Service_FS, "Failed to load PFS from file %s!", file_path.c_str()); + NGLOG_ERROR(Service_FS, "Failed to load PFS from file {}!", file_path); return result; } diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index a6dcebcc34..1f5ded514d 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include #include "common/file_util.h" #include "common/logging/log.h" #include "core/file_sys/program_metadata.h" @@ -22,7 +21,7 @@ Loader::ResultStatus ProgramMetadata::Load(const std::string& file_path) { Loader::ResultStatus result = Load(file_data); if (result != Loader::ResultStatus::Success) - LOG_ERROR(Service_FS, "Failed to load NPDM from file %s!", file_path.c_str()); + NGLOG_ERROR(Service_FS, "Failed to load NPDM from file {}!", file_path); return result; } @@ -77,14 +76,14 @@ u64 ProgramMetadata::GetFilesystemPermissions() const { } void ProgramMetadata::Print() const { - LOG_DEBUG(Service_FS, "Magic: %.4s", npdm_header.magic.data()); - LOG_DEBUG(Service_FS, "Main thread priority: 0x%02x", npdm_header.main_thread_priority); - LOG_DEBUG(Service_FS, "Main thread core: %u", npdm_header.main_thread_cpu); - LOG_DEBUG(Service_FS, "Main thread stack size: 0x%x bytes", npdm_header.main_stack_size); - LOG_DEBUG(Service_FS, "Process category: %u", npdm_header.process_category); - LOG_DEBUG(Service_FS, "Flags: %02x", npdm_header.flags); - LOG_DEBUG(Service_FS, " > 64-bit instructions: %s", - npdm_header.has_64_bit_instructions ? "YES" : "NO"); + NGLOG_DEBUG(Service_FS, "Magic: {:.4}", npdm_header.magic.data()); + NGLOG_DEBUG(Service_FS, "Main thread priority: {:#04X}", npdm_header.main_thread_priority); + NGLOG_DEBUG(Service_FS, "Main thread core: {}", npdm_header.main_thread_cpu); + NGLOG_DEBUG(Service_FS, "Main thread stack size: {:#X} bytes", npdm_header.main_stack_size); + NGLOG_DEBUG(Service_FS, "Process category: {}", npdm_header.process_category); + NGLOG_DEBUG(Service_FS, "Flags: {:02X}", npdm_header.flags); + NGLOG_DEBUG(Service_FS, " > 64-bit instructions: {}", + npdm_header.has_64_bit_instructions ? "YES" : "NO"); auto address_space = "Unknown"; switch (npdm_header.address_space_type) { @@ -96,19 +95,19 @@ void ProgramMetadata::Print() const { break; } - LOG_DEBUG(Service_FS, " > Address space: %s\n", address_space); + NGLOG_DEBUG(Service_FS, " > Address space: {}\n", address_space); // Begin ACID printing (potential perms, signed) - LOG_DEBUG(Service_FS, "Magic: %.4s", acid_header.magic.data()); - LOG_DEBUG(Service_FS, "Flags: %02x", acid_header.flags); - LOG_DEBUG(Service_FS, " > Is Retail: %s", acid_header.is_retail ? "YES" : "NO"); - LOG_DEBUG(Service_FS, "Title ID Min: %016" PRIX64, acid_header.title_id_min); - LOG_DEBUG(Service_FS, "Title ID Max: %016" PRIX64, acid_header.title_id_max); - LOG_DEBUG(Service_FS, "Filesystem Access: %016" PRIX64 "\n", acid_file_access.permissions); + NGLOG_DEBUG(Service_FS, "Magic: {:.4}", acid_header.magic.data()); + NGLOG_DEBUG(Service_FS, "Flags: {:02X}", acid_header.flags); + NGLOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO"); + NGLOG_DEBUG(Service_FS, "Title ID Min: {:016X}", acid_header.title_id_min); + NGLOG_DEBUG(Service_FS, "Title ID Max: {:016X}", acid_header.title_id_max); + NGLOG_DEBUG(Service_FS, "Filesystem Access: {:016X}\n", acid_file_access.permissions); // Begin ACI0 printing (actual perms, unsigned) - LOG_DEBUG(Service_FS, "Magic: %.4s", aci_header.magic.data()); - LOG_DEBUG(Service_FS, "Title ID: %016" PRIX64, aci_header.title_id); - LOG_DEBUG(Service_FS, "Filesystem Access: %016" PRIX64 "\n", aci_file_access.permissions); + NGLOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data()); + NGLOG_DEBUG(Service_FS, "Title ID: {:016X}", aci_header.title_id); + NGLOG_DEBUG(Service_FS, "Filesystem Access: {:016X}\n", aci_file_access.permissions); } } // namespace FileSys diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index b214279489..dc7591acab 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp @@ -14,7 +14,7 @@ namespace FileSys { RomFS_Factory::RomFS_Factory(Loader::AppLoader& app_loader) { // Load the RomFS from the app if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) { - LOG_ERROR(Service_FS, "Unable to read RomFS!"); + NGLOG_ERROR(Service_FS, "Unable to read RomFS!"); } } @@ -24,13 +24,13 @@ ResultVal> RomFS_Factory::Open(const Path& pa } ResultCode RomFS_Factory::Format(const Path& path) { - LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str()); + NGLOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName()); // TODO(bunnei): Find the right error code for this return ResultCode(-1); } ResultVal RomFS_Factory::GetFormatInfo(const Path& path) const { - LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); + NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); // TODO(bunnei): Find the right error code for this return ResultCode(-1); } diff --git a/src/core/file_sys/romfs_filesystem.cpp b/src/core/file_sys/romfs_filesystem.cpp index b9982e6fae..8e2bce6872 100644 --- a/src/core/file_sys/romfs_filesystem.cpp +++ b/src/core/file_sys/romfs_filesystem.cpp @@ -21,74 +21,72 @@ ResultVal> RomFS_FileSystem::OpenFile(const std: } ResultCode RomFS_FileSystem::DeleteFile(const std::string& path) const { - LOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive (%s).", - GetName().c_str()); + NGLOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive ({}).", GetName()); // TODO(bunnei): Use correct error code return ResultCode(-1); } ResultCode RomFS_FileSystem::RenameFile(const std::string& src_path, const std::string& dest_path) const { - LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive (%s).", - GetName().c_str()); + NGLOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).", + GetName()); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode RomFS_FileSystem::DeleteDirectory(const Path& path) const { - LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive (%s).", - GetName().c_str()); + NGLOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).", + GetName()); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode RomFS_FileSystem::DeleteDirectoryRecursively(const Path& path) const { - LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive (%s).", - GetName().c_str()); + NGLOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).", + GetName()); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode RomFS_FileSystem::CreateFile(const std::string& path, u64 size) const { - LOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive (%s).", - GetName().c_str()); + NGLOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive ({}).", GetName()); // TODO(bunnei): Use correct error code return ResultCode(-1); } ResultCode RomFS_FileSystem::CreateDirectory(const std::string& path) const { - LOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive (%s).", - GetName().c_str()); + NGLOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive ({}).", + GetName()); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode RomFS_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const { - LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive (%s).", - GetName().c_str()); + NGLOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).", + GetName()); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultVal> RomFS_FileSystem::OpenDirectory( const std::string& path) const { - LOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive"); + NGLOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive"); return MakeResult>(std::make_unique()); } u64 RomFS_FileSystem::GetFreeSpaceSize() const { - LOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive"); + NGLOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive"); return 0; } ResultVal RomFS_FileSystem::GetEntryType(const std::string& path) const { - LOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path %s).", path.c_str()); + NGLOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path {}).", path); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultVal RomFS_Storage::Read(const u64 offset, const size_t length, u8* buffer) const { - LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length); + NGLOG_TRACE(Service_FS, "called offset={}, length={}", offset, length); romfs_file->Seek(data_offset + offset, SEEK_SET); size_t read_length = (size_t)std::min((u64)length, data_size - offset); @@ -97,7 +95,7 @@ ResultVal RomFS_Storage::Read(const u64 offset, const size_t length, u8* ResultVal RomFS_Storage::Write(const u64 offset, const size_t length, const bool flush, const u8* buffer) const { - LOG_ERROR(Service_FS, "Attempted to write to ROMFS file"); + NGLOG_ERROR(Service_FS, "Attempted to write to ROMFS file"); // TODO(Subv): Find error code return MakeResult(0); } @@ -107,7 +105,7 @@ u64 RomFS_Storage::GetSize() const { } bool RomFS_Storage::SetSize(const u64 size) const { - LOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file"); + NGLOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file"); return false; } diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 14868fed2d..a1491f5421 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -30,7 +30,7 @@ ResultVal> SaveData_Factory::Open(const Path& } ResultCode SaveData_Factory::Format(const Path& path) { - LOG_WARNING(Service_FS, "Format archive %s", GetName().c_str()); + NGLOG_WARNING(Service_FS, "Format archive {}", GetName()); // Create the save data directory. if (!FileUtil::CreateFullPath(GetFullPath())) { // TODO(Subv): Find the correct error code. @@ -41,7 +41,7 @@ ResultCode SaveData_Factory::Format(const Path& path) { } ResultVal SaveData_Factory::GetFormatInfo(const Path& path) const { - LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); + NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); // TODO(bunnei): Find the right error code for this return ResultCode(-1); } diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index 00e80d2a7f..59ac3e0be8 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include #include #include "common/common_types.h" #include "common/logging/log.h" @@ -26,13 +25,13 @@ ResultVal> SDMC_Factory::Open(const Path& pat } ResultCode SDMC_Factory::Format(const Path& path) { - LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str()); + NGLOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName()); // TODO(Subv): Find the right error code for this return ResultCode(-1); } ResultVal SDMC_Factory::GetFormatInfo(const Path& path) const { - LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); + NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); // TODO(bunnei): Find the right error code for this return ResultCode(-1); } From 3f78a61f09c97a115828521f3ee99c3db83c29f8 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 25 Apr 2018 11:54:48 -0400 Subject: [PATCH 58/74] file-sys: convert a StringFromFormat call into fmt::format in GetFullPath() Lessens the amount to read and gets rid of the PRIX64 macro, allowing us to use a single string for the whole path, making it easier to read. --- src/core/file_sys/savedata_factory.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index a1491f5421..c1be8fee4b 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -2,11 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include #include #include "common/common_types.h" #include "common/logging/log.h" -#include "common/string_util.h" #include "core/core.h" #include "core/file_sys/disk_filesystem.h" #include "core/file_sys/savedata_factory.h" @@ -50,8 +48,7 @@ std::string SaveData_Factory::GetFullPath() const { u64 title_id = Core::CurrentProcess()->program_id; // TODO(Subv): Somehow obtain this value. u32 user = 0; - return Common::StringFromFormat("%ssave/%016" PRIX64 "/%08X/", nand_directory.c_str(), title_id, - user); + return fmt::format("{}save/{:016X}/{:08X}/", nand_directory, title_id, user); } } // namespace FileSys From e2f2a49d2d0fd51ef83ef94fa2e93a2829d974e5 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 19:45:14 -0500 Subject: [PATCH 59/74] GPU: Corrected the upper bound of the PFIFO method ids in the command processor. --- src/video_core/command_processor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index f6a88f031b..26792a2bf0 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -27,7 +27,7 @@ enum class BufferMethods { SetGraphMacroCode = 0x45, SetGraphMacroCodeArg = 0x46, SetGraphMacroEntry = 0x47, - CountBufferMethods = 0x100, + CountBufferMethods = 0x40, }; void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) { From a994446b6ec776c9383e8b13c45eeb461405adff Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 20:01:29 -0500 Subject: [PATCH 60/74] GPU: Move the Maxwell3D macro uploading code to the inside of the Maxwell3D processor. It doesn't belong in the PFIFO handler. --- src/video_core/command_processor.cpp | 25 ------------------------- src/video_core/engines/maxwell_3d.cpp | 14 ++++++++++---- src/video_core/engines/maxwell_3d.h | 17 +++++++++++++---- src/video_core/gpu.h | 7 ------- 4 files changed, 23 insertions(+), 40 deletions(-) diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 26792a2bf0..2eaece2988 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -24,9 +24,6 @@ namespace Tegra { enum class BufferMethods { BindObject = 0, - SetGraphMacroCode = 0x45, - SetGraphMacroCodeArg = 0x46, - SetGraphMacroEntry = 0x47, CountBufferMethods = 0x40, }; @@ -36,28 +33,6 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) "{:08X} remaining params {}", method, subchannel, value, remaining_params); - if (method == static_cast(BufferMethods::SetGraphMacroEntry)) { - // Prepare to upload a new macro, reset the upload counter. - NGLOG_DEBUG(HW_GPU, "Uploading GPU macro {:08X}", value); - current_macro_entry = value; - current_macro_code.clear(); - return; - } - - if (method == static_cast(BufferMethods::SetGraphMacroCodeArg)) { - // Append a new code word to the current macro. - current_macro_code.push_back(value); - - // There are no more params remaining, submit the code to the 3D engine. - if (remaining_params == 0) { - maxwell_3d->SubmitMacroCode(current_macro_entry, std::move(current_macro_code)); - current_macro_entry = InvalidGraphMacroEntry; - current_macro_code.clear(); - } - - return; - } - if (method == static_cast(BufferMethods::BindObject)) { // Bind the current subchannel to the desired engine id. NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2acbb9cd66..bc40f8d988 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -22,10 +22,6 @@ constexpr u32 MacroRegistersStart = 0xE00; Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager), macro_interpreter(*this) {} -void Maxwell3D::SubmitMacroCode(u32 entry, std::vector code) { - uploaded_macros[entry * 2 + MacroRegistersStart] = std::move(code); -} - void Maxwell3D::CallMacroMethod(u32 method, std::vector parameters) { auto macro_code = uploaded_macros.find(method); // The requested macro must have been uploaded already. @@ -75,6 +71,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { regs.reg_array[method] = value; switch (method) { + case MAXWELL3D_REG_INDEX(macros.data): { + ProcessMacroUpload(value); + break; + } case MAXWELL3D_REG_INDEX(code_address.code_address_high): case MAXWELL3D_REG_INDEX(code_address.code_address_low): { // Note: For some reason games (like Puyo Puyo Tetris) seem to write 0 to the CODE_ADDRESS @@ -141,6 +141,12 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { } } +void Maxwell3D::ProcessMacroUpload(u32 data) { + // Store the uploaded macro code to interpret them when they're called. + auto& macro = uploaded_macros[regs.macros.entry * 2 + MacroRegistersStart]; + macro.push_back(data); +} + void Maxwell3D::ProcessQueryGet() { GPUVAddr sequence_address = regs.query.QueryAddress(); // Since the sequence address is given as a GPU VAddr, we have to convert it to an application diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index a022665eba..8edc3cd384 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -322,7 +322,15 @@ public: union { struct { - INSERT_PADDING_WORDS(0x200); + INSERT_PADDING_WORDS(0x45); + + struct { + INSERT_PADDING_WORDS(1); + u32 data; + u32 entry; + } macros; + + INSERT_PADDING_WORDS(0x1B8); struct { u32 address_high; @@ -637,9 +645,6 @@ public: /// Write the value to the register identified by method. void WriteReg(u32 method, u32 value, u32 remaining_params); - /// Uploads the code for a GPU macro program associated with the specified entry. - void SubmitMacroCode(u32 entry, std::vector code); - /// Returns a list of enabled textures for the specified shader stage. std::vector GetStageTextures(Regs::ShaderStage stage) const; @@ -670,6 +675,9 @@ private: */ void CallMacroMethod(u32 method, std::vector parameters); + /// Handles writes to the macro uploading registers. + void ProcessMacroUpload(u32 data); + /// Handles a write to the QUERY_GET register. void ProcessQueryGet(); @@ -687,6 +695,7 @@ private: static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ "Field " #field_name " has invalid position") +ASSERT_REG_POSITION(macros, 0x45); ASSERT_REG_POSITION(rt, 0x200); ASSERT_REG_POSITION(viewport_transform[0], 0x280); ASSERT_REG_POSITION(viewport, 0x300); diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 2888daedcf..7afa6aaefa 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -86,8 +86,6 @@ public: } private: - static constexpr u32 InvalidGraphMacroEntry = 0xFFFFFFFF; - /// Writes a single register in the engine bound to the specified subchannel void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params); @@ -100,11 +98,6 @@ private: std::unique_ptr fermi_2d; /// Compute engine std::unique_ptr maxwell_compute; - - /// Entry of the macro that is currently being uploaded - u32 current_macro_entry = InvalidGraphMacroEntry; - /// Code being uploaded for the current macro - std::vector current_macro_code; }; } // namespace Tegra From c16cfbbc6c062491d84a6bc9976027b7a7587fdb Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 20:03:50 -0500 Subject: [PATCH 61/74] GPU: Reduce the number of registers of Maxwell3D to 0xE00. The rest are just macro shim registers. --- src/video_core/engines/maxwell_3d.cpp | 6 +++--- src/video_core/engines/maxwell_3d.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index bc40f8d988..4306b894f7 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -33,9 +33,6 @@ void Maxwell3D::CallMacroMethod(u32 method, std::vector parameters) { } void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { - ASSERT_MSG(method < Regs::NUM_REGS, - "Invalid Maxwell3D register, increase the size of the Regs structure"); - auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); // It is an error to write to a register other than the current macro's ARG register before it @@ -64,6 +61,9 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { return; } + ASSERT_MSG(method < Regs::NUM_REGS, + "Invalid Maxwell3D register, increase the size of the Regs structure"); + if (debug_context) { debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr); } diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 8edc3cd384..5cf62fb016 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -31,7 +31,7 @@ public: /// Register structure of the Maxwell3D engine. /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. struct Regs { - static constexpr size_t NUM_REGS = 0xE36; + static constexpr size_t NUM_REGS = 0xE00; static constexpr size_t NumRenderTargets = 8; static constexpr size_t NumViewports = 16; @@ -613,7 +613,7 @@ public: u32 size[MaxShaderStage]; } tex_info_buffers; - INSERT_PADDING_WORDS(0x102); + INSERT_PADDING_WORDS(0xCC); }; std::array reg_array; }; From b1109931b9a92ce89635cb7c0c0c1c0c7e6866ed Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 20:12:40 -0500 Subject: [PATCH 62/74] GPU: Added boilerplate code for the Fermi2D engine --- src/video_core/engines/fermi_2d.cpp | 7 ++++++- src/video_core/engines/fermi_2d.h | 28 +++++++++++++++++++++++++++- src/video_core/gpu.cpp | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 7aab163dca..87634da216 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp @@ -7,7 +7,12 @@ namespace Tegra { namespace Engines { -void Fermi2D::WriteReg(u32 method, u32 value) {} +Fermi2D::Fermi2D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} + +void Fermi2D::WriteReg(u32 method, u32 value) { + ASSERT_MSG(method < Regs::NUM_REGS, + "Invalid Fermi2D register, increase the size of the Regs structure"); +} } // namespace Engines } // namespace Tegra diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 8967ddede0..a97f5bb28f 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h @@ -4,19 +4,45 @@ #pragma once +#include +#include "common/assert.h" +#include "common/common_funcs.h" #include "common/common_types.h" +#include "video_core/memory_manager.h" namespace Tegra { namespace Engines { +#define FERMI2D_REG_INDEX(field_name) \ + (offsetof(Tegra::Engines::Fermi2D::Regs, field_name) / sizeof(u32)) + class Fermi2D final { public: - Fermi2D() = default; + explicit Fermi2D(MemoryManager& memory_manager); ~Fermi2D() = default; /// Write the value to the register identified by method. void WriteReg(u32 method, u32 value); + + struct Regs { + static constexpr size_t NUM_REGS = 0x258; + + union { + struct { + INSERT_PADDING_WORDS(0x258); + }; + std::array reg_array; + }; + } regs{}; + + MemoryManager& memory_manager; }; +#define ASSERT_REG_POSITION(field_name, position) \ + static_assert(offsetof(Fermi2D::Regs, field_name) == position * 4, \ + "Field " #field_name " has invalid position") + +#undef ASSERT_REG_POSITION + } // namespace Engines } // namespace Tegra diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 9463cd5d66..351d217116 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -12,7 +12,7 @@ namespace Tegra { GPU::GPU() { memory_manager = std::make_unique(); maxwell_3d = std::make_unique(*memory_manager); - fermi_2d = std::make_unique(); + fermi_2d = std::make_unique(*memory_manager); maxwell_compute = std::make_unique(); } From 378c881427d34962461099ef3d55de871710b897 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 22:14:08 -0500 Subject: [PATCH 63/74] GPU: Added surface copy registers to Fermi2D --- src/video_core/engines/fermi_2d.h | 58 ++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index a97f5bb28f..78d06218f0 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h @@ -6,8 +6,10 @@ #include #include "common/assert.h" +#include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "video_core/gpu.h" #include "video_core/memory_manager.h" namespace Tegra { @@ -27,9 +29,59 @@ public: struct Regs { static constexpr size_t NUM_REGS = 0x258; + struct Surface { + RenderTargetFormat format; + BitField<0, 1, u32> linear; + union { + BitField<0, 4, u32> block_depth; + BitField<4, 4, u32> block_height; + BitField<8, 4, u32> block_width; + }; + u32 depth; + u32 layer; + u32 pitch; + u32 width; + u32 height; + u32 address_high; + u32 address_low; + + GPUVAddr Address() const { + return static_cast((static_cast(address_high) << 32) | + address_low); + } + }; + static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size"); + + enum class Operation : u32 { + SrcCopyAnd = 0, + ROPAnd = 1, + Blend = 2, + SrcCopy = 3, + ROP = 4, + SrcCopyPremult = 5, + BlendPremult = 6, + }; + union { struct { - INSERT_PADDING_WORDS(0x258); + INSERT_PADDING_WORDS(0x80); + + Surface dst; + + INSERT_PADDING_WORDS(2); + + Surface src; + + INSERT_PADDING_WORDS(0x15); + + Operation operation; + + INSERT_PADDING_WORDS(0x9); + + // TODO(Subv): This is only a guess. + u32 trigger; + + INSERT_PADDING_WORDS(0x1A3); }; std::array reg_array; }; @@ -42,6 +94,10 @@ public: static_assert(offsetof(Fermi2D::Regs, field_name) == position * 4, \ "Field " #field_name " has invalid position") +ASSERT_REG_POSITION(dst, 0x80); +ASSERT_REG_POSITION(src, 0x8C); +ASSERT_REG_POSITION(operation, 0xAB); +ASSERT_REG_POSITION(trigger, 0xB5); #undef ASSERT_REG_POSITION } // namespace Engines From a6da2b93c16fd09ef491606d9a0dc99b51f4186f Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 24 Apr 2018 21:57:10 -0500 Subject: [PATCH 64/74] GPU: Added a function to retrieve the bytes per pixel of the render target formats. --- src/video_core/gpu.cpp | 12 ++++++++++++ src/video_core/gpu.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 351d217116..9eb1439180 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -22,4 +22,16 @@ const Tegra::Engines::Maxwell3D& GPU::Get3DEngine() const { return *maxwell_3d; } +u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { + ASSERT(format != RenderTargetFormat::NONE); + + switch (format) { + case RenderTargetFormat::RGBA8_UNORM: + case RenderTargetFormat::RGB10_A2_UNORM: + return 4; + default: + UNIMPLEMENTED_MSG("Unimplemented render target format %u", static_cast(format)); + } +} + } // namespace Tegra diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 7afa6aaefa..f168a51712 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -21,6 +21,9 @@ enum class RenderTargetFormat : u32 { RGBA8_SRGB = 0xD6, }; +/// Returns the number of bytes per pixel of each rendertarget format. +u32 RenderTargetBytesPerPixel(RenderTargetFormat format); + class DebugContext; /** From 1dd4861d38b862724052a5db66067d77ede468d4 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 24 Apr 2018 21:58:45 -0500 Subject: [PATCH 65/74] GPU: Make the Textures::CopySwizzledData function accessible from the outside of the file. --- src/video_core/textures/decoders.cpp | 5 ++--- src/video_core/textures/decoders.h | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 9c3ae875c2..8b39b2bdfc 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -27,9 +27,8 @@ static u32 GetSwizzleOffset(u32 x, u32 y, u32 image_width, u32 bytes_per_pixel, return address; } -static void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, - u8* swizzled_data, u8* unswizzled_data, bool unswizzle, - u32 block_height) { +void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, + u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height) { u8* data_ptrs[2]; for (unsigned y = 0; y < height; ++y) { for (unsigned x = 0; x < width; ++x) { diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index a700911cf7..2562c4b060 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h @@ -17,6 +17,10 @@ namespace Texture { std::vector UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, u32 block_height = TICEntry::DefaultBlockHeight); +/// Copies texture data from a buffer and performs swizzling/unswizzling as necessary. +void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, + u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height); + /** * Decodes an unswizzled texture into a A8R8G8B8 texture. */ From 5ab597041f885ed552344ff890a0dff6a53c1f1e Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 24 Apr 2018 22:01:27 -0500 Subject: [PATCH 66/74] Memory: Added a missing shortcut for Memory::CopyBlock for the current process. --- src/core/memory.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index ff0420c562..9e5d1cd4bc 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -657,6 +657,10 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, } } +void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size) { + CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size); +} + boost::optional TryVirtualToPhysicalAddress(const VAddr addr) { if (addr == 0) { return 0; From 1740aa544408d32a5c904f40d92c6e06ace6d00a Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 25 Apr 2018 11:17:38 -0500 Subject: [PATCH 67/74] Shaders: Implemented the FSET instruction. This instruction is similar to the FSETP instruction, but it doesn't set a predicate, it sets the destination register to 1.0 if the condition holds, and 0 otherwise. --- .../renderer_opengl/gl_shader_decompiler.cpp | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 896b6cd2cc..3dffb205d1 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -570,6 +570,59 @@ private: } break; } + case OpCode::Type::FloatSet: { + std::string dest = GetRegister(instr.gpr0); + std::string op_a = instr.fset.neg_a ? "-" : ""; + op_a += GetRegister(instr.gpr8); + + if (instr.fset.abs_a) { + op_a = "abs(" + op_a + ')'; + } + + std::string op_b = instr.fset.neg_b ? "-" : ""; + + if (instr.is_b_imm) { + std::string imm = GetImmediate19(instr); + if (instr.fset.neg_imm) + op_b += "(-" + imm + ')'; + else + op_b += imm; + } else { + if (instr.is_b_gpr) { + op_b += GetRegister(instr.gpr20); + } else { + op_b += GetUniform(instr.uniform); + } + } + + if (instr.fset.abs_b) { + op_b = "abs(" + op_b + ")"; + } + + using Tegra::Shader::Pred; + ASSERT_MSG(instr.fset.pred39 == static_cast(Pred::UnusedIndex), + "Compound predicates are not implemented"); + + // The fset instruction sets a register to 1.0 if the condition is true, and to 0 + // otherwise. + using Tegra::Shader::PredCondition; + switch (instr.fset.cond) { + case PredCondition::LessThan: + SetDest(0, dest, "((" + op_a + ") < (" + op_b + ")) ? 1.0 : 0", 1, 1); + break; + case PredCondition::Equal: + SetDest(0, dest, "((" + op_a + ") == (" + op_b + ")) ? 1.0 : 0", 1, 1); + break; + case PredCondition::GreaterThan: + SetDest(0, dest, "((" + op_a + ") > (" + op_b + ")) ? 1.0 : 0", 1, 1); + break; + default: + NGLOG_CRITICAL(HW_GPU, "Unhandled predicate condition: {} (a: {}, b: {})", + static_cast(instr.fset.cond.Value()), op_a, op_b); + UNREACHABLE(); + } + break; + } default: { switch (opcode->GetId()) { case OpCode::Id::EXIT: { From e9ad8e9185a4ab7f29728dbaf131de328eefc4fc Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 25 Apr 2018 12:52:55 -0500 Subject: [PATCH 68/74] Shaders: Added bit decodings for the I2I instruction. --- src/video_core/engines/shader_bytecode.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 6cae6ff45a..f4d11fa5df 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -275,6 +275,9 @@ public: I2F_C, I2F_R, I2F_IMM, + I2I_C, + I2I_R, + I2I_IMM, LOP32I, MOV_C, MOV_R, @@ -427,6 +430,9 @@ private: INST("0100110010111---", Id::I2F_C, Type::Arithmetic, "I2F_C"), INST("0101110010111---", Id::I2F_R, Type::Arithmetic, "I2F_R"), INST("0011100-10111---", Id::I2F_IMM, Type::Arithmetic, "I2F_IMM"), + INST("0100110011100---", Id::I2I_C, Type::Arithmetic, "I2I_C"), + INST("0101110011100---", Id::I2I_R, Type::Arithmetic, "I2I_R"), + INST("01110001-1000---", Id::I2I_IMM, Type::Arithmetic, "I2I_IMM"), INST("000001----------", Id::LOP32I, Type::Arithmetic, "LOP32I"), INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), From 20d86d8a36dca4bf1b465193745a365c3ab9abcd Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 24 Apr 2018 22:00:40 -0500 Subject: [PATCH 69/74] GPU: Partially implemented the Fermi2D surface copy operation. The hardware allows for some rather complicated operations to be performed on the data during the copy, this is not implemented. Only same-format same-size raw copies are implemented for now. --- src/video_core/engines/fermi_2d.cpp | 54 +++++++++++++++++++++++++++++ src/video_core/engines/fermi_2d.h | 5 +++ 2 files changed, 59 insertions(+) diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 87634da216..9019f25045 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp @@ -2,7 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/memory.h" #include "video_core/engines/fermi_2d.h" +#include "video_core/textures/decoders.h" namespace Tegra { namespace Engines { @@ -12,6 +14,58 @@ Fermi2D::Fermi2D(MemoryManager& memory_manager) : memory_manager(memory_manager) void Fermi2D::WriteReg(u32 method, u32 value) { ASSERT_MSG(method < Regs::NUM_REGS, "Invalid Fermi2D register, increase the size of the Regs structure"); + + regs.reg_array[method] = value; + + switch (method) { + case FERMI2D_REG_INDEX(trigger): { + HandleSurfaceCopy(); + break; + } + } +} + +void Fermi2D::HandleSurfaceCopy() { + NGLOG_WARNING(HW_GPU, "Requested a surface copy with operation {}", + static_cast(regs.operation)); + + const GPUVAddr source = regs.src.Address(); + const GPUVAddr dest = regs.dst.Address(); + + // TODO(Subv): Only same-format and same-size copies are allowed for now. + ASSERT(regs.src.format == regs.dst.format); + ASSERT(regs.src.width * regs.src.height == regs.dst.width * regs.dst.height); + + // TODO(Subv): Only raw copies are implemented. + ASSERT(regs.operation == Regs::Operation::SrcCopy); + + const VAddr source_cpu = *memory_manager.GpuToCpuAddress(source); + const VAddr dest_cpu = *memory_manager.GpuToCpuAddress(dest); + + u32 src_bytes_per_pixel = RenderTargetBytesPerPixel(regs.src.format); + u32 dst_bytes_per_pixel = RenderTargetBytesPerPixel(regs.dst.format); + + if (regs.src.linear == regs.dst.linear) { + // If the input layout and the output layout are the same, just perform a raw copy. + Memory::CopyBlock(dest_cpu, source_cpu, + src_bytes_per_pixel * regs.dst.width * regs.dst.height); + return; + } + + u8* src_buffer = Memory::GetPointer(source_cpu); + u8* dst_buffer = Memory::GetPointer(dest_cpu); + + if (!regs.src.linear && regs.dst.linear) { + // If the input is tiled and the output is linear, deswizzle the input and copy it over. + Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel, + dst_bytes_per_pixel, src_buffer, dst_buffer, true, + regs.src.block_height); + } else { + // If the input is linear and the output is tiled, swizzle the input and copy it over. + Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel, + dst_bytes_per_pixel, dst_buffer, src_buffer, false, + regs.dst.block_height); + } } } // namespace Engines diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 78d06218f0..0c5b413cca 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h @@ -88,6 +88,11 @@ public: } regs{}; MemoryManager& memory_manager; + +private: + /// Performs the copy from the source surface to the destination surface as configured in the + /// registers. + void HandleSurfaceCopy(); }; #define ASSERT_REG_POSITION(field_name, position) \ From 40dee76c57e76438d06fc282d1f8a632933d5816 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 25 Apr 2018 19:11:22 -0400 Subject: [PATCH 70/74] kernel: Migrate logging macros to fmt-compatible ones --- src/core/hle/kernel/handle_table.cpp | 4 +- src/core/hle/kernel/hle_ipc.cpp | 5 +- src/core/hle/kernel/process.cpp | 8 +- src/core/hle/kernel/resource_limit.cpp | 6 +- src/core/hle/kernel/scheduler.cpp | 6 +- src/core/hle/kernel/server_session.cpp | 6 +- src/core/hle/kernel/shared_memory.cpp | 15 +-- src/core/hle/kernel/svc.cpp | 138 ++++++++++++------------- src/core/hle/kernel/thread.cpp | 15 +-- src/core/hle/kernel/timer.cpp | 4 +- src/core/hle/kernel/vm_manager.cpp | 8 +- 11 files changed, 109 insertions(+), 106 deletions(-) diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 822449cd55..f7a9920d8d 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -26,7 +26,7 @@ ResultVal HandleTable::Create(SharedPtr obj) { u16 slot = next_free_slot; if (slot >= generations.size()) { - LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); + NGLOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); return ERR_OUT_OF_HANDLES; } next_free_slot = generations[slot]; @@ -48,7 +48,7 @@ ResultVal HandleTable::Create(SharedPtr obj) { ResultVal HandleTable::Duplicate(Handle handle) { SharedPtr object = GetGeneric(handle); if (object == nullptr) { - LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle); + NGLOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle); return ERR_INVALID_HANDLE; } return Create(std::move(object)); diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index bef4f15f53..aa6ca10261 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -118,7 +118,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { std::make_shared(rp.PopRaw()); } else { if (Session()->IsDomain()) - LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!"); + NGLOG_WARNING(IPC, "Domain request has no DomainMessageHeader!"); } } @@ -270,7 +270,8 @@ size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size) const { const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()}; const size_t buffer_size{GetWriteBufferSize()}; if (size > buffer_size) { - LOG_CRITICAL(Core, "size (%016zx) is greater than buffer_size (%016zx)", size, buffer_size); + NGLOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size, + buffer_size); size = buffer_size; // TODO(bunnei): This needs to be HW tested } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 2cffec198a..751a0524d0 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -54,7 +54,7 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { continue; } else if ((type & 0xF00) == 0xE00) { // 0x0FFF // Allowed interrupts list - LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored"); + NGLOG_WARNING(Loader, "ExHeader allowed interrupts list ignored"); } else if ((type & 0xF80) == 0xF00) { // 0x07FF // Allowed syscalls mask unsigned int index = ((descriptor >> 24) & 7) * 24; @@ -74,7 +74,7 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { } else if ((type & 0xFFE) == 0xFF8) { // 0x001F // Mapped memory range if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) { - LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); + NGLOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); continue; } u32 end_desc = kernel_caps[i + 1]; @@ -109,9 +109,9 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { int minor = kernel_version & 0xFF; int major = (kernel_version >> 8) & 0xFF; - LOG_INFO(Loader, "ExHeader kernel version: %d.%d", major, minor); + NGLOG_INFO(Loader, "ExHeader kernel version: {}.{}", major, minor); } else { - LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x%08X", descriptor); + NGLOG_ERROR(Loader, "Unhandled kernel caps descriptor: {:#010X}", descriptor); } } } diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index 88ca8ad7ed..0ef5fc57d0 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -29,7 +29,7 @@ SharedPtr ResourceLimit::GetForCategory(ResourceLimitCategory cat case ResourceLimitCategory::OTHER: return resource_limits[static_cast(category)]; default: - LOG_CRITICAL(Kernel, "Unknown resource limit category"); + NGLOG_CRITICAL(Kernel, "Unknown resource limit category"); UNREACHABLE(); } } @@ -55,7 +55,7 @@ s32 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const { case ResourceType::CPUTime: return current_cpu_time; default: - LOG_ERROR(Kernel, "Unknown resource type=%08X", static_cast(resource)); + NGLOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast(resource)); UNIMPLEMENTED(); return 0; } @@ -84,7 +84,7 @@ u32 ResourceLimit::GetMaxResourceValue(ResourceType resource) const { case ResourceType::CPUTime: return max_cpu_time; default: - LOG_ERROR(Kernel, "Unknown resource type=%08X", static_cast(resource)); + NGLOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast(resource)); UNIMPLEMENTED(); return 0; } diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 921f27efb3..ff6a0941a2 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -94,11 +94,11 @@ void Scheduler::Reschedule() { Thread* next = PopNextReadyThread(); if (cur && next) { - LOG_TRACE(Kernel, "context switch %u -> %u", cur->GetObjectId(), next->GetObjectId()); + NGLOG_TRACE(Kernel, "context switch {} -> {}", cur->GetObjectId(), next->GetObjectId()); } else if (cur) { - LOG_TRACE(Kernel, "context switch %u -> idle", cur->GetObjectId()); + NGLOG_TRACE(Kernel, "context switch {} -> idle", cur->GetObjectId()); } else if (next) { - LOG_TRACE(Kernel, "context switch idle -> %u", next->GetObjectId()); + NGLOG_TRACE(Kernel, "context switch idle -> {}", next->GetObjectId()); } SwitchContext(next); diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 33397d84f7..b1f8e771c4 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -68,7 +68,7 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con return domain_request_handlers[object_id - 1]->HandleSyncRequest(context); case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: { - LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x%08X", object_id); + NGLOG_DEBUG(IPC, "CloseVirtualHandle, object_id={:#010X}", object_id); domain_request_handlers[object_id - 1] = nullptr; @@ -78,8 +78,8 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con } } - LOG_CRITICAL(IPC, "Unknown domain command=%d", - static_cast(domain_message_header->command.Value())); + NGLOG_CRITICAL(IPC, "Unknown domain command={}", + static_cast(domain_message_header->command.Value())); ASSERT(false); } diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index bc99993c81..b18e9aea4a 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -107,16 +107,16 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi // Error out if the requested permissions don't match what the creator process allows. if (static_cast(permissions) & ~static_cast(own_other_permissions)) { - LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, permissions don't match", - GetObjectId(), address, name.c_str()); + NGLOG_ERROR(Kernel, "cannot map id={}, address={:#X} name={}, permissions don't match", + GetObjectId(), address, name); return ERR_INVALID_COMBINATION; } // Error out if the provided permissions are not compatible with what the creator process needs. if (other_permissions != MemoryPermission::DontCare && static_cast(this->permissions) & ~static_cast(other_permissions)) { - LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, permissions don't match", - GetObjectId(), address, name.c_str()); + NGLOG_ERROR(Kernel, "cannot map id={}, address={:#X} name={}, permissions don't match", + GetObjectId(), address, name); return ERR_WRONG_PERMISSION; } @@ -131,9 +131,10 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi auto result = target_process->vm_manager.MapMemoryBlock( target_address, backing_block, backing_block_offset, size, MemoryState::Shared); if (result.Failed()) { - LOG_ERROR(Kernel, - "cannot map id=%u, target_address=0x%lx name=%s, error mapping to virtual memory", - GetObjectId(), target_address, name.c_str()); + NGLOG_ERROR( + Kernel, + "cannot map id={}, target_address={:#X} name={}, error mapping to virtual memory", + GetObjectId(), target_address, name); return result.Code(); } diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index c22da6e47e..cb19b1a69a 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -31,7 +31,7 @@ namespace Kernel { /// Set the process heap to a given Size. It can both extend and shrink the heap. static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { - LOG_TRACE(Kernel_SVC, "called, heap_size=0x%llx", heap_size); + NGLOG_TRACE(Kernel_SVC, "called, heap_size={:#X}", heap_size); auto& process = *Core::CurrentProcess(); CASCADE_RESULT(*heap_addr, process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite)); @@ -39,21 +39,21 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { } static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) { - LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x%lx", addr); + NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, addr={:#X}", addr); return RESULT_SUCCESS; } /// Maps a memory range into a different range. static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { - LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr, - src_addr, size); + NGLOG_TRACE(Kernel_SVC, "called, dst_addr={:#X}, src_addr={:#X}, size={:#X}", dst_addr, + src_addr, size); return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size); } /// Unmaps a region that was previously mapped with svcMapMemory static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { - LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr, - src_addr, size); + NGLOG_TRACE(Kernel_SVC, "called, dst_addr={:#X}, src_addr={:#X}, size={:#X}", dst_addr, + src_addr, size); return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size); } @@ -68,11 +68,11 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address if (port_name.size() > PortNameMaxLength) return ERR_PORT_NAME_TOO_LONG; - LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name.c_str()); + NGLOG_TRACE(Kernel_SVC, "called port_name={}", port_name); auto it = Service::g_kernel_named_ports.find(port_name); if (it == Service::g_kernel_named_ports.end()) { - LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name.c_str()); + NGLOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name); return ERR_NOT_FOUND; } @@ -90,11 +90,11 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address static ResultCode SendSyncRequest(Handle handle) { SharedPtr session = g_handle_table.Get(handle); if (!session) { - LOG_ERROR(Kernel_SVC, "called with invalid handle=0x%08X", handle); + NGLOG_ERROR(Kernel_SVC, "called with invalid handle={:#010X}", handle); return ERR_INVALID_HANDLE; } - LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str()); + NGLOG_TRACE(Kernel_SVC, "called handle={:#010X}({})", handle, session->GetName()); Core::System::GetInstance().PrepareReschedule(); @@ -105,7 +105,7 @@ static ResultCode SendSyncRequest(Handle handle) { /// Get the ID for the specified thread. static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { - LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); + NGLOG_TRACE(Kernel_SVC, "called thread={:#010X}", thread_handle); const SharedPtr thread = g_handle_table.Get(thread_handle); if (!thread) { @@ -118,7 +118,7 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { /// Get the ID of the specified process static ResultCode GetProcessId(u32* process_id, Handle process_handle) { - LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle); + NGLOG_TRACE(Kernel_SVC, "called process={:#010X}", process_handle); const SharedPtr process = g_handle_table.Get(process_handle); if (!process) { @@ -178,8 +178,8 @@ static ResultCode WaitSynchronization1( /// Wait for the given handles to synchronize, timeout after the specified nanoseconds static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count, s64 nano_seconds) { - LOG_TRACE(Kernel_SVC, "called handles_address=0x%llx, handle_count=%d, nano_seconds=%d", - handles_address, handle_count, nano_seconds); + NGLOG_TRACE(Kernel_SVC, "called handles_address={:#X}, handle_count={}, nano_seconds={}", + handles_address, handle_count, nano_seconds); if (!Memory::IsValidVirtualAddress(handles_address)) return ERR_INVALID_POINTER; @@ -239,7 +239,7 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 /// Resumes a thread waiting on WaitSynchronization static ResultCode CancelSynchronization(Handle thread_handle) { - LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); + NGLOG_TRACE(Kernel_SVC, "called thread={:#X}", thread_handle); const SharedPtr thread = g_handle_table.Get(thread_handle); if (!thread) { @@ -256,38 +256,38 @@ static ResultCode CancelSynchronization(Handle thread_handle) { /// Attempts to locks a mutex, creating it if it does not already exist static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, Handle requesting_thread_handle) { - LOG_TRACE(Kernel_SVC, - "called holding_thread_handle=0x%08X, mutex_addr=0x%llx, " - "requesting_current_thread_handle=0x%08X", - holding_thread_handle, mutex_addr, requesting_thread_handle); + NGLOG_TRACE(Kernel_SVC, + "called holding_thread_handle={:#010X}, mutex_addr={:#X}, " + "requesting_current_thread_handle={:#010X}", + holding_thread_handle, mutex_addr, requesting_thread_handle); return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle); } /// Unlock a mutex static ResultCode ArbitrateUnlock(VAddr mutex_addr) { - LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr); + NGLOG_TRACE(Kernel_SVC, "called mutex_addr={:#X}", mutex_addr); return Mutex::Release(mutex_addr); } /// Break program execution static void Break(u64 unk_0, u64 unk_1, u64 unk_2) { - LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!"); + NGLOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!"); ASSERT(false); } /// Used to output a message on a debug hardware unit - does nothing on a retail unit static void OutputDebugString(VAddr address, s32 len) { - std::vector string(len); - Memory::ReadBlock(address, string.data(), len); - LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data()); + std::string str(len, '\0'); + Memory::ReadBlock(address, str.data(), str.size()); + NGLOG_DEBUG(Debug_Emulated, "{}", str); } /// Gets system/memory information for the current process static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) { - LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id, - info_sub_id, handle); + NGLOG_TRACE(Kernel_SVC, "called info_id={:#X}, info_sub_id={:#X}, handle={:#010X}", info_id, + info_sub_id, handle); auto& vm_manager = Core::CurrentProcess()->vm_manager; @@ -338,12 +338,12 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) *result = Core::CurrentProcess()->is_virtual_address_memory_enabled; break; case GetInfoType::TitleId: - LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0"); + NGLOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0"); *result = 0; break; case GetInfoType::PrivilegedProcessId: - LOG_WARNING(Kernel_SVC, - "(STUBBED) Attempted to query priviledged process id bounds, returned 0"); + NGLOG_WARNING(Kernel_SVC, + "(STUBBED) Attempted to query privileged process id bounds, returned 0"); *result = 0; break; default: @@ -355,13 +355,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) /// Sets the thread activity static ResultCode SetThreadActivity(Handle handle, u32 unknown) { - LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, unknown=0x%08X", handle, unknown); + NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:#010X}, unknown={:#010X}", handle, + unknown); return RESULT_SUCCESS; } /// Gets the thread context static ResultCode GetThreadContext(Handle handle, VAddr addr) { - LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, addr=0x%" PRIx64, handle, addr); + NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:#010X}, addr={:#X}", handle, addr); return RESULT_SUCCESS; } @@ -400,15 +401,15 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { /// Get which CPU core is executing the current thread static u32 GetCurrentProcessorNumber() { - LOG_WARNING(Kernel_SVC, "(STUBBED) called, defaulting to processor 0"); + NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, defaulting to processor 0"); return 0; } static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size, u32 permissions) { - LOG_TRACE(Kernel_SVC, - "called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X", - shared_memory_handle, addr, size, permissions); + NGLOG_TRACE(Kernel_SVC, + "called, shared_memory_handle={:#X}, addr={:#X}, size={:#X}, permissions={:#010X}", + shared_memory_handle, addr, size, permissions); SharedPtr shared_memory = g_handle_table.Get(shared_memory_handle); if (!shared_memory) { @@ -428,16 +429,15 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type, MemoryPermission::DontCare); default: - LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); + NGLOG_ERROR(Kernel_SVC, "unknown permissions={:#010X}", permissions); } return RESULT_SUCCESS; } static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { - LOG_WARNING(Kernel_SVC, - "called, shared_memory_handle=0x%08X, addr=0x%" PRIx64 ", size=0x%" PRIx64 "", - shared_memory_handle, addr, size); + NGLOG_WARNING(Kernel_SVC, "called, shared_memory_handle={:#010X}, addr={:#X}, size={:#X}", + shared_memory_handle, addr, size); SharedPtr shared_memory = g_handle_table.Get(shared_memory_handle); @@ -465,19 +465,19 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i memory_info->type = static_cast(vma->second.meminfo_state); } - LOG_TRACE(Kernel_SVC, "called process=0x%08X addr=%llx", process_handle, addr); + NGLOG_TRACE(Kernel_SVC, "called process={:#010X} addr={:X}", process_handle, addr); return RESULT_SUCCESS; } /// Query memory static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAddr addr) { - LOG_TRACE(Kernel_SVC, "called, addr=%llx", addr); + NGLOG_TRACE(Kernel_SVC, "called, addr={:X}", addr); return QueryProcessMemory(memory_info, page_info, CurrentProcess, addr); } /// Exits the current process static void ExitProcess() { - LOG_INFO(Kernel_SVC, "Process %u exiting", Core::CurrentProcess()->process_id); + NGLOG_INFO(Kernel_SVC, "Process {} exiting", Core::CurrentProcess()->process_id); ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running, "Process has already exited"); @@ -534,9 +534,9 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V case THREADPROCESSORID_2: case THREADPROCESSORID_3: // TODO(bunnei): Implement support for other processor IDs - LOG_ERROR(Kernel_SVC, - "Newly created thread must run in another thread (%u), unimplemented.", - processor_id); + NGLOG_ERROR(Kernel_SVC, + "Newly created thread must run in another thread ({}), unimplemented.", + processor_id); break; default: ASSERT_MSG(false, "Unsupported thread processor ID: %d", processor_id); @@ -551,17 +551,17 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V Core::System::GetInstance().PrepareReschedule(); - LOG_TRACE(Kernel_SVC, - "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " - "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", - entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle); + NGLOG_TRACE(Kernel_SVC, + "called entrypoint={:#010X} ({}), arg={:#010X}, stacktop={:#010X}, " + "threadpriority={:#010X}, processorid={:#010X} : created handle={:#010X}", + entry_point, name, arg, stack_top, priority, processor_id, *out_handle); return RESULT_SUCCESS; } /// Starts the thread for the provided handle static ResultCode StartThread(Handle thread_handle) { - LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); + NGLOG_TRACE(Kernel_SVC, "called thread={:#010X}", thread_handle); const SharedPtr thread = g_handle_table.Get(thread_handle); if (!thread) { @@ -575,7 +575,7 @@ static ResultCode StartThread(Handle thread_handle) { /// Called when a thread exits static void ExitThread() { - LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::CPU().GetPC()); + NGLOG_TRACE(Kernel_SVC, "called, pc={:#010X}", Core::CPU().GetPC()); ExitCurrentThread(); Core::System::GetInstance().PrepareReschedule(); @@ -583,7 +583,7 @@ static void ExitThread() { /// Sleep the current thread static void SleepThread(s64 nanoseconds) { - LOG_TRACE(Kernel_SVC, "called nanoseconds=%lld", nanoseconds); + NGLOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); // Don't attempt to yield execution if there are no available threads to run, // this way we avoid a useless reschedule to the idle thread. @@ -602,9 +602,9 @@ static void SleepThread(s64 nanoseconds) { /// Signal process wide key atomic static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr, Handle thread_handle, s64 nano_seconds) { - LOG_TRACE( + NGLOG_TRACE( Kernel_SVC, - "called mutex_addr=%llx, condition_variable_addr=%llx, thread_handle=0x%08X, timeout=%d", + "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle={:#010X}, timeout={}", mutex_addr, condition_variable_addr, thread_handle, nano_seconds); SharedPtr thread = g_handle_table.Get(thread_handle); @@ -629,8 +629,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var /// Signal process wide key static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) { - LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x%llx, target=0x%08x", - condition_variable_addr, target); + NGLOG_TRACE(Kernel_SVC, "called, condition_variable_addr={:#X}, target={:#010X}", + condition_variable_addr, target); u32 processed = 0; auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList(); @@ -696,13 +696,13 @@ static u64 GetSystemTick() { /// Close a handle static ResultCode CloseHandle(Handle handle) { - LOG_TRACE(Kernel_SVC, "Closing handle 0x%08X", handle); + NGLOG_TRACE(Kernel_SVC, "Closing handle {:#010X}", handle); return g_handle_table.Close(handle); } /// Reset an event static ResultCode ResetSignal(Handle handle) { - LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x%08X", handle); + NGLOG_WARNING(Kernel_SVC, "(STUBBED) called handle {:#010X}", handle); auto event = g_handle_table.Get(handle); ASSERT(event != nullptr); event->Clear(); @@ -711,29 +711,29 @@ static ResultCode ResetSignal(Handle handle) { /// Creates a TransferMemory object static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) { - LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%lx, size=0x%lx, perms=%08X", addr, size, - permissions); + NGLOG_WARNING(Kernel_SVC, "(STUBBED) called addr={:#X}, size={:#X}, perms={:010X}", addr, size, + permissions); *handle = 0; return RESULT_SUCCESS; } static ResultCode GetThreadCoreMask(Handle handle, u32* mask, u64* unknown) { - LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X", handle); + NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:010X}", handle); *mask = 0x0; *unknown = 0xf; return RESULT_SUCCESS; } static ResultCode SetThreadCoreMask(Handle handle, u32 mask, u64 unknown) { - LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, mask=0x%08X, unknown=0x%lx", handle, - mask, unknown); + NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:#010X}, mask={:#010X}, unknown={:#X}", + handle, mask, unknown); return RESULT_SUCCESS; } static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions, u32 remote_permissions) { - LOG_TRACE(Kernel_SVC, "called, size=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", size, - local_permissions, remote_permissions); + NGLOG_TRACE(Kernel_SVC, "called, size={:#X}, localPerms={:#010X}, remotePerms={:#010X}", size, + local_permissions, remote_permissions); auto sharedMemHandle = SharedMemory::Create(g_handle_table.Get(KernelHandle::CurrentProcess), size, static_cast(local_permissions), @@ -744,7 +744,7 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss } static ResultCode ClearEvent(Handle handle) { - LOG_TRACE(Kernel_SVC, "called, event=0xX", handle); + NGLOG_TRACE(Kernel_SVC, "called, event={:010X}", handle); SharedPtr evt = g_handle_table.Get(handle); if (evt == nullptr) @@ -896,7 +896,7 @@ static const FunctionDef SVC_Table[] = { static const FunctionDef* GetSVCInfo(u32 func_num) { if (func_num >= std::size(SVC_Table)) { - LOG_ERROR(Kernel_SVC, "unknown svc=0x%02X", func_num); + NGLOG_ERROR(Kernel_SVC, "Unknown svc={:#04X}", func_num); return nullptr; } return &SVC_Table[func_num]; @@ -915,10 +915,10 @@ void CallSVC(u32 immediate) { if (info->func) { info->func(); } else { - LOG_CRITICAL(Kernel_SVC, "unimplemented SVC function %s(..)", info->name); + NGLOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name); } } else { - LOG_CRITICAL(Kernel_SVC, "unknown SVC function 0x%x", immediate); + NGLOG_CRITICAL(Kernel_SVC, "Unknown SVC function {:#X}", immediate); } } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 36222d45fe..4cd57ab258 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -101,9 +101,10 @@ void ExitCurrentThread() { * @param cycles_late The number of CPU cycles that have passed since the desired wakeup time */ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { - SharedPtr thread = wakeup_callback_handle_table.Get((Handle)thread_handle); + const auto proper_handle = static_cast(thread_handle); + SharedPtr thread = wakeup_callback_handle_table.Get(proper_handle); if (thread == nullptr) { - LOG_CRITICAL(Kernel, "Callback fired for invalid thread %08X", (Handle)thread_handle); + NGLOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle); return; } @@ -238,19 +239,19 @@ ResultVal> Thread::Create(std::string name, VAddr entry_point, SharedPtr owner_process) { // Check if priority is in ranged. Lowest priority -> highest priority id. if (priority > THREADPRIO_LOWEST) { - LOG_ERROR(Kernel_SVC, "Invalid thread priority: %u", priority); + NGLOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); return ERR_OUT_OF_RANGE; } if (processor_id > THREADPROCESSORID_MAX) { - LOG_ERROR(Kernel_SVC, "Invalid processor id: %d", processor_id); + NGLOG_ERROR(Kernel_SVC, "Invalid processor id: {}", processor_id); return ERR_OUT_OF_RANGE_KERNEL; } // TODO(yuriks): Other checks, returning 0xD9001BEA if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) { - LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %016" PRIx64, name.c_str(), entry_point); + NGLOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point); // TODO (bunnei): Find the correct error code to use here return ResultCode(-1); } @@ -289,8 +290,8 @@ ResultVal> Thread::Create(std::string name, VAddr entry_point, auto& linheap_memory = memory_region->linear_heap_memory; if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) { - LOG_ERROR(Kernel_SVC, - "Not enough space in region to allocate a new TLS page for thread"); + NGLOG_ERROR(Kernel_SVC, + "Not enough space in region to allocate a new TLS page for thread"); return ERR_OUT_OF_MEMORY; } diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 8da745634e..ad58bf043b 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -77,7 +77,7 @@ void Timer::WakeupAllWaitingThreads() { } void Timer::Signal(int cycles_late) { - LOG_TRACE(Kernel, "Timer %u fired", GetObjectId()); + NGLOG_TRACE(Kernel, "Timer {} fired", GetObjectId()); signaled = true; @@ -97,7 +97,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { timer_callback_handle_table.Get(static_cast(timer_handle)); if (timer == nullptr) { - LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08" PRIx64, timer_handle); + NGLOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle); return; } diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index acd65ee685..eb2e35eed7 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -379,22 +379,22 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { } u64 VMManager::GetTotalMemoryUsage() { - LOG_WARNING(Kernel, "(STUBBED) called"); + NGLOG_WARNING(Kernel, "(STUBBED) called"); return 0xF8000000; } u64 VMManager::GetTotalHeapUsage() { - LOG_WARNING(Kernel, "(STUBBED) called"); + NGLOG_WARNING(Kernel, "(STUBBED) called"); return 0x0; } VAddr VMManager::GetAddressSpaceBaseAddr() { - LOG_WARNING(Kernel, "(STUBBED) called"); + NGLOG_WARNING(Kernel, "(STUBBED) called"); return 0x8000000; } u64 VMManager::GetAddressSpaceSize() { - LOG_WARNING(Kernel, "(STUBBED) called"); + NGLOG_WARNING(Kernel, "(STUBBED) called"); return MAX_ADDRESS; } From 1913cf47833c4927e7f2b67dc87eeaaf4ae6ac15 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 25 Apr 2018 19:52:48 -0400 Subject: [PATCH 71/74] kernel/shared_memory: Remove unnecessary semicolon at end of ConvertPermissions() Functions don't need to be terminated by semicolons. --- src/core/hle/kernel/shared_memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index b18e9aea4a..f0b65c73d2 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -152,7 +152,7 @@ VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) { u32 masked_permissions = static_cast(permission) & static_cast(MemoryPermission::ReadWriteExecute); return static_cast(masked_permissions); -}; +} u8* SharedMemory::GetPointer(u32 offset) { return backing_block->data() + backing_block_offset + offset; From 08da0b7acc6e9a251a8505a0abf6deaf2276cde8 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 26 Apr 2018 08:54:52 -0400 Subject: [PATCH 72/74] core/hw: Move logging macros over to fmt-capable ones --- src/core/hw/hw.cpp | 10 ++++++---- src/core/hw/lcd.cpp | 8 ++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp index 0db604c76d..f8a40390a1 100644 --- a/src/core/hw/hw.cpp +++ b/src/core/hw/hw.cpp @@ -33,7 +33,8 @@ inline void Read(T& var, const u32 addr) { LCD::Read(var, addr); break; default: - LOG_ERROR(HW_Memory, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr); + NGLOG_ERROR(HW_Memory, "Unknown Read{} @ {:#010X}", sizeof(var) * 8, addr); + break; } } @@ -61,7 +62,8 @@ inline void Write(u32 addr, const T data) { LCD::Write(addr, data); break; default: - LOG_ERROR(HW_Memory, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr); + NGLOG_ERROR(HW_Memory, "Unknown Write{} {:#010X} @ {:#010X}", sizeof(data) * 8, data, addr); + break; } } @@ -83,12 +85,12 @@ void Update() {} /// Initialize hardware void Init() { LCD::Init(); - LOG_DEBUG(HW, "initialized OK"); + NGLOG_DEBUG(HW, "Initialized OK"); } /// Shutdown hardware void Shutdown() { LCD::Shutdown(); - LOG_DEBUG(HW, "shutdown OK"); + NGLOG_DEBUG(HW, "Shutdown OK"); } } // namespace HW diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp index 690079b656..7d0046bf3d 100644 --- a/src/core/hw/lcd.cpp +++ b/src/core/hw/lcd.cpp @@ -20,7 +20,7 @@ inline void Read(T& var, const u32 raw_addr) { // Reads other than u32 are untested, so I'd rather have them abort than silently fail if (index >= 0x400 || !std::is_same::value) { - LOG_ERROR(HW_LCD, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr); + NGLOG_ERROR(HW_LCD, "Unknown Read{} @ {:#010X}", sizeof(var) * 8, addr); return; } @@ -34,7 +34,7 @@ inline void Write(u32 addr, const T data) { // Writes other than u32 are untested, so I'd rather have them abort than silently fail if (index >= 0x400 || !std::is_same::value) { - LOG_ERROR(HW_LCD, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr); + NGLOG_ERROR(HW_LCD, "Unknown Write{} {:#010X} @ {:#010X}", sizeof(data) * 8, data, addr); return; } @@ -56,12 +56,12 @@ template void Write(u32 addr, const u8 data); /// Initialize hardware void Init() { memset(&g_regs, 0, sizeof(g_regs)); - LOG_DEBUG(HW_LCD, "initialized OK"); + NGLOG_DEBUG(HW_LCD, "Initialized OK"); } /// Shutdown hardware void Shutdown() { - LOG_DEBUG(HW_LCD, "shutdown OK"); + NGLOG_DEBUG(HW_LCD, "Shutdown OK"); } } // namespace LCD From 623d7724760020e8b8879f699e10d6cd9518961a Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 26 Apr 2018 11:08:40 -0400 Subject: [PATCH 73/74] core/gdbstub: Move logging macros to new fmt-compatible ones --- src/core/gdbstub/gdbstub.cpp | 75 ++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index e4f337a0a2..46606b9922 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -180,7 +179,7 @@ static u8 HexCharToValue(u8 hex) { return hex - 'A' + 0xA; } - LOG_ERROR(Debug_GDBStub, "Invalid nibble: %c (%02x)\n", hex, hex); + NGLOG_ERROR(Debug_GDBStub, "Invalid nibble: {} ({:02X})", hex, hex); return 0; } @@ -320,7 +319,7 @@ static u8 ReadByte() { u8 c; size_t received_size = recv(gdbserver_socket, reinterpret_cast(&c), 1, MSG_WAITALL); if (received_size != 1) { - LOG_ERROR(Debug_GDBStub, "recv failed : %ld", received_size); + NGLOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size); Shutdown(); } @@ -361,9 +360,8 @@ static void RemoveBreakpoint(BreakpointType type, PAddr addr) { auto bp = p.find(static_cast(addr)); if (bp != p.end()) { - LOG_DEBUG(Debug_GDBStub, - "gdb: removed a breakpoint: %016" PRIx64 " bytes at %016" PRIx64 " of type %d\n", - bp->second.len, bp->second.addr, static_cast(type)); + NGLOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}", + bp->second.len, bp->second.addr, static_cast(type)); p.erase(static_cast(addr)); } } @@ -408,10 +406,10 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) { } if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { - LOG_DEBUG(Debug_GDBStub, - "Found breakpoint type %d @ %016" PRIx64 ", range: %016" PRIx64 - " - %016" PRIx64 " (%" PRIx64 " bytes)\n", - static_cast(type), addr, bp->second.addr, bp->second.addr + len, len); + NGLOG_DEBUG(Debug_GDBStub, + "Found breakpoint type {} @ {:016X}, range: {:016X}" + " - {:016X} ({:X} bytes)", + static_cast(type), addr, bp->second.addr, bp->second.addr + len, len); return true; } } @@ -427,7 +425,7 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) { static void SendPacket(const char packet) { size_t sent_size = send(gdbserver_socket, &packet, 1, 0); if (sent_size != 1) { - LOG_ERROR(Debug_GDBStub, "send failed"); + NGLOG_ERROR(Debug_GDBStub, "send failed"); } } @@ -445,7 +443,7 @@ static void SendReply(const char* reply) { command_length = static_cast(strlen(reply)); if (command_length + 4 > sizeof(command_buffer)) { - LOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply"); + NGLOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply"); return; } @@ -462,7 +460,7 @@ static void SendReply(const char* reply) { while (left > 0) { int sent_size = send(gdbserver_socket, reinterpret_cast(ptr), left, 0); if (sent_size < 0) { - LOG_ERROR(Debug_GDBStub, "gdb: send failed"); + NGLOG_ERROR(Debug_GDBStub, "gdb: send failed"); return Shutdown(); } @@ -473,7 +471,7 @@ static void SendReply(const char* reply) { /// Handle query command from gdb client. static void HandleQuery() { - LOG_DEBUG(Debug_GDBStub, "gdb: query '%s'\n", command_buffer + 1); + NGLOG_DEBUG(Debug_GDBStub, "gdb: query '{}'", command_buffer + 1); const char* query = reinterpret_cast(command_buffer + 1); @@ -512,8 +510,8 @@ static void SendSignal(u32 signal) { latest_signal = signal; - std::string buffer = Common::StringFromFormat("T%02x", latest_signal); - LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str()); + std::string buffer = fmt::format("T{:02x}", latest_signal); + NGLOG_DEBUG(Debug_GDBStub, "Response: {}", buffer); SendReply(buffer.c_str()); } @@ -527,18 +525,18 @@ static void ReadCommand() { // ignore ack return; } else if (c == 0x03) { - LOG_INFO(Debug_GDBStub, "gdb: found break command\n"); + NGLOG_INFO(Debug_GDBStub, "gdb: found break command"); halt_loop = true; SendSignal(SIGTRAP); return; } else if (c != GDB_STUB_START) { - LOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte %02x\n", c); + NGLOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte {:02X}", c); return; } while ((c = ReadByte()) != GDB_STUB_END) { if (command_length >= sizeof(command_buffer)) { - LOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow\n"); + NGLOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow"); SendPacket(GDB_STUB_NACK); return; } @@ -551,9 +549,10 @@ static void ReadCommand() { u8 checksum_calculated = CalculateChecksum(command_buffer, command_length); if (checksum_received != checksum_calculated) { - LOG_ERROR(Debug_GDBStub, - "gdb: invalid checksum: calculated %02x and read %02x for $%s# (length: %d)\n", - checksum_calculated, checksum_received, command_buffer, command_length); + NGLOG_ERROR( + Debug_GDBStub, + "gdb: invalid checksum: calculated {:02X} and read {:02X} for ${}# (length: {})", + checksum_calculated, checksum_received, command_buffer, command_length); command_length = 0; @@ -580,7 +579,7 @@ static bool IsDataAvailable() { t.tv_usec = 0; if (select(gdbserver_socket + 1, &fd_socket, nullptr, nullptr, &t) < 0) { - LOG_ERROR(Debug_GDBStub, "select failed"); + NGLOG_ERROR(Debug_GDBStub, "select failed"); return false; } @@ -693,7 +692,7 @@ static void ReadMemory() { u64 len = HexToLong(start_offset, static_cast((command_buffer + command_length) - start_offset)); - LOG_DEBUG(Debug_GDBStub, "gdb: addr: %016lx len: %016lx\n", addr, len); + NGLOG_DEBUG(Debug_GDBStub, "gdb: addr: {:016X} len: {:016X}", addr, len); if (len * 2 > sizeof(reply)) { SendReply("E01"); @@ -781,8 +780,8 @@ static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) { breakpoint.len = len; p.insert({addr, breakpoint}); - LOG_DEBUG(Debug_GDBStub, "gdb: added %d breakpoint: %016" PRIx64 " bytes at %016" PRIx64 "\n", - static_cast(type), breakpoint.len, breakpoint.addr); + NGLOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}", + static_cast(type), breakpoint.len, breakpoint.addr); return true; } @@ -889,7 +888,7 @@ void HandlePacket() { return; } - LOG_DEBUG(Debug_GDBStub, "Packet: %s", command_buffer); + NGLOG_DEBUG(Debug_GDBStub, "Packet: {}", command_buffer); switch (command_buffer[0]) { case 'q': @@ -903,7 +902,7 @@ void HandlePacket() { break; case 'k': Shutdown(); - LOG_INFO(Debug_GDBStub, "killed by gdb"); + NGLOG_INFO(Debug_GDBStub, "killed by gdb"); return; case 'g': ReadRegisters(); @@ -982,7 +981,7 @@ static void Init(u16 port) { breakpoints_write.clear(); // Start gdb server - LOG_INFO(Debug_GDBStub, "Starting GDB server on port %d...", port); + NGLOG_INFO(Debug_GDBStub, "Starting GDB server on port {}...", port); sockaddr_in saddr_server = {}; saddr_server.sin_family = AF_INET; @@ -995,28 +994,28 @@ static void Init(u16 port) { int tmpsock = static_cast(socket(PF_INET, SOCK_STREAM, 0)); if (tmpsock == -1) { - LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket"); + NGLOG_ERROR(Debug_GDBStub, "Failed to create gdb socket"); } // Set socket to SO_REUSEADDR so it can always bind on the same port int reuse_enabled = 1; if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled, sizeof(reuse_enabled)) < 0) { - LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option"); + NGLOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option"); } const sockaddr* server_addr = reinterpret_cast(&saddr_server); socklen_t server_addrlen = sizeof(saddr_server); if (bind(tmpsock, server_addr, server_addrlen) < 0) { - LOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket"); + NGLOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket"); } if (listen(tmpsock, 1) < 0) { - LOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket"); + NGLOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket"); } // Wait for gdb to connect - LOG_INFO(Debug_GDBStub, "Waiting for gdb to connect...\n"); + NGLOG_INFO(Debug_GDBStub, "Waiting for gdb to connect..."); sockaddr_in saddr_client; sockaddr* client_addr = reinterpret_cast(&saddr_client); socklen_t client_addrlen = sizeof(saddr_client); @@ -1027,9 +1026,9 @@ static void Init(u16 port) { halt_loop = false; step_loop = false; - LOG_ERROR(Debug_GDBStub, "Failed to accept gdb client"); + NGLOG_ERROR(Debug_GDBStub, "Failed to accept gdb client"); } else { - LOG_INFO(Debug_GDBStub, "Client connected.\n"); + NGLOG_INFO(Debug_GDBStub, "Client connected."); saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr); } @@ -1048,7 +1047,7 @@ void Shutdown() { return; } - LOG_INFO(Debug_GDBStub, "Stopping GDB ..."); + NGLOG_INFO(Debug_GDBStub, "Stopping GDB ..."); if (gdbserver_socket != -1) { shutdown(gdbserver_socket, SHUT_RDWR); gdbserver_socket = -1; @@ -1058,7 +1057,7 @@ void Shutdown() { WSACleanup(); #endif - LOG_INFO(Debug_GDBStub, "GDB stopped."); + NGLOG_INFO(Debug_GDBStub, "GDB stopped."); } bool IsServerEnabled() { From 87a92ef062dcfca44e6122dea6cad747daaa2659 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 26 Apr 2018 14:57:38 -0400 Subject: [PATCH 74/74] common: Remove chunk_file.h and linear_disk_cache.h These are unused (and given chunk_file references Dolphin's >SVN< I doubt they were going to be used). --- src/common/CMakeLists.txt | 2 - src/common/chunk_file.h | 623 --------------------------------- src/common/linear_disk_cache.h | 167 --------- 3 files changed, 792 deletions(-) delete mode 100644 src/common/chunk_file.h delete mode 100644 src/common/linear_disk_cache.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 32cb85de04..f49a316127 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -31,7 +31,6 @@ add_library(common STATIC bit_set.h break_points.cpp break_points.h - chunk_file.h cityhash.cpp cityhash.h color.h @@ -41,7 +40,6 @@ add_library(common STATIC file_util.cpp file_util.h hash.h - linear_disk_cache.h logging/backend.cpp logging/backend.h logging/filter.cpp diff --git a/src/common/chunk_file.h b/src/common/chunk_file.h deleted file mode 100644 index 972ef90390..0000000000 --- a/src/common/chunk_file.h +++ /dev/null @@ -1,623 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#pragma once - -// Extremely simple serialization framework. - -// (mis)-features: -// + Super fast -// + Very simple -// + Same code is used for serialization and deserializaition (in most cases) -// - Zero backwards/forwards compatibility -// - Serialization code for anything complex has to be manually written. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common/assert.h" -#include "common/common_types.h" -#include "common/logging/log.h" - -template -struct LinkedListItem : public T { - LinkedListItem* next; -}; - -class PointerWrap; - -class PointerWrapSection { -public: - PointerWrapSection(PointerWrap& p, int ver, const char* title) - : p_(p), ver_(ver), title_(title) {} - ~PointerWrapSection(); - - bool operator==(const int& v) const { - return ver_ == v; - } - bool operator!=(const int& v) const { - return ver_ != v; - } - bool operator<=(const int& v) const { - return ver_ <= v; - } - bool operator>=(const int& v) const { - return ver_ >= v; - } - bool operator<(const int& v) const { - return ver_ < v; - } - bool operator>(const int& v) const { - return ver_ > v; - } - - operator bool() const { - return ver_ > 0; - } - -private: - PointerWrap& p_; - int ver_; - const char* title_; -}; - -// Wrapper class -class PointerWrap { -// This makes it a compile error if you forget to define DoState() on non-POD. -// Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason... -#ifdef _MSC_VER - template ::value, - bool isPointer = std::is_pointer::value> -#else - template ::value> -#endif - struct DoHelper { - static void DoArray(PointerWrap* p, T* x, int count) { - for (int i = 0; i < count; ++i) - p->Do(x[i]); - } - - static void Do(PointerWrap* p, T& x) { - p->DoClass(x); - } - }; - - template - struct DoHelper { - static void DoArray(PointerWrap* p, T* x, int count) { - p->DoVoid((void*)x, sizeof(T) * count); - } - - static void Do(PointerWrap* p, T& x) { - p->DoVoid((void*)&x, sizeof(x)); - } - }; - -public: - enum Mode { - MODE_READ = 1, // load - MODE_WRITE, // save - MODE_MEASURE, // calculate size - MODE_VERIFY, // compare - }; - - enum Error { - ERROR_NONE = 0, - ERROR_WARNING = 1, - ERROR_FAILURE = 2, - }; - - u8** ptr; - Mode mode; - Error error; - -public: - PointerWrap(u8** ptr_, Mode mode_) : ptr(ptr_), mode(mode_), error(ERROR_NONE) {} - PointerWrap(unsigned char** ptr_, int mode_) - : ptr((u8**)ptr_), mode((Mode)mode_), error(ERROR_NONE) {} - - PointerWrapSection Section(const char* title, int ver) { - return Section(title, ver, ver); - } - - // The returned object can be compared against the version that was loaded. - // This can be used to support versions as old as minVer. - // Version = 0 means the section was not found. - PointerWrapSection Section(const char* title, int minVer, int ver) { - char marker[16] = {0}; - int foundVersion = ver; - - strncpy(marker, title, sizeof(marker)); - if (!ExpectVoid(marker, sizeof(marker))) { - // Might be before we added name markers for safety. - if (foundVersion == 1 && ExpectVoid(&foundVersion, sizeof(foundVersion))) - DoMarker(title); - // Wasn't found, but maybe we can still load the state. - else - foundVersion = 0; - } else - Do(foundVersion); - - if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) { - LOG_ERROR(Common, "Savestate failure: wrong version %d found for %s", foundVersion, - title); - SetError(ERROR_FAILURE); - return PointerWrapSection(*this, -1, title); - } - return PointerWrapSection(*this, foundVersion, title); - } - - void SetMode(Mode mode_) { - mode = mode_; - } - Mode GetMode() const { - return mode; - } - u8** GetPPtr() { - return ptr; - } - void SetError(Error error_) { - if (error < error_) - error = error_; - if (error > ERROR_WARNING) - mode = PointerWrap::MODE_MEASURE; - } - - bool ExpectVoid(void* data, int size) { - switch (mode) { - case MODE_READ: - if (memcmp(data, *ptr, size) != 0) - return false; - break; - case MODE_WRITE: - memcpy(*ptr, data, size); - break; - case MODE_MEASURE: - break; // MODE_MEASURE - don't need to do anything - case MODE_VERIFY: - for (int i = 0; i < size; i++) { - DEBUG_ASSERT_MSG( - ((u8*)data)[i] == (*ptr)[i], - "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", - ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], - &(*ptr)[i]); - } - break; - default: - break; // throw an error? - } - (*ptr) += size; - return true; - } - - void DoVoid(void* data, int size) { - switch (mode) { - case MODE_READ: - memcpy(data, *ptr, size); - break; - case MODE_WRITE: - memcpy(*ptr, data, size); - break; - case MODE_MEASURE: - break; // MODE_MEASURE - don't need to do anything - case MODE_VERIFY: - for (int i = 0; i < size; i++) { - DEBUG_ASSERT_MSG( - ((u8*)data)[i] == (*ptr)[i], - "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", - ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], - &(*ptr)[i]); - } - break; - default: - break; // throw an error? - } - (*ptr) += size; - } - - template - void Do(std::map& x) { - if (mode == MODE_READ) { - for (auto it = x.begin(), end = x.end(); it != end; ++it) { - if (it->second != nullptr) - delete it->second; - } - } - T* dv = nullptr; - DoMap(x, dv); - } - - template - void Do(std::map& x) { - T dv = T(); - DoMap(x, dv); - } - - template - void DoMap(std::map& x, T& default_val) { - unsigned int number = (unsigned int)x.size(); - Do(number); - switch (mode) { - case MODE_READ: { - x.clear(); - while (number > 0) { - K first = K(); - Do(first); - T second = default_val; - Do(second); - x[first] = second; - --number; - } - } break; - case MODE_WRITE: - case MODE_MEASURE: - case MODE_VERIFY: { - typename std::map::iterator itr = x.begin(); - while (number > 0) { - K first = itr->first; - Do(first); - Do(itr->second); - --number; - ++itr; - } - } break; - } - } - - template - void Do(std::multimap& x) { - if (mode == MODE_READ) { - for (auto it = x.begin(), end = x.end(); it != end; ++it) { - if (it->second != nullptr) - delete it->second; - } - } - T* dv = nullptr; - DoMultimap(x, dv); - } - - template - void Do(std::multimap& x) { - T dv = T(); - DoMultimap(x, dv); - } - - template - void DoMultimap(std::multimap& x, T& default_val) { - unsigned int number = (unsigned int)x.size(); - Do(number); - switch (mode) { - case MODE_READ: { - x.clear(); - while (number > 0) { - K first = K(); - Do(first); - T second = default_val; - Do(second); - x.insert(std::make_pair(first, second)); - --number; - } - } break; - case MODE_WRITE: - case MODE_MEASURE: - case MODE_VERIFY: { - typename std::multimap::iterator itr = x.begin(); - while (number > 0) { - Do(itr->first); - Do(itr->second); - --number; - ++itr; - } - } break; - } - } - - // Store vectors. - template - void Do(std::vector& x) { - T* dv = nullptr; - DoVector(x, dv); - } - - template - void Do(std::vector& x) { - T dv = T(); - DoVector(x, dv); - } - - template - void DoPOD(std::vector& x) { - T dv = T(); - DoVectorPOD(x, dv); - } - - template - void Do(std::vector& x, T& default_val) { - DoVector(x, default_val); - } - - template - void DoVector(std::vector& x, T& default_val) { - u32 vec_size = (u32)x.size(); - Do(vec_size); - x.resize(vec_size, default_val); - if (vec_size > 0) - DoArray(&x[0], vec_size); - } - - template - void DoVectorPOD(std::vector& x, T& default_val) { - u32 vec_size = (u32)x.size(); - Do(vec_size); - x.resize(vec_size, default_val); - if (vec_size > 0) - DoArray(&x[0], vec_size); - } - - // Store deques. - template - void Do(std::deque& x) { - T* dv = nullptr; - DoDeque(x, dv); - } - - template - void Do(std::deque& x) { - T dv = T(); - DoDeque(x, dv); - } - - template - void DoDeque(std::deque& x, T& default_val) { - u32 deq_size = (u32)x.size(); - Do(deq_size); - x.resize(deq_size, default_val); - u32 i; - for (i = 0; i < deq_size; i++) - Do(x[i]); - } - - // Store STL lists. - template - void Do(std::list& x) { - T* dv = nullptr; - Do(x, dv); - } - - template - void Do(std::list& x) { - T dv = T(); - DoList(x, dv); - } - - template - void Do(std::list& x, T& default_val) { - DoList(x, default_val); - } - - template - void DoList(std::list& x, T& default_val) { - u32 list_size = (u32)x.size(); - Do(list_size); - x.resize(list_size, default_val); - - typename std::list::iterator itr, end; - for (itr = x.begin(), end = x.end(); itr != end; ++itr) - Do(*itr); - } - - // Store STL sets. - template - void Do(std::set& x) { - if (mode == MODE_READ) { - for (auto it = x.begin(), end = x.end(); it != end; ++it) { - if (*it != nullptr) - delete *it; - } - } - DoSet(x); - } - - template - void Do(std::set& x) { - DoSet(x); - } - - template - void DoSet(std::set& x) { - unsigned int number = (unsigned int)x.size(); - Do(number); - - switch (mode) { - case MODE_READ: { - x.clear(); - while (number-- > 0) { - T it = T(); - Do(it); - x.insert(it); - } - } break; - case MODE_WRITE: - case MODE_MEASURE: - case MODE_VERIFY: { - typename std::set::iterator itr = x.begin(); - while (number-- > 0) - Do(*itr++); - } break; - - default: - LOG_ERROR(Common, "Savestate error: invalid mode %d.", mode); - } - } - - // Store strings. - void Do(std::string& x) { - int stringLen = (int)x.length() + 1; - Do(stringLen); - - switch (mode) { - case MODE_READ: - x = (char*)*ptr; - break; - case MODE_WRITE: - memcpy(*ptr, x.c_str(), stringLen); - break; - case MODE_MEASURE: - break; - case MODE_VERIFY: - DEBUG_ASSERT_MSG((x == (char*)*ptr), - "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", - x.c_str(), (char*)*ptr, ptr); - break; - } - (*ptr) += stringLen; - } - - void Do(std::wstring& x) { - int stringLen = sizeof(wchar_t) * ((int)x.length() + 1); - Do(stringLen); - - switch (mode) { - case MODE_READ: - x = (wchar_t*)*ptr; - break; - case MODE_WRITE: - memcpy(*ptr, x.c_str(), stringLen); - break; - case MODE_MEASURE: - break; - case MODE_VERIFY: - DEBUG_ASSERT_MSG((x == (wchar_t*)*ptr), - "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", - x.c_str(), (wchar_t*)*ptr, ptr); - break; - } - (*ptr) += stringLen; - } - - template - void DoClass(T& x) { - x.DoState(*this); - } - - template - void DoClass(T*& x) { - if (mode == MODE_READ) { - if (x != nullptr) - delete x; - x = new T(); - } - x->DoState(*this); - } - - template - void DoArray(T* x, int count) { - DoHelper::DoArray(this, x, count); - } - - template - void Do(T& x) { - DoHelper::Do(this, x); - } - - template - void DoPOD(T& x) { - DoHelper::Do(this, x); - } - - template - void DoPointer(T*& x, T* const base) { - // pointers can be more than 2^31 apart, but you're using this function wrong if you need - // that much range - s32 offset = x - base; - Do(offset); - if (mode == MODE_READ) - x = base + offset; - } - - template * (*TNew)(), void (*TFree)(LinkedListItem*), - void (*TDo)(PointerWrap&, T*)> - void DoLinkedList(LinkedListItem*& list_start, LinkedListItem** list_end = nullptr) { - LinkedListItem* list_cur = list_start; - LinkedListItem* prev = nullptr; - - while (true) { - u8 shouldExist = (list_cur ? 1 : 0); - Do(shouldExist); - if (shouldExist == 1) { - LinkedListItem* cur = list_cur ? list_cur : TNew(); - TDo(*this, (T*)cur); - if (!list_cur) { - if (mode == MODE_READ) { - cur->next = nullptr; - list_cur = cur; - if (prev) - prev->next = cur; - else - list_start = cur; - } else { - TFree(cur); - continue; - } - } - } else { - if (mode == MODE_READ) { - if (prev) - prev->next = nullptr; - if (list_end) - *list_end = prev; - if (list_cur) { - if (list_start == list_cur) - list_start = nullptr; - do { - LinkedListItem* next = list_cur->next; - TFree(list_cur); - list_cur = next; - } while (list_cur); - } - } - break; - } - prev = list_cur; - list_cur = list_cur->next; - } - } - - void DoMarker(const char* prevName, u32 arbitraryNumber = 0x42) { - u32 cookie = arbitraryNumber; - Do(cookie); - if (mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) { - LOG_ERROR(Common, - "After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). " - "Aborting savestate load...", - prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); - SetError(ERROR_FAILURE); - } - } -}; - -inline PointerWrapSection::~PointerWrapSection() { - if (ver_ > 0) { - p_.DoMarker(title_); - } -} diff --git a/src/common/linear_disk_cache.h b/src/common/linear_disk_cache.h deleted file mode 100644 index 94c695163e..0000000000 --- a/src/common/linear_disk_cache.h +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include -#include "common/common_types.h" - -// defined in Version.cpp -extern const char* scm_rev_git_str; - -// On disk format: -// header{ -// u32 'DCAC'; -// u32 version; // svn_rev -// u16 sizeof(key_type); -// u16 sizeof(value_type); -//} - -// key_value_pair{ -// u32 value_size; -// key_type key; -// value_type[value_size] value; -//} - -template -class LinearDiskCacheReader { -public: - virtual void Read(const K& key, const V* value, u32 value_size) = 0; -}; - -// Dead simple unsorted key-value store with append functionality. -// No random read functionality, all reading is done in OpenAndRead. -// Keys and values can contain any characters, including \0. -// -// Suitable for caching generated shader bytecode between executions. -// Not tuned for extreme performance but should be reasonably fast. -// Does not support keys or values larger than 2GB, which should be reasonable. -// Keys must have non-zero length; values can have zero length. - -// K and V are some POD type -// K : the key type -// V : value array type -template -class LinearDiskCache { -public: - // return number of read entries - u32 OpenAndRead(const char* filename, LinearDiskCacheReader& reader) { - using std::ios_base; - - // close any currently opened file - Close(); - m_num_entries = 0; - - // try opening for reading/writing - OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary); - - m_file.seekg(0, std::ios::end); - std::fstream::pos_type end_pos = m_file.tellg(); - m_file.seekg(0, std::ios::beg); - std::fstream::pos_type start_pos = m_file.tellg(); - std::streamoff file_size = end_pos - start_pos; - - if (m_file.is_open() && ValidateHeader()) { - // good header, read some key/value pairs - K key; - - V* value = nullptr; - u32 value_size; - u32 entry_number; - - std::fstream::pos_type last_pos = m_file.tellg(); - - while (Read(&value_size)) { - std::streamoff next_extent = - (last_pos - start_pos) + sizeof(value_size) + value_size; - if (next_extent > file_size) - break; - - delete[] value; - value = new V[value_size]; - - // read key/value and pass to reader - if (Read(&key) && Read(value, value_size) && Read(&entry_number) && - entry_number == m_num_entries + 1) { - reader.Read(key, value, value_size); - } else { - break; - } - - m_num_entries++; - last_pos = m_file.tellg(); - } - m_file.seekp(last_pos); - m_file.clear(); - - delete[] value; - return m_num_entries; - } - - // failed to open file for reading or bad header - // close and recreate file - Close(); - m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary); - WriteHeader(); - return 0; - } - - void Sync() { - m_file.flush(); - } - - void Close() { - if (m_file.is_open()) - m_file.close(); - // clear any error flags - m_file.clear(); - } - - // Appends a key-value pair to the store. - void Append(const K& key, const V* value, u32 value_size) { - // TODO: Should do a check that we don't already have "key"? (I think each caller does that - // already.) - Write(&value_size); - Write(&key); - Write(value, value_size); - m_num_entries++; - Write(&m_num_entries); - } - -private: - void WriteHeader() { - Write(&m_header); - } - - bool ValidateHeader() { - char file_header[sizeof(Header)]; - - return (Read(file_header, sizeof(Header)) && - !memcmp((const char*)&m_header, file_header, sizeof(Header))); - } - - template - bool Write(const D* data, u32 count = 1) { - return m_file.write((const char*)data, count * sizeof(D)).good(); - } - - template - bool Read(const D* data, u32 count = 1) { - return m_file.read((char*)data, count * sizeof(D)).good(); - } - - struct Header { - Header() : id(*(u32*)"DCAC"), key_t_size(sizeof(K)), value_t_size(sizeof(V)) { - memcpy(ver, scm_rev_git_str, 40); - } - - const u32 id; - const u16 key_t_size, value_t_size; - char ver[40]; - - } m_header; - - std::fstream m_file; - u32 m_num_entries; -};