diff options
Diffstat (limited to 'src')
29 files changed, 467 insertions, 765 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 40b1ea4a2..052357be4 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -6,8 +6,6 @@ add_library(core STATIC announce_multiplayer_session.h arm/arm_interface.h arm/arm_interface.cpp - arm/cpu_interrupt_handler.cpp - arm/cpu_interrupt_handler.h arm/dynarmic/arm_dynarmic_32.cpp arm/dynarmic/arm_dynarmic_32.h arm/dynarmic/arm_dynarmic_64.cpp @@ -727,8 +725,6 @@ add_library(core STATIC internal_network/sockets.h loader/deconstructed_rom_directory.cpp loader/deconstructed_rom_directory.h - loader/elf.cpp - loader/elf.h loader/kip.cpp loader/kip.h loader/loader.cpp diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 73f259525..7d62d030e 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -27,7 +27,6 @@ namespace Core { class System; class CPUInterruptHandler; -using CPUInterrupts = std::array<CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>; using WatchpointArray = std::array<Kernel::DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>; /// Generic ARMv8 CPU interface @@ -36,10 +35,8 @@ public: YUZU_NON_COPYABLE(ARM_Interface); YUZU_NON_MOVEABLE(ARM_Interface); - explicit ARM_Interface(System& system_, CPUInterrupts& interrupt_handlers_, - bool uses_wall_clock_) - : system{system_}, interrupt_handlers{interrupt_handlers_}, uses_wall_clock{ - uses_wall_clock_} {} + explicit ARM_Interface(System& system_, bool uses_wall_clock_) + : system{system_}, uses_wall_clock{uses_wall_clock_} {} virtual ~ARM_Interface() = default; struct ThreadContext32 { @@ -181,6 +178,9 @@ public: /// Signal an interrupt and ask the core to halt as soon as possible. virtual void SignalInterrupt() = 0; + /// Clear a previous interrupt. + virtual void ClearInterrupt() = 0; + struct BacktraceEntry { std::string module; u64 address; @@ -208,7 +208,6 @@ public: protected: /// System context that this ARM interface is running under. System& system; - CPUInterrupts& interrupt_handlers; const WatchpointArray* watchpoints; bool uses_wall_clock; diff --git a/src/core/arm/cpu_interrupt_handler.cpp b/src/core/arm/cpu_interrupt_handler.cpp deleted file mode 100644 index 77b6194d7..000000000 --- a/src/core/arm/cpu_interrupt_handler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/thread.h" -#include "core/arm/cpu_interrupt_handler.h" - -namespace Core { - -CPUInterruptHandler::CPUInterruptHandler() : interrupt_event{std::make_unique<Common::Event>()} {} - -CPUInterruptHandler::~CPUInterruptHandler() = default; - -void CPUInterruptHandler::SetInterrupt(bool is_interrupted_) { - if (is_interrupted_) { - interrupt_event->Set(); - } - is_interrupted = is_interrupted_; -} - -void CPUInterruptHandler::AwaitInterrupt() { - interrupt_event->Wait(); -} - -} // namespace Core diff --git a/src/core/arm/cpu_interrupt_handler.h b/src/core/arm/cpu_interrupt_handler.h deleted file mode 100644 index 286e12e53..000000000 --- a/src/core/arm/cpu_interrupt_handler.h +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <atomic> -#include <memory> - -namespace Common { -class Event; -} - -namespace Core { - -class CPUInterruptHandler { -public: - CPUInterruptHandler(); - ~CPUInterruptHandler(); - - CPUInterruptHandler(const CPUInterruptHandler&) = delete; - CPUInterruptHandler& operator=(const CPUInterruptHandler&) = delete; - - CPUInterruptHandler(CPUInterruptHandler&&) = delete; - CPUInterruptHandler& operator=(CPUInterruptHandler&&) = delete; - - bool IsInterrupted() const { - return is_interrupted; - } - - void SetInterrupt(bool is_interrupted); - - void AwaitInterrupt(); - -private: - std::unique_ptr<Common::Event> interrupt_event; - std::atomic_bool is_interrupted{false}; -}; - -} // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index b8d2ce224..1638bc41d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -11,7 +11,6 @@ #include "common/logging/log.h" #include "common/page_table.h" #include "common/settings.h" -#include "core/arm/cpu_interrupt_handler.h" #include "core/arm/dynarmic/arm_dynarmic_32.h" #include "core/arm/dynarmic/arm_dynarmic_cp15.h" #include "core/arm/dynarmic/arm_exclusive_monitor.h" @@ -125,7 +124,9 @@ public: } void AddTicks(u64 ticks) override { - ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + if (parent.uses_wall_clock) { + return; + } // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a // rough approximation of the amount of executed ticks in the system, it may be thrown off @@ -142,7 +143,12 @@ public: } u64 GetTicksRemaining() override { - ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + if (parent.uses_wall_clock) { + if (!IsInterrupted()) { + return minimum_run_cycles; + } + return 0U; + } return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0); } @@ -168,11 +174,15 @@ public: parent.jit.load()->HaltExecution(hr); } + bool IsInterrupted() { + return parent.system.Kernel().PhysicalCore(parent.core_index).IsInterrupted(); + } + ARM_Dynarmic_32& parent; Core::Memory::Memory& memory; std::size_t num_interpreted_instructions{}; bool debugger_enabled{}; - static constexpr u64 minimum_run_cycles = 1000U; + static constexpr u64 minimum_run_cycles = 10000U; }; std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* page_table) const { @@ -200,7 +210,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* // Timing config.wall_clock_cntpct = uses_wall_clock; - config.enable_cycle_counting = !uses_wall_clock; + config.enable_cycle_counting = true; // Code cache size config.code_cache_size = 512_MiB; @@ -311,11 +321,9 @@ void ARM_Dynarmic_32::RewindBreakpointInstruction() { LoadContext(breakpoint_context); } -ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, - bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, - std::size_t core_index_) - : ARM_Interface{system_, interrupt_handlers_, uses_wall_clock_}, - cb(std::make_unique<DynarmicCallbacks32>(*this)), +ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, + ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_) + : ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks32>(*this)), cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index_}, exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {} @@ -394,6 +402,10 @@ void ARM_Dynarmic_32::SignalInterrupt() { jit.load()->HaltExecution(break_loop); } +void ARM_Dynarmic_32::ClearInterrupt() { + jit.load()->ClearHalt(break_loop); +} + void ARM_Dynarmic_32::ClearInstructionCache() { jit.load()->ClearCache(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 346e9abf8..d24ba2289 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -28,8 +28,8 @@ class System; class ARM_Dynarmic_32 final : public ARM_Interface { public: - ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, bool uses_wall_clock_, - ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_); + ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, + std::size_t core_index_); ~ARM_Dynarmic_32() override; void SetPC(u64 pc) override; @@ -56,6 +56,7 @@ public: void LoadContext(const ThreadContext64& ctx) override {} void SignalInterrupt() override; + void ClearInterrupt() override; void ClearExclusiveState() override; void ClearInstructionCache() override; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 1a4d37cbc..921a5a734 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -10,7 +10,6 @@ #include "common/logging/log.h" #include "common/page_table.h" #include "common/settings.h" -#include "core/arm/cpu_interrupt_handler.h" #include "core/arm/dynarmic/arm_dynarmic_64.h" #include "core/arm/dynarmic/arm_exclusive_monitor.h" #include "core/core.h" @@ -166,7 +165,9 @@ public: } void AddTicks(u64 ticks) override { - ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + if (parent.uses_wall_clock) { + return; + } // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a // rough approximation of the amount of executed ticks in the system, it may be thrown off @@ -181,7 +182,12 @@ public: } u64 GetTicksRemaining() override { - ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + if (parent.uses_wall_clock) { + if (!IsInterrupted()) { + return minimum_run_cycles; + } + return 0U; + } return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0); } @@ -211,12 +217,16 @@ public: parent.jit.load()->HaltExecution(hr); } + bool IsInterrupted() { + return parent.system.Kernel().PhysicalCore(parent.core_index).IsInterrupted(); + } + ARM_Dynarmic_64& parent; Core::Memory::Memory& memory; u64 tpidrro_el0 = 0; u64 tpidr_el0 = 0; bool debugger_enabled{}; - static constexpr u64 minimum_run_cycles = 1000U; + static constexpr u64 minimum_run_cycles = 10000U; }; std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* page_table, @@ -260,7 +270,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* // Timing config.wall_clock_cntpct = uses_wall_clock; - config.enable_cycle_counting = !uses_wall_clock; + config.enable_cycle_counting = true; // Code cache size config.code_cache_size = 512_MiB; @@ -371,10 +381,9 @@ void ARM_Dynarmic_64::RewindBreakpointInstruction() { LoadContext(breakpoint_context); } -ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, - bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, - std::size_t core_index_) - : ARM_Interface{system_, interrupt_handlers_, uses_wall_clock_}, +ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, + ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_) + : ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index_}, exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {} @@ -461,6 +470,10 @@ void ARM_Dynarmic_64::SignalInterrupt() { jit.load()->HaltExecution(break_loop); } +void ARM_Dynarmic_64::ClearInterrupt() { + jit.load()->ClearHalt(break_loop); +} + void ARM_Dynarmic_64::ClearInstructionCache() { jit.load()->ClearCache(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index c77a83ad7..ed1a5eb96 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -20,14 +20,13 @@ class Memory; namespace Core { class DynarmicCallbacks64; -class CPUInterruptHandler; class DynarmicExclusiveMonitor; class System; class ARM_Dynarmic_64 final : public ARM_Interface { public: - ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, bool uses_wall_clock_, - ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_); + ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, + std::size_t core_index_); ~ARM_Dynarmic_64() override; void SetPC(u64 pc) override; @@ -50,6 +49,7 @@ public: void LoadContext(const ThreadContext64& ctx) override; void SignalInterrupt() override; + void ClearInterrupt() override; void ClearExclusiveState() override; void ClearInstructionCache() override; diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index ac64d2f9d..e42bdd17d 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp @@ -15,6 +15,7 @@ #include "core/debugger/debugger_interface.h" #include "core/debugger/gdbstub.h" #include "core/hle/kernel/global_scheduler_context.h" +#include "core/hle/kernel/k_scheduler.h" template <typename Readable, typename Buffer, typename Callback> static void AsyncReceiveInto(Readable& r, Buffer& buffer, Callback&& c) { @@ -230,13 +231,12 @@ private: } void PauseEmulation() { + Kernel::KScopedSchedulerLock sl{system.Kernel()}; + // Put all threads to sleep on next scheduler round. for (auto* thread : ThreadList()) { thread->RequestSuspend(Kernel::SuspendType::Debug); } - - // Signal an interrupt so that scheduler will fire. - system.Kernel().InterruptAllPhysicalCores(); } void ResumeEmulation(Kernel::KThread* except = nullptr) { @@ -253,7 +253,8 @@ private: template <typename Callback> void MarkResumed(Callback&& cb) { - std::scoped_lock lk{connection_lock}; + Kernel::KScopedSchedulerLock sl{system.Kernel()}; + std::scoped_lock cl{connection_lock}; stopped = false; cb(); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index f4072e1c3..ce7fa8275 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -17,7 +17,6 @@ #include "common/thread.h" #include "common/thread_worker.h" #include "core/arm/arm_interface.h" -#include "core/arm/cpu_interrupt_handler.h" #include "core/arm/exclusive_monitor.h" #include "core/core.h" #include "core/core_timing.h" @@ -82,7 +81,7 @@ struct KernelCore::Impl { void InitializeCores() { for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { - cores[core_id].Initialize((*current_process).Is64BitProcess()); + cores[core_id]->Initialize((*current_process).Is64BitProcess()); system.Memory().SetCurrentPageTable(*current_process, core_id); } } @@ -100,7 +99,9 @@ struct KernelCore::Impl { next_user_process_id = KProcess::ProcessIDMin; next_thread_id = 1; - cores.clear(); + for (auto& core : cores) { + core = nullptr; + } global_handle_table->Finalize(); global_handle_table.reset(); @@ -199,7 +200,7 @@ struct KernelCore::Impl { const s32 core{static_cast<s32>(i)}; schedulers[i] = std::make_unique<Kernel::KScheduler>(system.Kernel()); - cores.emplace_back(i, system, *schedulers[i], interrupts); + cores[i] = std::make_unique<Kernel::PhysicalCore>(i, system, *schedulers[i]); auto* main_thread{Kernel::KThread::Create(system.Kernel())}; main_thread->SetName(fmt::format("MainThread:{}", core)); @@ -761,7 +762,7 @@ struct KernelCore::Impl { std::unordered_set<KAutoObject*> registered_in_use_objects; std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; - std::vector<Kernel::PhysicalCore> cores; + std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores; // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others std::atomic<u32> next_host_thread_id{Core::Hardware::NUM_CPU_CORES}; @@ -785,7 +786,6 @@ struct KernelCore::Impl { Common::ThreadWorker service_threads_manager; std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads; - std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; bool is_multicore{}; @@ -874,11 +874,11 @@ const Kernel::KScheduler& KernelCore::Scheduler(std::size_t id) const { } Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) { - return impl->cores[id]; + return *impl->cores[id]; } const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const { - return impl->cores[id]; + return *impl->cores[id]; } size_t KernelCore::CurrentPhysicalCoreIndex() const { @@ -890,11 +890,11 @@ size_t KernelCore::CurrentPhysicalCoreIndex() const { } Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() { - return impl->cores[CurrentPhysicalCoreIndex()]; + return *impl->cores[CurrentPhysicalCoreIndex()]; } const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const { - return impl->cores[CurrentPhysicalCoreIndex()]; + return *impl->cores[CurrentPhysicalCoreIndex()]; } Kernel::KScheduler* KernelCore::CurrentScheduler() { @@ -906,15 +906,6 @@ Kernel::KScheduler* KernelCore::CurrentScheduler() { return impl->schedulers[core_id].get(); } -std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() { - return impl->interrupts; -} - -const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() - const { - return impl->interrupts; -} - Kernel::TimeManager& KernelCore::TimeManager() { return impl->time_manager; } @@ -939,24 +930,18 @@ const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const { return *impl->global_object_list_container; } -void KernelCore::InterruptAllPhysicalCores() { - for (auto& physical_core : impl->cores) { - physical_core.Interrupt(); - } -} - void KernelCore::InvalidateAllInstructionCaches() { for (auto& physical_core : impl->cores) { - physical_core.ArmInterface().ClearInstructionCache(); + physical_core->ArmInterface().ClearInstructionCache(); } } void KernelCore::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { for (auto& physical_core : impl->cores) { - if (!physical_core.IsInitialized()) { + if (!physical_core->IsInitialized()) { continue; } - physical_core.ArmInterface().InvalidateCacheRange(addr, size); + physical_core->ArmInterface().InvalidateCacheRange(addr, size); } } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 6c7cf6af2..bcf016a97 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -9,14 +9,12 @@ #include <string> #include <unordered_map> #include <vector> -#include "core/arm/cpu_interrupt_handler.h" #include "core/hardware_properties.h" #include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_slab_heap.h" #include "core/hle/kernel/svc_common.h" namespace Core { -class CPUInterruptHandler; class ExclusiveMonitor; class System; } // namespace Core @@ -183,12 +181,6 @@ public: const KAutoObjectWithListContainer& ObjectListContainer() const; - std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts(); - - const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const; - - void InterruptAllPhysicalCores(); - void InvalidateAllInstructionCaches(); void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp index 6e7dacf97..d4375962f 100644 --- a/src/core/hle/kernel/physical_core.cpp +++ b/src/core/hle/kernel/physical_core.cpp @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/arm/cpu_interrupt_handler.h" #include "core/arm/dynarmic/arm_dynarmic_32.h" #include "core/arm/dynarmic/arm_dynarmic_64.h" #include "core/core.h" @@ -11,16 +10,14 @@ namespace Kernel { -PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_, - Core::CPUInterrupts& interrupts_) - : core_index{core_index_}, system{system_}, scheduler{scheduler_}, - interrupts{interrupts_}, guard{std::make_unique<std::mutex>()} { +PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_) + : core_index{core_index_}, system{system_}, scheduler{scheduler_} { #ifdef ARCHITECTURE_x86_64 // TODO(bunnei): Initialization relies on a core being available. We may later replace this with // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager. auto& kernel = system.Kernel(); arm_interface = std::make_unique<Core::ARM_Dynarmic_64>( - system, interrupts, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index); + system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index); #else #error Platform not supported yet. #endif @@ -34,7 +31,7 @@ void PhysicalCore::Initialize([[maybe_unused]] bool is_64_bit) { if (!is_64_bit) { // We already initialized a 64-bit core, replace with a 32-bit one. arm_interface = std::make_unique<Core::ARM_Dynarmic_32>( - system, interrupts, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index); + system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index); } #else #error Platform not supported yet. @@ -47,24 +44,26 @@ void PhysicalCore::Run() { } void PhysicalCore::Idle() { - interrupts[core_index].AwaitInterrupt(); + std::unique_lock lk{guard}; + on_interrupt.wait(lk, [this] { return is_interrupted; }); } bool PhysicalCore::IsInterrupted() const { - return interrupts[core_index].IsInterrupted(); + return is_interrupted; } void PhysicalCore::Interrupt() { - guard->lock(); - interrupts[core_index].SetInterrupt(true); + std::unique_lock lk{guard}; + is_interrupted = true; arm_interface->SignalInterrupt(); - guard->unlock(); + on_interrupt.notify_all(); } void PhysicalCore::ClearInterrupt() { - guard->lock(); - interrupts[core_index].SetInterrupt(false); - guard->unlock(); + std::unique_lock lk{guard}; + is_interrupted = false; + arm_interface->ClearInterrupt(); + on_interrupt.notify_all(); } } // namespace Kernel diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index 898d1e5db..2fc8d4be2 100644 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h @@ -14,7 +14,6 @@ class KScheduler; } // namespace Kernel namespace Core { -class CPUInterruptHandler; class ExclusiveMonitor; class System; } // namespace Core @@ -23,15 +22,11 @@ namespace Kernel { class PhysicalCore { public: - PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_, - Core::CPUInterrupts& interrupts_); + PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_); ~PhysicalCore(); - PhysicalCore(const PhysicalCore&) = delete; - PhysicalCore& operator=(const PhysicalCore&) = delete; - - PhysicalCore(PhysicalCore&&) = default; - PhysicalCore& operator=(PhysicalCore&&) = delete; + YUZU_NON_COPYABLE(PhysicalCore); + YUZU_NON_MOVEABLE(PhysicalCore); /// Initialize the core for the specified parameters. void Initialize(bool is_64_bit); @@ -86,9 +81,11 @@ private: const std::size_t core_index; Core::System& system; Kernel::KScheduler& scheduler; - Core::CPUInterrupts& interrupts; - std::unique_ptr<std::mutex> guard; + + std::mutex guard; + std::condition_variable on_interrupt; std::unique_ptr<Core::ARM_Interface> arm_interface; + bool is_interrupted; }; } // namespace Kernel diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp deleted file mode 100644 index dfb10c34f..000000000 --- a/src/core/loader/elf.cpp +++ /dev/null @@ -1,263 +0,0 @@ -// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project -// SPDX-FileCopyrightText: 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <cstring> -#include <memory> -#include "common/common_funcs.h" -#include "common/common_types.h" -#include "common/elf.h" -#include "common/logging/log.h" -#include "core/hle/kernel/code_set.h" -#include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" -#include "core/loader/elf.h" -#include "core/memory.h" - -using namespace Common::ELF; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// ElfReader class - -typedef int SectionID; - -class ElfReader { -private: - char* base; - u32* base32; - - Elf32_Ehdr* header; - Elf32_Phdr* segments; - Elf32_Shdr* sections; - - u32* sectionAddrs; - bool relocate; - VAddr entryPoint; - -public: - explicit ElfReader(void* ptr); - - u32 Read32(int off) const { - return base32[off >> 2]; - } - - // Quick accessors - u16 GetType() const { - return header->e_type; - } - u16 GetMachine() const { - return header->e_machine; - } - VAddr GetEntryPoint() const { - return entryPoint; - } - u32 GetFlags() const { - return (u32)(header->e_flags); - } - Kernel::CodeSet LoadInto(VAddr vaddr); - - int GetNumSegments() const { - return (int)(header->e_phnum); - } - int GetNumSections() const { - return (int)(header->e_shnum); - } - const u8* GetPtr(int offset) const { - return (u8*)base + offset; - } - const char* GetSectionName(int section) const; - const u8* GetSectionDataPtr(int section) const { - if (section < 0 || section >= header->e_shnum) - return nullptr; - if (sections[section].sh_type != ElfShtNobits) - return GetPtr(sections[section].sh_offset); - else - return nullptr; - } - bool IsCodeSection(int section) const { - return sections[section].sh_type == ElfShtProgBits; - } - const u8* GetSegmentPtr(int segment) { - return GetPtr(segments[segment].p_offset); - } - u32 GetSectionAddr(SectionID section) const { - return sectionAddrs[section]; - } - unsigned int GetSectionSize(SectionID section) const { - return sections[section].sh_size; - } - SectionID GetSectionByName(const char* name, int firstSection = 0) const; //-1 for not found - - bool DidRelocate() const { - return relocate; - } -}; - -ElfReader::ElfReader(void* ptr) { - base = (char*)ptr; - base32 = (u32*)ptr; - header = (Elf32_Ehdr*)ptr; - - segments = (Elf32_Phdr*)(base + header->e_phoff); - sections = (Elf32_Shdr*)(base + header->e_shoff); - - entryPoint = header->e_entry; -} - -const char* ElfReader::GetSectionName(int section) const { - if (sections[section].sh_type == ElfShtNull) - return nullptr; - - int name_offset = sections[section].sh_name; - const char* ptr = reinterpret_cast<const char*>(GetSectionDataPtr(header->e_shstrndx)); - - if (ptr) - return ptr + name_offset; - - return nullptr; -} - -Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { - LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx); - - // Should we relocate? - relocate = (header->e_type != ElfTypeExec); - - if (relocate) { - LOG_DEBUG(Loader, "Relocatable module"); - entryPoint += vaddr; - } else { - LOG_DEBUG(Loader, "Prerelocated executable"); - } - LOG_DEBUG(Loader, "{} segments:", header->e_phnum); - - // First pass : Get the bits into RAM - const VAddr base_addr = relocate ? vaddr : 0; - - u64 total_image_size = 0; - for (unsigned int i = 0; i < header->e_phnum; ++i) { - const Elf32_Phdr* p = &segments[i]; - if (p->p_type == ElfPtLoad) { - total_image_size += (p->p_memsz + 0xFFF) & ~0xFFF; - } - } - - Kernel::PhysicalMemory program_image(total_image_size); - std::size_t current_image_position = 0; - - Kernel::CodeSet codeset; - - for (unsigned int i = 0; i < header->e_phnum; ++i) { - const Elf32_Phdr* p = &segments[i]; - LOG_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 == ElfPtLoad) { - Kernel::CodeSet::Segment* codeset_segment; - u32 permission_flags = p->p_flags & (ElfPfRead | ElfPfWrite | ElfPfExec); - if (permission_flags == (ElfPfRead | ElfPfExec)) { - codeset_segment = &codeset.CodeSegment(); - } else if (permission_flags == (ElfPfRead)) { - codeset_segment = &codeset.RODataSegment(); - } else if (permission_flags == (ElfPfRead | ElfPfWrite)) { - codeset_segment = &codeset.DataSegment(); - } else { - LOG_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); - continue; - } - - const VAddr segment_addr = base_addr + p->p_vaddr; - const u32 aligned_size = (p->p_memsz + 0xFFF) & ~0xFFF; - - codeset_segment->offset = current_image_position; - codeset_segment->addr = segment_addr; - codeset_segment->size = aligned_size; - - std::memcpy(program_image.data() + current_image_position, GetSegmentPtr(i), - p->p_filesz); - current_image_position += aligned_size; - } - } - - codeset.entrypoint = base_addr + header->e_entry; - codeset.memory = std::move(program_image); - - LOG_DEBUG(Loader, "Done loading."); - - return codeset; -} - -SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const { - for (int i = firstSection; i < header->e_shnum; i++) { - const char* secname = GetSectionName(i); - - if (secname != nullptr && strcmp(name, secname) == 0) - return i; - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Loader namespace - -namespace Loader { - -AppLoader_ELF::AppLoader_ELF(FileSys::VirtualFile file_) : AppLoader(std::move(file_)) {} - -FileType AppLoader_ELF::IdentifyType(const FileSys::VirtualFile& elf_file) { - static constexpr u16 ELF_MACHINE_ARM{0x28}; - - u32 magic = 0; - if (4 != elf_file->ReadObject(&magic)) { - return FileType::Error; - } - - u16 machine = 0; - if (2 != elf_file->ReadObject(&machine, 18)) { - return FileType::Error; - } - - if (Common::MakeMagic('\x7f', 'E', 'L', 'F') == magic && ELF_MACHINE_ARM == machine) { - return FileType::ELF; - } - - return FileType::Error; -} - -AppLoader_ELF::LoadResult AppLoader_ELF::Load(Kernel::KProcess& process, - [[maybe_unused]] Core::System& system) { - if (is_loaded) { - return {ResultStatus::ErrorAlreadyLoaded, {}}; - } - - std::vector<u8> buffer = file->ReadAllBytes(); - if (buffer.size() != file->GetSize()) { - return {ResultStatus::ErrorIncorrectELFFileSize, {}}; - } - - const VAddr base_address = process.PageTable().GetCodeRegionStart(); - ElfReader elf_reader(&buffer[0]); - Kernel::CodeSet codeset = elf_reader.LoadInto(base_address); - const VAddr entry_point = codeset.entrypoint; - - // Setup the process code layout - if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), buffer.size()).IsError()) { - return {ResultStatus::ErrorNotInitialized, {}}; - } - - process.LoadModule(std::move(codeset), entry_point); - - is_loaded = true; - return {ResultStatus::Success, LoadParameters{48, Core::Memory::DEFAULT_STACK_SIZE}}; -} - -} // namespace Loader diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h deleted file mode 100644 index acd33dc3d..000000000 --- a/src/core/loader/elf.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project -// SPDX-FileCopyrightText: 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/loader/loader.h" - -namespace Core { -class System; -} - -namespace Loader { - -/// Loads an ELF/AXF file -class AppLoader_ELF final : public AppLoader { -public: - explicit AppLoader_ELF(FileSys::VirtualFile file); - - /** - * Identifies whether or not the given file is an ELF file. - * - * @param elf_file The file to identify. - * - * @return FileType::ELF, or FileType::Error if the file is not an ELF file. - */ - static FileType IdentifyType(const FileSys::VirtualFile& elf_file); - - FileType GetFileType() const override { - return IdentifyType(file); - } - - LoadResult Load(Kernel::KProcess& process, Core::System& system) override; -}; - -} // namespace Loader diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 994ee891f..104d16efa 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -12,7 +12,6 @@ #include "core/core.h" #include "core/hle/kernel/k_process.h" #include "core/loader/deconstructed_rom_directory.h" -#include "core/loader/elf.h" #include "core/loader/kip.h" #include "core/loader/nax.h" #include "core/loader/nca.h" @@ -39,8 +38,6 @@ std::optional<FileType> IdentifyFileLoader(FileSys::VirtualFile file) { FileType IdentifyFile(FileSys::VirtualFile file) { if (const auto romdir_type = IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) { return *romdir_type; - } else if (const auto elf_type = IdentifyFileLoader<AppLoader_ELF>(file)) { - return *elf_type; } else if (const auto nso_type = IdentifyFileLoader<AppLoader_NSO>(file)) { return *nso_type; } else if (const auto nro_type = IdentifyFileLoader<AppLoader_NRO>(file)) { @@ -69,8 +66,6 @@ FileType GuessFromFilename(const std::string& name) { const std::string extension = Common::ToLower(std::string(Common::FS::GetExtensionFromFilename(name))); - if (extension == "elf") - return FileType::ELF; if (extension == "nro") return FileType::NRO; if (extension == "nso") @@ -89,8 +84,6 @@ FileType GuessFromFilename(const std::string& name) { std::string GetFileTypeString(FileType type) { switch (type) { - case FileType::ELF: - return "ELF"; case FileType::NRO: return "NRO"; case FileType::NSO: @@ -208,10 +201,6 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V FileType type, u64 program_id, std::size_t program_index) { switch (type) { - // Standard ELF file format. - case FileType::ELF: - return std::make_unique<AppLoader_ELF>(std::move(file)); - // NX NSO file format. case FileType::NSO: return std::make_unique<AppLoader_NSO>(std::move(file)); diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 7bf4faaf1..7b43f70ed 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -34,7 +34,6 @@ namespace Loader { enum class FileType { Error, Unknown, - ELF, NSO, NRO, NCA, diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index d4a49ea99..98dd9035a 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -1306,7 +1306,7 @@ void EmitContext::DefineInputs(const IR::Program& program) { subgroup_mask_gt = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupGtMaskKHR); subgroup_mask_ge = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupGeMaskKHR); } - if (info.uses_subgroup_invocation_id || info.uses_subgroup_shuffles || + if (info.uses_fswzadd || info.uses_subgroup_invocation_id || info.uses_subgroup_shuffles || (profile.warp_size_potentially_larger_than_guest && (info.uses_subgroup_vote || info.uses_subgroup_mask))) { subgroup_local_invocation_id = @@ -1411,7 +1411,8 @@ void EmitContext::DefineInputs(const IR::Program& program) { void EmitContext::DefineOutputs(const IR::Program& program) { const Info& info{program.info}; const std::optional<u32> invocations{program.invocations}; - if (info.stores.AnyComponent(IR::Attribute::PositionX) || stage == Stage::VertexB) { + if (runtime_info.convert_depth_mode || info.stores.AnyComponent(IR::Attribute::PositionX) || + stage == Stage::VertexB) { output_position = DefineOutput(*this, F32[4], invocations, spv::BuiltIn::Position); } if (info.stores[IR::Attribute::PointSize] || runtime_info.fixed_state_point_size) { diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 689164a6a..7d1431b6d 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -317,195 +317,204 @@ VkPrimitiveTopology PrimitiveTopology([[maybe_unused]] const Device& device, } } -VkFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size) { - switch (type) { - case Maxwell::VertexAttribute::Type::UnsignedNorm: - switch (size) { - case Maxwell::VertexAttribute::Size::Size_8: - return VK_FORMAT_R8_UNORM; - case Maxwell::VertexAttribute::Size::Size_8_8: - return VK_FORMAT_R8G8_UNORM; - case Maxwell::VertexAttribute::Size::Size_8_8_8: - return VK_FORMAT_R8G8B8_UNORM; - case Maxwell::VertexAttribute::Size::Size_8_8_8_8: - return VK_FORMAT_R8G8B8A8_UNORM; - case Maxwell::VertexAttribute::Size::Size_16: - return VK_FORMAT_R16_UNORM; - case Maxwell::VertexAttribute::Size::Size_16_16: - return VK_FORMAT_R16G16_UNORM; - case Maxwell::VertexAttribute::Size::Size_16_16_16: - return VK_FORMAT_R16G16B16_UNORM; - case Maxwell::VertexAttribute::Size::Size_16_16_16_16: - return VK_FORMAT_R16G16B16A16_UNORM; - case Maxwell::VertexAttribute::Size::Size_10_10_10_2: - return VK_FORMAT_A2B10G10R10_UNORM_PACK32; - default: +VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type, + Maxwell::VertexAttribute::Size size) { + const VkFormat format{([&]() { + switch (type) { + case Maxwell::VertexAttribute::Type::UnsignedNorm: + switch (size) { + case Maxwell::VertexAttribute::Size::Size_8: + return VK_FORMAT_R8_UNORM; + case Maxwell::VertexAttribute::Size::Size_8_8: + return VK_FORMAT_R8G8_UNORM; + case Maxwell::VertexAttribute::Size::Size_8_8_8: + return VK_FORMAT_R8G8B8_UNORM; + case Maxwell::VertexAttribute::Size::Size_8_8_8_8: + return VK_FORMAT_R8G8B8A8_UNORM; + case Maxwell::VertexAttribute::Size::Size_16: + return VK_FORMAT_R16_UNORM; + case Maxwell::VertexAttribute::Size::Size_16_16: + return VK_FORMAT_R16G16_UNORM; + case Maxwell::VertexAttribute::Size::Size_16_16_16: + return VK_FORMAT_R16G16B16_UNORM; + case Maxwell::VertexAttribute::Size::Size_16_16_16_16: + return VK_FORMAT_R16G16B16A16_UNORM; + case Maxwell::VertexAttribute::Size::Size_10_10_10_2: + return VK_FORMAT_A2B10G10R10_UNORM_PACK32; + default: + break; + } break; - } - break; - case Maxwell::VertexAttribute::Type::SignedNorm: - switch (size) { - case Maxwell::VertexAttribute::Size::Size_8: - return VK_FORMAT_R8_SNORM; - case Maxwell::VertexAttribute::Size::Size_8_8: - return VK_FORMAT_R8G8_SNORM; - case Maxwell::VertexAttribute::Size::Size_8_8_8: - return VK_FORMAT_R8G8B8_SNORM; - case Maxwell::VertexAttribute::Size::Size_8_8_8_8: - return VK_FORMAT_R8G8B8A8_SNORM; - case Maxwell::VertexAttribute::Size::Size_16: - return VK_FORMAT_R16_SNORM; - case Maxwell::VertexAttribute::Size::Size_16_16: - return VK_FORMAT_R16G16_SNORM; - case Maxwell::VertexAttribute::Size::Size_16_16_16: - return VK_FORMAT_R16G16B16_SNORM; - case Maxwell::VertexAttribute::Size::Size_16_16_16_16: - return VK_FORMAT_R16G16B16A16_SNORM; - case Maxwell::VertexAttribute::Size::Size_10_10_10_2: - return VK_FORMAT_A2B10G10R10_SNORM_PACK32; - default: + case Maxwell::VertexAttribute::Type::SignedNorm: + switch (size) { + case Maxwell::VertexAttribute::Size::Size_8: + return VK_FORMAT_R8_SNORM; + case Maxwell::VertexAttribute::Size::Size_8_8: + return VK_FORMAT_R8G8_SNORM; + case Maxwell::VertexAttribute::Size::Size_8_8_8: + return VK_FORMAT_R8G8B8_SNORM; + case Maxwell::VertexAttribute::Size::Size_8_8_8_8: + return VK_FORMAT_R8G8B8A8_SNORM; + case Maxwell::VertexAttribute::Size::Size_16: + return VK_FORMAT_R16_SNORM; + case Maxwell::VertexAttribute::Size::Size_16_16: + return VK_FORMAT_R16G16_SNORM; + case Maxwell::VertexAttribute::Size::Size_16_16_16: + return VK_FORMAT_R16G16B16_SNORM; + case Maxwell::VertexAttribute::Size::Size_16_16_16_16: + return VK_FORMAT_R16G16B16A16_SNORM; + case Maxwell::VertexAttribute::Size::Size_10_10_10_2: + return VK_FORMAT_A2B10G10R10_SNORM_PACK32; + default: + break; + } break; - } - break; - case Maxwell::VertexAttribute::Type::UnsignedScaled: - switch (size) { - case Maxwell::VertexAttribute::Size::Size_8: - return VK_FORMAT_R8_USCALED; - case Maxwell::VertexAttribute::Size::Size_8_8: - return VK_FORMAT_R8G8_USCALED; - case Maxwell::VertexAttribute::Size::Size_8_8_8: - return VK_FORMAT_R8G8B8_USCALED; - case Maxwell::VertexAttribute::Size::Size_8_8_8_8: - return VK_FORMAT_R8G8B8A8_USCALED; - case Maxwell::VertexAttribute::Size::Size_16: - return VK_FORMAT_R16_USCALED; - case Maxwell::VertexAttribute::Size::Size_16_16: - return VK_FORMAT_R16G16_USCALED; - case Maxwell::VertexAttribute::Size::Size_16_16_16: - return VK_FORMAT_R16G16B16_USCALED; - case Maxwell::VertexAttribute::Size::Size_16_16_16_16: - return VK_FORMAT_R16G16B16A16_USCALED; - case Maxwell::VertexAttribute::Size::Size_10_10_10_2: - return VK_FORMAT_A2B10G10R10_USCALED_PACK32; - default: + case Maxwell::VertexAttribute::Type::UnsignedScaled: + switch (size) { + case Maxwell::VertexAttribute::Size::Size_8: + return VK_FORMAT_R8_USCALED; + case Maxwell::VertexAttribute::Size::Size_8_8: + return VK_FORMAT_R8G8_USCALED; + case Maxwell::VertexAttribute::Size::Size_8_8_8: + return VK_FORMAT_R8G8B8_USCALED; + case Maxwell::VertexAttribute::Size::Size_8_8_8_8: + return VK_FORMAT_R8G8B8A8_USCALED; + case Maxwell::VertexAttribute::Size::Size_16: + return VK_FORMAT_R16_USCALED; + case Maxwell::VertexAttribute::Size::Size_16_16: + return VK_FORMAT_R16G16_USCALED; + case Maxwell::VertexAttribute::Size::Size_16_16_16: + return VK_FORMAT_R16G16B16_USCALED; + case Maxwell::VertexAttribute::Size::Size_16_16_16_16: + return VK_FORMAT_R16G16B16A16_USCALED; + case Maxwell::VertexAttribute::Size::Size_10_10_10_2: + return VK_FORMAT_A2B10G10R10_USCALED_PACK32; + default: + break; + } break; - } - break; - case Maxwell::VertexAttribute::Type::SignedScaled: - switch (size) { - case Maxwell::VertexAttribute::Size::Size_8: - return VK_FORMAT_R8_SSCALED; - case Maxwell::VertexAttribute::Size::Size_8_8: - return VK_FORMAT_R8G8_SSCALED; - case Maxwell::VertexAttribute::Size::Size_8_8_8: - return VK_FORMAT_R8G8B8_SSCALED; - case Maxwell::VertexAttribute::Size::Size_8_8_8_8: - return VK_FORMAT_R8G8B8A8_SSCALED; - case Maxwell::VertexAttribute::Size::Size_16: - return VK_FORMAT_R16_SSCALED; - case Maxwell::VertexAttribute::Size::Size_16_16: - return VK_FORMAT_R16G16_SSCALED; - case Maxwell::VertexAttribute::Size::Size_16_16_16: - return VK_FORMAT_R16G16B16_SSCALED; - case Maxwell::VertexAttribute::Size::Size_16_16_16_16: - return VK_FORMAT_R16G16B16A16_SSCALED; - case Maxwell::VertexAttribute::Size::Size_10_10_10_2: - return VK_FORMAT_A2B10G10R10_SSCALED_PACK32; - default: + case Maxwell::VertexAttribute::Type::SignedScaled: + switch (size) { + case Maxwell::VertexAttribute::Size::Size_8: + return VK_FORMAT_R8_SSCALED; + case Maxwell::VertexAttribute::Size::Size_8_8: + return VK_FORMAT_R8G8_SSCALED; + case Maxwell::VertexAttribute::Size::Size_8_8_8: + return VK_FORMAT_R8G8B8_SSCALED; + case Maxwell::VertexAttribute::Size::Size_8_8_8_8: + return VK_FORMAT_R8G8B8A8_SSCALED; + case Maxwell::VertexAttribute::Size::Size_16: + return VK_FORMAT_R16_SSCALED; + case Maxwell::VertexAttribute::Size::Size_16_16: + return VK_FORMAT_R16G16_SSCALED; + case Maxwell::VertexAttribute::Size::Size_16_16_16: + return VK_FORMAT_R16G16B16_SSCALED; + case Maxwell::VertexAttribute::Size::Size_16_16_16_16: + return VK_FORMAT_R16G16B16A16_SSCALED; + case Maxwell::VertexAttribute::Size::Size_10_10_10_2: + return VK_FORMAT_A2B10G10R10_SSCALED_PACK32; + default: + break; + } break; - } - break; - case Maxwell::VertexAttribute::Type::UnsignedInt: - switch (size) { - case Maxwell::VertexAttribute::Size::Size_8: - return VK_FORMAT_R8_UINT; - case Maxwell::VertexAttribute::Size::Size_8_8: - return VK_FORMAT_R8G8_UINT; - case Maxwell::VertexAttribute::Size::Size_8_8_8: - return VK_FORMAT_R8G8B8_UINT; - case Maxwell::VertexAttribute::Size::Size_8_8_8_8: - return VK_FORMAT_R8G8B8A8_UINT; - case Maxwell::VertexAttribute::Size::Size_16: - return VK_FORMAT_R16_UINT; - case Maxwell::VertexAttribute::Size::Size_16_16: - return VK_FORMAT_R16G16_UINT; - case Maxwell::VertexAttribute::Size::Size_16_16_16: - return VK_FORMAT_R16G16B16_UINT; - case Maxwell::VertexAttribute::Size::Size_16_16_16_16: - return VK_FORMAT_R16G16B16A16_UINT; - case Maxwell::VertexAttribute::Size::Size_32: - return VK_FORMAT_R32_UINT; - case Maxwell::VertexAttribute::Size::Size_32_32: - return VK_FORMAT_R32G32_UINT; - case Maxwell::VertexAttribute::Size::Size_32_32_32: - return VK_FORMAT_R32G32B32_UINT; - case Maxwell::VertexAttribute::Size::Size_32_32_32_32: - return VK_FORMAT_R32G32B32A32_UINT; - case Maxwell::VertexAttribute::Size::Size_10_10_10_2: - return VK_FORMAT_A2B10G10R10_UINT_PACK32; - default: + case Maxwell::VertexAttribute::Type::UnsignedInt: + switch (size) { + case Maxwell::VertexAttribute::Size::Size_8: + return VK_FORMAT_R8_UINT; + case Maxwell::VertexAttribute::Size::Size_8_8: + return VK_FORMAT_R8G8_UINT; + case Maxwell::VertexAttribute::Size::Size_8_8_8: + return VK_FORMAT_R8G8B8_UINT; + case Maxwell::VertexAttribute::Size::Size_8_8_8_8: + return VK_FORMAT_R8G8B8A8_UINT; + case Maxwell::VertexAttribute::Size::Size_16: + return VK_FORMAT_R16_UINT; + case Maxwell::VertexAttribute::Size::Size_16_16: + return VK_FORMAT_R16G16_UINT; + case Maxwell::VertexAttribute::Size::Size_16_16_16: + return VK_FORMAT_R16G16B16_UINT; + case Maxwell::VertexAttribute::Size::Size_16_16_16_16: + return VK_FORMAT_R16G16B16A16_UINT; + case Maxwell::VertexAttribute::Size::Size_32: + return VK_FORMAT_R32_UINT; + case Maxwell::VertexAttribute::Size::Size_32_32: + return VK_FORMAT_R32G32_UINT; + case Maxwell::VertexAttribute::Size::Size_32_32_32: + return VK_FORMAT_R32G32B32_UINT; + case Maxwell::VertexAttribute::Size::Size_32_32_32_32: + return VK_FORMAT_R32G32B32A32_UINT; + case Maxwell::VertexAttribute::Size::Size_10_10_10_2: + return VK_FORMAT_A2B10G10R10_UINT_PACK32; + default: + break; + } break; - } - break; - case Maxwell::VertexAttribute::Type::SignedInt: - switch (size) { - case Maxwell::VertexAttribute::Size::Size_8: - return VK_FORMAT_R8_SINT; - case Maxwell::VertexAttribute::Size::Size_8_8: - return VK_FORMAT_R8G8_SINT; - case Maxwell::VertexAttribute::Size::Size_8_8_8: - return VK_FORMAT_R8G8B8_SINT; - case Maxwell::VertexAttribute::Size::Size_8_8_8_8: - return VK_FORMAT_R8G8B8A8_SINT; - case Maxwell::VertexAttribute::Size::Size_16: - return VK_FORMAT_R16_SINT; - case Maxwell::VertexAttribute::Size::Size_16_16: - return VK_FORMAT_R16G16_SINT; - case Maxwell::VertexAttribute::Size::Size_16_16_16: - return VK_FORMAT_R16G16B16_SINT; - case Maxwell::VertexAttribute::Size::Size_16_16_16_16: - return VK_FORMAT_R16G16B16A16_SINT; - case Maxwell::VertexAttribute::Size::Size_32: - return VK_FORMAT_R32_SINT; - case Maxwell::VertexAttribute::Size::Size_32_32: - return VK_FORMAT_R32G32_SINT; - case Maxwell::VertexAttribute::Size::Size_32_32_32: - return VK_FORMAT_R32G32B32_SINT; - case Maxwell::VertexAttribute::Size::Size_32_32_32_32: - return VK_FORMAT_R32G32B32A32_SINT; - case Maxwell::VertexAttribute::Size::Size_10_10_10_2: - return VK_FORMAT_A2B10G10R10_SINT_PACK32; - default: + case Maxwell::VertexAttribute::Type::SignedInt: + switch (size) { + case Maxwell::VertexAttribute::Size::Size_8: + return VK_FORMAT_R8_SINT; + case Maxwell::VertexAttribute::Size::Size_8_8: + return VK_FORMAT_R8G8_SINT; + case Maxwell::VertexAttribute::Size::Size_8_8_8: + return VK_FORMAT_R8G8B8_SINT; + case Maxwell::VertexAttribute::Size::Size_8_8_8_8: + return VK_FORMAT_R8G8B8A8_SINT; + case Maxwell::VertexAttribute::Size::Size_16: + return VK_FORMAT_R16_SINT; + case Maxwell::VertexAttribute::Size::Size_16_16: + return VK_FORMAT_R16G16_SINT; + case Maxwell::VertexAttribute::Size::Size_16_16_16: + return VK_FORMAT_R16G16B16_SINT; + case Maxwell::VertexAttribute::Size::Size_16_16_16_16: + return VK_FORMAT_R16G16B16A16_SINT; + case Maxwell::VertexAttribute::Size::Size_32: + return VK_FORMAT_R32_SINT; + case Maxwell::VertexAttribute::Size::Size_32_32: + return VK_FORMAT_R32G32_SINT; + case Maxwell::VertexAttribute::Size::Size_32_32_32: + return VK_FORMAT_R32G32B32_SINT; + case Maxwell::VertexAttribute::Size::Size_32_32_32_32: + return VK_FORMAT_R32G32B32A32_SINT; + case Maxwell::VertexAttribute::Size::Size_10_10_10_2: + return VK_FORMAT_A2B10G10R10_SINT_PACK32; + default: + break; + } break; - } - break; - case Maxwell::VertexAttribute::Type::Float: - switch (size) { - case Maxwell::VertexAttribute::Size::Size_16: - return VK_FORMAT_R16_SFLOAT; - case Maxwell::VertexAttribute::Size::Size_16_16: - return VK_FORMAT_R16G16_SFLOAT; - case Maxwell::VertexAttribute::Size::Size_16_16_16: - return VK_FORMAT_R16G16B16_SFLOAT; - case Maxwell::VertexAttribute::Size::Size_16_16_16_16: - return VK_FORMAT_R16G16B16A16_SFLOAT; - case Maxwell::VertexAttribute::Size::Size_32: - return VK_FORMAT_R32_SFLOAT; - case Maxwell::VertexAttribute::Size::Size_32_32: - return VK_FORMAT_R32G32_SFLOAT; - case Maxwell::VertexAttribute::Size::Size_32_32_32: - return VK_FORMAT_R32G32B32_SFLOAT; - case Maxwell::VertexAttribute::Size::Size_32_32_32_32: - return VK_FORMAT_R32G32B32A32_SFLOAT; - case Maxwell::VertexAttribute::Size::Size_11_11_10: - return VK_FORMAT_B10G11R11_UFLOAT_PACK32; - default: + case Maxwell::VertexAttribute::Type::Float: + switch (size) { + case Maxwell::VertexAttribute::Size::Size_16: + return VK_FORMAT_R16_SFLOAT; + case Maxwell::VertexAttribute::Size::Size_16_16: + return VK_FORMAT_R16G16_SFLOAT; + case Maxwell::VertexAttribute::Size::Size_16_16_16: + return VK_FORMAT_R16G16B16_SFLOAT; + case Maxwell::VertexAttribute::Size::Size_16_16_16_16: + return VK_FORMAT_R16G16B16A16_SFLOAT; + case Maxwell::VertexAttribute::Size::Size_32: + return VK_FORMAT_R32_SFLOAT; + case Maxwell::VertexAttribute::Size::Size_32_32: + return VK_FORMAT_R32G32_SFLOAT; + case Maxwell::VertexAttribute::Size::Size_32_32_32: + return VK_FORMAT_R32G32B32_SFLOAT; + case Maxwell::VertexAttribute::Size::Size_32_32_32_32: + return VK_FORMAT_R32G32B32A32_SFLOAT; + case Maxwell::VertexAttribute::Size::Size_11_11_10: + return VK_FORMAT_B10G11R11_UFLOAT_PACK32; + default: + break; + } break; } - break; + return VK_FORMAT_UNDEFINED; + })()}; + + if (format == VK_FORMAT_UNDEFINED) { + UNIMPLEMENTED_MSG("Unimplemented vertex format of type={} and size={}", type, size); } - UNIMPLEMENTED_MSG("Unimplemented vertex format of type={} and size={}", type, size); - return {}; + + return device.GetSupportedFormat(format, VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT, + FormatType::Buffer); } VkCompareOp ComparisonOp(Maxwell::ComparisonOp comparison) { diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h index 9edd6af6a..356d46292 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.h +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h @@ -48,7 +48,8 @@ VkShaderStageFlagBits ShaderStage(Shader::Stage stage); VkPrimitiveTopology PrimitiveTopology(const Device& device, Maxwell::PrimitiveTopology topology); -VkFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size); +VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type, + Maxwell::VertexAttribute::Size size); VkCompareOp ComparisonOp(Maxwell::ComparisonOp comparison); diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 4a1d96322..27e6ebf94 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp @@ -87,12 +87,8 @@ u32 GetBytesPerPixel(const Tegra::FramebufferConfig& framebuffer) { } std::size_t GetSizeInBytes(const Tegra::FramebufferConfig& framebuffer) { - // TODO(Rodrigo): Read this from HLE - constexpr u32 block_height_log2 = 4; - const u32 bytes_per_pixel = GetBytesPerPixel(framebuffer); - const u64 size_bytes{Tegra::Texture::CalculateSize( - true, bytes_per_pixel, framebuffer.stride, framebuffer.height, 1, block_height_log2, 0)}; - return size_bytes; + return static_cast<std::size_t>(framebuffer.stride) * + static_cast<std::size_t>(framebuffer.height) * GetBytesPerPixel(framebuffer); } VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) { @@ -173,10 +169,12 @@ VkSemaphore BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, // TODO(Rodrigo): Read this from HLE constexpr u32 block_height_log2 = 4; const u32 bytes_per_pixel = GetBytesPerPixel(framebuffer); - const u64 size_bytes{GetSizeInBytes(framebuffer)}; - + const u64 linear_size{GetSizeInBytes(framebuffer)}; + const u64 tiled_size{Tegra::Texture::CalculateSize(true, bytes_per_pixel, + framebuffer.stride, framebuffer.height, + 1, block_height_log2, 0)}; Tegra::Texture::UnswizzleTexture( - mapped_span.subspan(image_offset, size_bytes), std::span(host_ptr, size_bytes), + mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size), bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0); const VkBufferImageCopy copy{ diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 682f05335..5aca8f038 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -559,7 +559,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { vertex_attributes.push_back({ .location = static_cast<u32>(index), .binding = attribute.buffer, - .format = MaxwellToVK::VertexFormat(attribute.Type(), attribute.Size()), + .format = MaxwellToVK::VertexFormat(device, attribute.Type(), attribute.Size()), .offset = attribute.offset, }); } diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 10f9fe7fe..16e46d3e5 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -939,7 +939,7 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs) .pNext = nullptr, .location = static_cast<u32>(index), .binding = binding, - .format = MaxwellToVK::VertexFormat(attribute.type, attribute.size), + .format = MaxwellToVK::VertexFormat(device, attribute.type, attribute.size), .offset = attribute.offset, }); } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index ba6d81420..16463a892 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1618,6 +1618,9 @@ ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParam ImageView::~ImageView() = default; VkImageView ImageView::DepthView() { + if (!image_handle) { + return VK_NULL_HANDLE; + } if (depth_view) { return *depth_view; } @@ -1627,6 +1630,9 @@ VkImageView ImageView::DepthView() { } VkImageView ImageView::StencilView() { + if (!image_handle) { + return VK_NULL_HANDLE; + } if (stencil_view) { return *stencil_view; } @@ -1636,6 +1642,9 @@ VkImageView ImageView::StencilView() { } VkImageView ImageView::ColorView() { + if (!image_handle) { + return VK_NULL_HANDLE; + } if (color_view) { return *color_view; } @@ -1645,6 +1654,9 @@ VkImageView ImageView::ColorView() { VkImageView ImageView::StorageView(Shader::TextureType texture_type, Shader::ImageFormat image_format) { + if (!image_handle) { + return VK_NULL_HANDLE; + } if (image_format == Shader::ImageFormat::Typeless) { return Handle(texture_type); } diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 743ac09f6..ddecfca13 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -50,6 +50,21 @@ constexpr std::array R4G4_UNORM_PACK8{ VK_FORMAT_UNDEFINED, }; +constexpr std::array R16G16B16_SFLOAT{ + VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_UNDEFINED, +}; + +constexpr std::array R16G16B16_SSCALED{ + VK_FORMAT_R16G16B16A16_SSCALED, + VK_FORMAT_UNDEFINED, +}; + +constexpr std::array R8G8B8_SSCALED{ + VK_FORMAT_R8G8B8A8_SSCALED, + VK_FORMAT_UNDEFINED, +}; + } // namespace Alternatives enum class NvidiaArchitecture { @@ -102,6 +117,12 @@ constexpr const VkFormat* GetFormatAlternatives(VkFormat format) { return Alternatives::B5G6R5_UNORM_PACK16.data(); case VK_FORMAT_R4G4_UNORM_PACK8: return Alternatives::R4G4_UNORM_PACK8.data(); + case VK_FORMAT_R16G16B16_SFLOAT: + return Alternatives::R16G16B16_SFLOAT.data(); + case VK_FORMAT_R16G16B16_SSCALED: + return Alternatives::R16G16B16_SSCALED.data(); + case VK_FORMAT_R8G8B8_SSCALED: + return Alternatives::R8G8B8_SSCALED.data(); default: return nullptr; } @@ -122,109 +143,142 @@ VkFormatFeatureFlags GetFormatFeatures(VkFormatProperties properties, FormatType std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::PhysicalDevice physical) { static constexpr std::array formats{ - VK_FORMAT_A8B8G8R8_UNORM_PACK32, - VK_FORMAT_A8B8G8R8_UINT_PACK32, - VK_FORMAT_A8B8G8R8_SNORM_PACK32, + VK_FORMAT_A1R5G5B5_UNORM_PACK16, + VK_FORMAT_A2B10G10R10_SINT_PACK32, + VK_FORMAT_A2B10G10R10_SNORM_PACK32, + VK_FORMAT_A2B10G10R10_SSCALED_PACK32, + VK_FORMAT_A2B10G10R10_UINT_PACK32, + VK_FORMAT_A2B10G10R10_UNORM_PACK32, + VK_FORMAT_A2B10G10R10_USCALED_PACK32, VK_FORMAT_A8B8G8R8_SINT_PACK32, + VK_FORMAT_A8B8G8R8_SNORM_PACK32, VK_FORMAT_A8B8G8R8_SRGB_PACK32, - VK_FORMAT_R5G6B5_UNORM_PACK16, - VK_FORMAT_B5G6R5_UNORM_PACK16, - VK_FORMAT_R5G5B5A1_UNORM_PACK16, + VK_FORMAT_A8B8G8R8_UINT_PACK32, + VK_FORMAT_A8B8G8R8_UNORM_PACK32, + VK_FORMAT_ASTC_10x10_SRGB_BLOCK, + VK_FORMAT_ASTC_10x10_UNORM_BLOCK, + VK_FORMAT_ASTC_10x5_SRGB_BLOCK, + VK_FORMAT_ASTC_10x5_UNORM_BLOCK, + VK_FORMAT_ASTC_10x6_SRGB_BLOCK, + VK_FORMAT_ASTC_10x6_UNORM_BLOCK, + VK_FORMAT_ASTC_10x8_SRGB_BLOCK, + VK_FORMAT_ASTC_10x8_UNORM_BLOCK, + VK_FORMAT_ASTC_12x10_SRGB_BLOCK, + VK_FORMAT_ASTC_12x10_UNORM_BLOCK, + VK_FORMAT_ASTC_12x12_SRGB_BLOCK, + VK_FORMAT_ASTC_12x12_UNORM_BLOCK, + VK_FORMAT_ASTC_4x4_SRGB_BLOCK, + VK_FORMAT_ASTC_4x4_UNORM_BLOCK, + VK_FORMAT_ASTC_5x4_SRGB_BLOCK, + VK_FORMAT_ASTC_5x4_UNORM_BLOCK, + VK_FORMAT_ASTC_5x5_SRGB_BLOCK, + VK_FORMAT_ASTC_5x5_UNORM_BLOCK, + VK_FORMAT_ASTC_6x5_SRGB_BLOCK, + VK_FORMAT_ASTC_6x5_UNORM_BLOCK, + VK_FORMAT_ASTC_6x6_SRGB_BLOCK, + VK_FORMAT_ASTC_6x6_UNORM_BLOCK, + VK_FORMAT_ASTC_8x5_SRGB_BLOCK, + VK_FORMAT_ASTC_8x5_UNORM_BLOCK, + VK_FORMAT_ASTC_8x6_SRGB_BLOCK, + VK_FORMAT_ASTC_8x6_UNORM_BLOCK, + VK_FORMAT_ASTC_8x8_SRGB_BLOCK, + VK_FORMAT_ASTC_8x8_UNORM_BLOCK, + VK_FORMAT_B10G11R11_UFLOAT_PACK32, + VK_FORMAT_B4G4R4A4_UNORM_PACK16, VK_FORMAT_B5G5R5A1_UNORM_PACK16, - VK_FORMAT_A2B10G10R10_UNORM_PACK32, - VK_FORMAT_A2B10G10R10_UINT_PACK32, - VK_FORMAT_A1R5G5B5_UNORM_PACK16, - VK_FORMAT_R32G32B32A32_SFLOAT, - VK_FORMAT_R32G32B32A32_SINT, - VK_FORMAT_R32G32B32A32_UINT, - VK_FORMAT_R32G32_SFLOAT, - VK_FORMAT_R32G32_SINT, - VK_FORMAT_R32G32_UINT, + VK_FORMAT_B5G6R5_UNORM_PACK16, + VK_FORMAT_B8G8R8A8_SRGB, + VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_BC1_RGBA_SRGB_BLOCK, + VK_FORMAT_BC1_RGBA_UNORM_BLOCK, + VK_FORMAT_BC2_SRGB_BLOCK, + VK_FORMAT_BC2_UNORM_BLOCK, + VK_FORMAT_BC3_SRGB_BLOCK, + VK_FORMAT_BC3_UNORM_BLOCK, + VK_FORMAT_BC4_SNORM_BLOCK, + VK_FORMAT_BC4_UNORM_BLOCK, + VK_FORMAT_BC5_SNORM_BLOCK, + VK_FORMAT_BC5_UNORM_BLOCK, + VK_FORMAT_BC6H_SFLOAT_BLOCK, + VK_FORMAT_BC6H_UFLOAT_BLOCK, + VK_FORMAT_BC7_SRGB_BLOCK, + VK_FORMAT_BC7_UNORM_BLOCK, + VK_FORMAT_D16_UNORM, + VK_FORMAT_D16_UNORM_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_D32_SFLOAT, + VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, + VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R16G16B16A16_SINT, - VK_FORMAT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_SNORM, + VK_FORMAT_R16G16B16A16_SSCALED, + VK_FORMAT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_UNORM, - VK_FORMAT_R16G16_UNORM, - VK_FORMAT_R16G16_SNORM, + VK_FORMAT_R16G16B16A16_USCALED, + VK_FORMAT_R16G16B16_SFLOAT, + VK_FORMAT_R16G16B16_SINT, + VK_FORMAT_R16G16B16_SNORM, + VK_FORMAT_R16G16B16_SSCALED, + VK_FORMAT_R16G16B16_UINT, + VK_FORMAT_R16G16B16_UNORM, + VK_FORMAT_R16G16B16_USCALED, VK_FORMAT_R16G16_SFLOAT, - VK_FORMAT_R16G16_UINT, VK_FORMAT_R16G16_SINT, - VK_FORMAT_R16_UNORM, + VK_FORMAT_R16G16_SNORM, + VK_FORMAT_R16G16_SSCALED, + VK_FORMAT_R16G16_UINT, + VK_FORMAT_R16G16_UNORM, + VK_FORMAT_R16G16_USCALED, + VK_FORMAT_R16_SFLOAT, + VK_FORMAT_R16_SINT, VK_FORMAT_R16_SNORM, + VK_FORMAT_R16_SSCALED, VK_FORMAT_R16_UINT, + VK_FORMAT_R16_UNORM, + VK_FORMAT_R16_USCALED, + VK_FORMAT_R32G32B32A32_SFLOAT, + VK_FORMAT_R32G32B32A32_SINT, + VK_FORMAT_R32G32B32A32_UINT, + VK_FORMAT_R32G32B32_SFLOAT, + VK_FORMAT_R32G32B32_SINT, + VK_FORMAT_R32G32B32_UINT, + VK_FORMAT_R32G32_SFLOAT, + VK_FORMAT_R32G32_SINT, + VK_FORMAT_R32G32_UINT, + VK_FORMAT_R32_SFLOAT, + VK_FORMAT_R32_SINT, + VK_FORMAT_R32_UINT, + VK_FORMAT_R4G4B4A4_UNORM_PACK16, + VK_FORMAT_R4G4_UNORM_PACK8, + VK_FORMAT_R5G5B5A1_UNORM_PACK16, + VK_FORMAT_R5G6B5_UNORM_PACK16, + VK_FORMAT_R8G8B8A8_SINT, + VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SRGB, - VK_FORMAT_R8G8_UNORM, - VK_FORMAT_R8G8_SNORM, + VK_FORMAT_R8G8B8A8_SSCALED, + VK_FORMAT_R8G8B8A8_UINT, + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R8G8B8A8_USCALED, + VK_FORMAT_R8G8B8_SINT, + VK_FORMAT_R8G8B8_SNORM, + VK_FORMAT_R8G8B8_SSCALED, + VK_FORMAT_R8G8B8_UINT, + VK_FORMAT_R8G8B8_UNORM, + VK_FORMAT_R8G8B8_USCALED, VK_FORMAT_R8G8_SINT, + VK_FORMAT_R8G8_SNORM, + VK_FORMAT_R8G8_SSCALED, VK_FORMAT_R8G8_UINT, - VK_FORMAT_R8_UNORM, - VK_FORMAT_R8_SNORM, + VK_FORMAT_R8G8_UNORM, + VK_FORMAT_R8G8_USCALED, VK_FORMAT_R8_SINT, + VK_FORMAT_R8_SNORM, + VK_FORMAT_R8_SSCALED, VK_FORMAT_R8_UINT, - VK_FORMAT_B10G11R11_UFLOAT_PACK32, - VK_FORMAT_R32_SFLOAT, - VK_FORMAT_R32_UINT, - VK_FORMAT_R32_SINT, - VK_FORMAT_R16_SFLOAT, - VK_FORMAT_R16G16B16A16_SFLOAT, - VK_FORMAT_B8G8R8A8_UNORM, - VK_FORMAT_B8G8R8A8_SRGB, - VK_FORMAT_R4G4_UNORM_PACK8, - VK_FORMAT_R4G4B4A4_UNORM_PACK16, - VK_FORMAT_B4G4R4A4_UNORM_PACK16, - VK_FORMAT_D32_SFLOAT, - VK_FORMAT_D16_UNORM, + VK_FORMAT_R8_UNORM, + VK_FORMAT_R8_USCALED, VK_FORMAT_S8_UINT, - VK_FORMAT_D16_UNORM_S8_UINT, - VK_FORMAT_D24_UNORM_S8_UINT, - VK_FORMAT_D32_SFLOAT_S8_UINT, - VK_FORMAT_BC1_RGBA_UNORM_BLOCK, - VK_FORMAT_BC2_UNORM_BLOCK, - VK_FORMAT_BC3_UNORM_BLOCK, - VK_FORMAT_BC4_UNORM_BLOCK, - VK_FORMAT_BC4_SNORM_BLOCK, - VK_FORMAT_BC5_UNORM_BLOCK, - VK_FORMAT_BC5_SNORM_BLOCK, - VK_FORMAT_BC7_UNORM_BLOCK, - VK_FORMAT_BC6H_UFLOAT_BLOCK, - VK_FORMAT_BC6H_SFLOAT_BLOCK, - VK_FORMAT_BC1_RGBA_SRGB_BLOCK, - VK_FORMAT_BC2_SRGB_BLOCK, - VK_FORMAT_BC3_SRGB_BLOCK, - VK_FORMAT_BC7_SRGB_BLOCK, - VK_FORMAT_ASTC_4x4_UNORM_BLOCK, - VK_FORMAT_ASTC_4x4_SRGB_BLOCK, - VK_FORMAT_ASTC_5x4_UNORM_BLOCK, - VK_FORMAT_ASTC_5x4_SRGB_BLOCK, - VK_FORMAT_ASTC_5x5_UNORM_BLOCK, - VK_FORMAT_ASTC_5x5_SRGB_BLOCK, - VK_FORMAT_ASTC_6x5_UNORM_BLOCK, - VK_FORMAT_ASTC_6x5_SRGB_BLOCK, - VK_FORMAT_ASTC_6x6_UNORM_BLOCK, - VK_FORMAT_ASTC_6x6_SRGB_BLOCK, - VK_FORMAT_ASTC_8x5_UNORM_BLOCK, - VK_FORMAT_ASTC_8x5_SRGB_BLOCK, - VK_FORMAT_ASTC_8x6_UNORM_BLOCK, - VK_FORMAT_ASTC_8x6_SRGB_BLOCK, - VK_FORMAT_ASTC_8x8_UNORM_BLOCK, - VK_FORMAT_ASTC_8x8_SRGB_BLOCK, - VK_FORMAT_ASTC_10x5_UNORM_BLOCK, - VK_FORMAT_ASTC_10x5_SRGB_BLOCK, - VK_FORMAT_ASTC_10x6_UNORM_BLOCK, - VK_FORMAT_ASTC_10x6_SRGB_BLOCK, - VK_FORMAT_ASTC_10x8_UNORM_BLOCK, - VK_FORMAT_ASTC_10x8_SRGB_BLOCK, - VK_FORMAT_ASTC_10x10_UNORM_BLOCK, - VK_FORMAT_ASTC_10x10_SRGB_BLOCK, - VK_FORMAT_ASTC_12x10_UNORM_BLOCK, - VK_FORMAT_ASTC_12x10_SRGB_BLOCK, - VK_FORMAT_ASTC_12x12_UNORM_BLOCK, - VK_FORMAT_ASTC_12x12_SRGB_BLOCK, - VK_FORMAT_ASTC_8x6_UNORM_BLOCK, - VK_FORMAT_ASTC_8x6_SRGB_BLOCK, - VK_FORMAT_ASTC_6x5_UNORM_BLOCK, - VK_FORMAT_ASTC_6x5_SRGB_BLOCK, - VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, }; std::unordered_map<VkFormat, VkFormatProperties> format_properties; for (const auto format : formats) { @@ -739,9 +793,9 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags if (!IsFormatSupported(alternative, wanted_usage, format_type)) { continue; } - LOG_WARNING(Render_Vulkan, - "Emulating format={} with alternative format={} with usage={} and type={}", - wanted_format, alternative, wanted_usage, format_type); + LOG_DEBUG(Render_Vulkan, + "Emulating format={} with alternative format={} with usage={} and type={}", + wanted_format, alternative, wanted_usage, format_type); return alternative; } diff --git a/src/yuzu/applets/qt_profile_select.cpp b/src/yuzu/applets/qt_profile_select.cpp index 826c6c224..c8bcfb223 100644 --- a/src/yuzu/applets/qt_profile_select.cpp +++ b/src/yuzu/applets/qt_profile_select.cpp @@ -100,6 +100,7 @@ QtProfileSelectionDialog::QtProfileSelectionDialog(Core::HID::HIDCore& hid_core, } QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier); QCoreApplication::postEvent(tree_view, event); + SelectUser(tree_view->currentIndex()); }); const auto& profiles = profile_manager->GetAllUsers(); diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index ef3bdfb1a..c262d0a2b 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -1089,8 +1089,8 @@ QStringList GRenderWindow::GetUnsupportedGLExtensions() const { } if (!unsupported_ext.empty()) { - LOG_ERROR(Frontend, "GPU does not support all required extensions: {}", - glGetString(GL_RENDERER)); + const std::string gl_renderer{reinterpret_cast<const char*>(glGetString(GL_RENDERER))}; + LOG_ERROR(Frontend, "GPU does not support all required extensions: {}", gl_renderer); } for (const QString& ext : unsupported_ext) { LOG_ERROR(Frontend, "Unsupported GL extension: {}", ext.toStdString()); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 85b9652f0..378b40205 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1588,17 +1588,18 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p return true; } -void GMainWindow::SelectAndSetCurrentUser() { +bool GMainWindow::SelectAndSetCurrentUser() { QtProfileSelectionDialog dialog(system->HIDCore(), this); dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); dialog.setWindowModality(Qt::WindowModal); if (dialog.exec() == QDialog::Rejected) { - return; + return false; } Settings::values.current_user = dialog.GetIndex(); + return true; } void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index, @@ -1632,11 +1633,14 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t Settings::LogSettings(); if (UISettings::values.select_user_on_boot) { - SelectAndSetCurrentUser(); + if (SelectAndSetCurrentUser() == false) { + return; + } } - if (!LoadROM(filename, program_id, program_index)) + if (!LoadROM(filename, program_id, program_index)) { return; + } system->SetShuttingDown(false); @@ -3334,7 +3338,8 @@ void GMainWindow::MigrateConfigFiles() { } const auto origin = config_dir_fs_path / filename; const auto destination = config_dir_fs_path / "custom" / filename; - LOG_INFO(Frontend, "Migrating config file from {} to {}", origin, destination); + LOG_INFO(Frontend, "Migrating config file from {} to {}", origin.string(), + destination.string()); if (!Common::FS::RenameFile(origin, destination)) { // Delete the old config file if one already exists in the new location. Common::FS::RemoveFile(origin); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 23b67a14e..e13b38b24 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -218,7 +218,7 @@ private: void SetDiscordEnabled(bool state); void LoadAmiibo(const QString& filename); - void SelectAndSetCurrentUser(); + bool SelectAndSetCurrentUser(); /** * Stores the filename in the recently loaded files list. |