From 4219fd41b91dd78cffdf70db1a07cc1bdf7c174e Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Tue, 12 Jan 2021 10:22:33 +0100 Subject: [PATCH] early-access version 1310 --- README.md | 2 +- patches/inject-git-info.patch | 13 +-- src/CMakeLists.txt | 5 + src/common/div_ceil.h | 10 +- src/common/intrusive_red_black_tree.h | 94 ++++++++----------- src/common/parent_of_member.h | 49 ++++------ src/core/arm/dynarmic/arm_dynarmic_32.cpp | 9 +- src/core/file_sys/registered_cache.h | 8 +- src/core/hle/kernel/k_address_arbiter.cpp | 10 +- src/core/hle/kernel/k_address_arbiter.h | 7 +- src/core/hle/kernel/k_condition_variable.cpp | 11 +-- src/core/hle/kernel/k_condition_variable.h | 7 +- .../hle/kernel/k_synchronization_object.cpp | 10 +- .../hle/kernel/k_synchronization_object.h | 5 +- src/core/hle/kernel/kernel.cpp | 2 + src/core/hle/kernel/process.h | 2 +- src/core/hle/kernel/readable_event.h | 2 +- src/core/hle/kernel/server_port.h | 2 +- src/core/hle/kernel/server_session.h | 2 +- src/core/hle/kernel/svc.cpp | 1 + src/core/hle/kernel/thread.cpp | 6 +- src/core/hle/kernel/thread.h | 38 ++++++-- src/core/hle/service/apm/interface.cpp | 10 +- src/core/hle/service/apm/interface.h | 1 + .../service/nvdrv/devices/nvhost_nvdec.cpp | 3 +- .../hle/service/nvdrv/devices/nvhost_vic.cpp | 7 +- .../hle/service/nvflinger/buffer_queue.cpp | 6 +- src/tests/CMakeLists.txt | 1 - src/tests/common/ring_buffer.cpp | 30 +++--- src/video_core/CMakeLists.txt | 1 - src/video_core/cdma_pusher.cpp | 63 +++++-------- src/video_core/cdma_pusher.h | 35 ++----- .../command_classes/codecs/codec.cpp | 7 +- src/video_core/command_classes/nvdec.cpp | 8 +- src/video_core/command_classes/nvdec.h | 2 +- src/video_core/command_classes/vic.cpp | 45 +++++---- src/video_core/command_classes/vic.h | 51 ++-------- src/video_core/gpu.cpp | 6 +- src/video_core/gpu_thread.cpp | 3 +- src/yuzu/bootmanager.cpp | 7 +- src/yuzu/configuration/config.cpp | 4 +- .../configuration/configure_motion_touch.cpp | 7 +- src/yuzu/debugger/wait_tree.cpp | 46 ++++++++- src/yuzu/util/url_request_interceptor.cpp | 2 + src/yuzu_cmd/config.cpp | 2 +- src/yuzu_cmd/default_ini.h | 2 +- src/yuzu_cmd/yuzu.cpp | 2 - src/yuzu_tester/config.cpp | 2 +- src/yuzu_tester/default_ini.h | 2 +- 49 files changed, 308 insertions(+), 342 deletions(-) diff --git a/README.md b/README.md index 979f8cd96..a744accfe 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 1298. +This is the source code for early-access 1310. ## Legal Notice diff --git a/patches/inject-git-info.patch b/patches/inject-git-info.patch index cf7b6f780..a3c7b5951 100644 --- a/patches/inject-git-info.patch +++ b/patches/inject-git-info.patch @@ -1,31 +1,31 @@ diff --git a/CMakeModules/GenerateSCMRev.cmake b/CMakeModules/GenerateSCMRev.cmake -index 311ba1c2e..79315b198 100644 --- a/CMakeModules/GenerateSCMRev.cmake +++ b/CMakeModules/GenerateSCMRev.cmake -@@ -11,9 +11,9 @@ find_package(Git QUIET PATHS "${GIT_EXECUTABLE}") +@@ -11,10 +11,10 @@ # generate git/build information include(GetGitRevisionDescription) -get_git_head_revision(GIT_REF_SPEC GIT_REV) -git_describe(GIT_DESC --always --long --dirty) -git_branch_name(GIT_BRANCH) +-get_timestamp(BUILD_DATE) +#get_git_head_revision(GIT_REF_SPEC GIT_REV) +#git_describe(GIT_DESC --always --long --dirty) +#git_branch_name(GIT_BRANCH) - get_timestamp(BUILD_DATE) ++#get_timestamp(BUILD_DATE) # Generate cpp with Git revision from template -@@ -113,4 +113,5 @@ foreach (F IN LISTS HASH_FILES) + # Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well +@@ -113,4 +113,5 @@ set(COMBINED "${COMBINED}${TMP}") endforeach() string(MD5 SHADER_CACHE_VERSION "${COMBINED}") +set(BUILD_FULLNAME "${BUILD_FULLNAME} ") configure_file("${SRC_DIR}/src/common/scm_rev.cpp.in" "scm_rev.cpp" @ONLY) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt -index d120c8d3d..bf3dcdbf6 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt -@@ -28,6 +28,11 @@ add_custom_command(OUTPUT scm_rev.cpp +@@ -28,6 +28,12 @@ -DBUILD_TAG="${BUILD_TAG}" -DBUILD_ID="${DISPLAY_VERSION}" -DGIT_EXECUTABLE="${GIT_EXECUTABLE}" @@ -34,6 +34,7 @@ index d120c8d3d..bf3dcdbf6 100644 + -DGIT_DESC="${GIT_DESC}" + -DGIT_BRANCH="${GIT_BRANCH}" + -DBUILD_FULLNAME="${BUILD_FULLNAME}" ++ -DBUILD_DATE="${BUILD_DATE}" -P "${CMAKE_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake" DEPENDS # WARNING! It was too much work to try and make a common location for this list, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8777df751..61adbef28 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,10 +45,15 @@ if (MSVC) # Warnings /W3 + /we4062 # enumerator 'identifier' in a switch of enum 'enumeration' is not handled + /we4101 # 'identifier': unreferenced local variable + /we4265 # 'class': class has virtual functions, but destructor is not virtual + /we4388 # signed/unsigned mismatch /we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? /we4555 # Expression has no effect; expected expression with side-effect /we4834 # Discarding return value of function with 'nodiscard' attribute + /we5038 # data member 'member1' will be initialized after data member 'member2' ) # /GS- - No stack buffer overflow checks diff --git a/src/common/div_ceil.h b/src/common/div_ceil.h index 6b2c48f91..95e1489a9 100755 --- a/src/common/div_ceil.h +++ b/src/common/div_ceil.h @@ -11,16 +11,16 @@ namespace Common { /// Ceiled integer division. template -requires std::is_integral_v&& std::is_unsigned_v[[nodiscard]] constexpr auto DivCeil( - N number, D divisor) { - return (static_cast(number) + divisor - 1) / divisor; +requires std::is_integral_v&& std::is_unsigned_v[[nodiscard]] constexpr N DivCeil(N number, + D divisor) { + return static_cast((static_cast(number) + divisor - 1) / divisor); } /// Ceiled integer division with logarithmic divisor in base 2 template -requires std::is_integral_v&& std::is_unsigned_v[[nodiscard]] constexpr auto DivCeilLog2( +requires std::is_integral_v&& std::is_unsigned_v[[nodiscard]] constexpr N DivCeilLog2( N value, D alignment_log2) { - return (static_cast(value) + (D(1) << alignment_log2) - 1) >> alignment_log2; + return static_cast((static_cast(value) + (D(1) << alignment_log2) - 1) >> alignment_log2); } } // namespace Common diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h index 0be90912c..fb55de94e 100755 --- a/src/common/intrusive_red_black_tree.h +++ b/src/common/intrusive_red_black_tree.h @@ -1,18 +1,6 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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 for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. #pragma once @@ -30,7 +18,7 @@ class IntrusiveRedBlackTreeImpl; struct IntrusiveRedBlackTreeNode { private: - RB_ENTRY(IntrusiveRedBlackTreeNode) entry; + RB_ENTRY(IntrusiveRedBlackTreeNode) entry{}; friend class impl::IntrusiveRedBlackTreeImpl; @@ -38,8 +26,7 @@ private: friend class IntrusiveRedBlackTree; public: - constexpr IntrusiveRedBlackTreeNode() : entry() { /* ... */ - } + constexpr IntrusiveRedBlackTreeNode() = default; }; template @@ -80,18 +67,16 @@ public: using iterator_category = std::bidirectional_iterator_tag; using value_type = typename IntrusiveRedBlackTreeImpl::value_type; using difference_type = typename IntrusiveRedBlackTreeImpl::difference_type; - using pointer = typename std::conditional::type; - using reference = - typename std::conditional::type; + using pointer = std::conditional_t; + using reference = std::conditional_t; private: pointer node; public: - explicit Iterator(pointer n) : node(n) { /* ... */ - } + explicit Iterator(pointer n) : node(n) {} bool operator==(const Iterator& rhs) const { return this->node == rhs.node; @@ -137,12 +122,11 @@ public: }; protected: - /* Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot. - */ + // Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot. RB_GENERATE_WITHOUT_COMPARE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry); private: - /* Define accessors using RB_* functions. */ + // Define accessors using RB_* functions. constexpr void InitializeImpl() { RB_INIT(&this->root); } @@ -174,12 +158,12 @@ public: return RB_PREV(IntrusiveRedBlackTreeRoot, nullptr, node); } - static IntrusiveRedBlackTreeNode const* GetNext(IntrusiveRedBlackTreeNode const* node) { + static IntrusiveRedBlackTreeNode const* GetNext(const IntrusiveRedBlackTreeNode* node) { return static_cast( GetNext(const_cast(node))); } - static IntrusiveRedBlackTreeNode const* GetPrev(IntrusiveRedBlackTreeNode const* node) { + static IntrusiveRedBlackTreeNode const* GetPrev(const IntrusiveRedBlackTreeNode* node) { return static_cast( GetPrev(const_cast(node))); } @@ -189,7 +173,7 @@ public: this->InitializeImpl(); } - /* Iterator accessors. */ + // Iterator accessors. iterator begin() { return iterator(this->GetMinImpl()); } @@ -222,7 +206,7 @@ public: return const_iterator(&ref); } - /* Content management. */ + // Content management. bool empty() const { return this->EmptyImpl(); } @@ -273,8 +257,7 @@ consteval auto* GetLightCompareType() { } // namespace impl template -using LightCompareType = - typename std::remove_pointer())>::type; +using LightCompareType = std::remove_pointer_t())>; template class IntrusiveRedBlackTree { @@ -283,7 +266,7 @@ public: using ImplType = impl::IntrusiveRedBlackTreeImpl; private: - ImplType impl; + ImplType impl{}; public: struct IntrusiveRedBlackTreeRootWithCompare : ImplType::IntrusiveRedBlackTreeRoot {}; @@ -311,27 +294,25 @@ public: friend class IntrusiveRedBlackTree; using ImplIterator = - typename std::conditional::type; + std::conditional_t; using iterator_category = std::bidirectional_iterator_tag; using value_type = typename IntrusiveRedBlackTree::value_type; using difference_type = typename IntrusiveRedBlackTree::difference_type; - using pointer = typename std::conditional::type; - using reference = typename std::conditional::type; + using pointer = std::conditional_t; + using reference = std::conditional_t; private: ImplIterator iterator; private: - explicit Iterator(ImplIterator it) : iterator(it) { /* ... */ - } + explicit Iterator(ImplIterator it) : iterator(it) {} explicit Iterator(typename std::conditional::type::pointer ptr) - : iterator(ptr) { /* ... */ - } + : iterator(ptr) {} ImplIterator GetImplIterator() const { return this->iterator; @@ -382,7 +363,7 @@ public: }; private: - /* Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot. */ + // Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot. RB_GENERATE_WITH_COMPARE_STATIC(IntrusiveRedBlackTreeRootWithCompare, IntrusiveRedBlackTreeNode, entry, CompareImpl, LightCompareImpl); @@ -396,14 +377,14 @@ private: return Comparator::Compare(*static_cast(elm), *Traits::GetParent(rhs)); } - /* Define accessors using RB_* functions. */ + // Define accessors using RB_* functions. IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) { return RB_INSERT(IntrusiveRedBlackTreeRootWithCompare, static_cast(&this->impl.root), node); } - IntrusiveRedBlackTreeNode* FindImpl(IntrusiveRedBlackTreeNode const* node) const { + IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const { return RB_FIND( IntrusiveRedBlackTreeRootWithCompare, const_cast( @@ -411,7 +392,7 @@ private: const_cast(node)); } - IntrusiveRedBlackTreeNode* NFindImpl(IntrusiveRedBlackTreeNode const* node) const { + IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const { return RB_NFIND( IntrusiveRedBlackTreeRootWithCompare, const_cast( @@ -436,10 +417,9 @@ private: } public: - constexpr IntrusiveRedBlackTree() : impl() { /* ... */ - } + constexpr IntrusiveRedBlackTree() = default; - /* Iterator accessors. */ + // Iterator accessors. iterator begin() { return iterator(this->impl.begin()); } @@ -472,7 +452,7 @@ public: return const_iterator(this->impl.iterator_to(*Traits::GetNode(std::addressof(ref)))); } - /* Content management. */ + // Content management. bool empty() const { return this->impl.empty(); } @@ -548,12 +528,12 @@ private: return GetParentPointer(node); } - static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) { + static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { return GetParentPointer(node); } private: - static constexpr TYPED_STORAGE(Derived) DerivedStorage = {}; + static constexpr TypedStorage DerivedStorage = {}; static_assert(GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage)); }; @@ -569,7 +549,7 @@ public: using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl; static constexpr bool IsValid() { - TYPED_STORAGE(Derived) DerivedStorage = {}; + TypedStorage DerivedStorage = {}; return GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage); } @@ -591,7 +571,7 @@ private: return GetParentPointer(node); } - static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) { + static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { return GetParentPointer(node); } }; @@ -639,7 +619,7 @@ private: return static_cast(node); } - static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) { + static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { return static_cast(node); } }; diff --git a/src/common/parent_of_member.h b/src/common/parent_of_member.h index fd79e11b6..d9a14529d 100755 --- a/src/common/parent_of_member.h +++ b/src/common/parent_of_member.h @@ -1,18 +1,6 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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 for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. #pragma once @@ -22,22 +10,24 @@ #include "common/common_types.h" namespace Common { - +namespace detail { template -struct TypedStorage { - typename std::aligned_storage::type _storage; +struct TypedStorageImpl { + std::aligned_storage_t storage_; }; - -#define TYPED_STORAGE(...) TypedStorage<__VA_ARGS__, sizeof(__VA_ARGS__), alignof(__VA_ARGS__)> +} // namespace detail template -static constexpr T* GetPointer(TYPED_STORAGE(T) & ts) { - return static_cast(static_cast(std::addressof(ts._storage))); +using TypedStorage = detail::TypedStorageImpl; + +template +static constexpr T* GetPointer(TypedStorage& ts) { + return static_cast(static_cast(std::addressof(ts.storage_))); } template -static constexpr const T* GetPointer(const TYPED_STORAGE(T) & ts) { - return static_cast(static_cast(std::addressof(ts._storage))); +static constexpr const T* GetPointer(const TypedStorage& ts) { + return static_cast(static_cast(std::addressof(ts.storage_))); } namespace impl { @@ -73,8 +63,7 @@ struct OffsetOfUnionHolder { }; template - union UnionImpl { /* Empty ... */ - }; + union UnionImpl {}; }; template @@ -83,13 +72,11 @@ struct OffsetOfCalculator { typename OffsetOfUnionHolder::template UnionImpl; union Union { - char c; + char c{}; UnionHolder first_union; - TYPED_STORAGE(ParentType) parent; + TypedStorage parent; - /* This coerces the active member to be c. */ - constexpr Union() : c() { /* ... */ - } + constexpr Union() : c() {} }; static constexpr Union U = {}; diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 0831dd5d2..6c4c8e9e4 100755 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -71,15 +71,8 @@ public: } void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override { - switch (exception) { - case Dynarmic::A32::Exception::UndefinedInstruction: - case Dynarmic::A32::Exception::UnpredictableInstruction: - break; - case Dynarmic::A32::Exception::Breakpoint: - break; - } LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", - static_cast(exception), pc, MemoryReadCode(pc)); + exception, pc, MemoryReadCode(pc)); UNIMPLEMENTED(); } diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h index 5b414b0f0..b08a1687a 100755 --- a/src/core/file_sys/registered_cache.h +++ b/src/core/file_sys/registered_cache.h @@ -67,18 +67,18 @@ public: virtual void Refresh() = 0; virtual bool HasEntry(u64 title_id, ContentRecordType type) const = 0; - virtual bool HasEntry(ContentProviderEntry entry) const; + bool HasEntry(ContentProviderEntry entry) const; virtual std::optional GetEntryVersion(u64 title_id) const = 0; virtual VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const = 0; - virtual VirtualFile GetEntryUnparsed(ContentProviderEntry entry) const; + VirtualFile GetEntryUnparsed(ContentProviderEntry entry) const; virtual VirtualFile GetEntryRaw(u64 title_id, ContentRecordType type) const = 0; - virtual VirtualFile GetEntryRaw(ContentProviderEntry entry) const; + VirtualFile GetEntryRaw(ContentProviderEntry entry) const; virtual std::unique_ptr GetEntry(u64 title_id, ContentRecordType type) const = 0; - virtual std::unique_ptr GetEntry(ContentProviderEntry entry) const; + std::unique_ptr GetEntry(ContentProviderEntry entry) const; virtual std::vector ListEntries() const; diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index bf5e97ef7..d9e702f13 100755 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp @@ -1,10 +1,7 @@ -// Copyright 2020 yuzu Emulator Project +// Copyright 2021 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphere, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. - #include "core/arm/exclusive_monitor.h" #include "core/core.h" #include "core/hle/kernel/k_address_arbiter.h" @@ -18,7 +15,8 @@ namespace Kernel { -KAddressArbiter::KAddressArbiter(Core::System& system) : system{system}, kernel{system.Kernel()} {} +KAddressArbiter::KAddressArbiter(Core::System& system_) + : system{system_}, kernel{system.Kernel()} {} KAddressArbiter::~KAddressArbiter() = default; namespace { @@ -278,6 +276,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr); thread_tree.insert(*cur_thread); cur_thread->SetState(ThreadState::Waiting); + cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); } // Cancel the timer wait. @@ -341,6 +340,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr); thread_tree.insert(*cur_thread); cur_thread->SetState(ThreadState::Waiting); + cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); } // Cancel the timer wait. diff --git a/src/core/hle/kernel/k_address_arbiter.h b/src/core/hle/kernel/k_address_arbiter.h index 3a877e8a8..8d379b524 100755 --- a/src/core/hle/kernel/k_address_arbiter.h +++ b/src/core/hle/kernel/k_address_arbiter.h @@ -1,10 +1,7 @@ -// Copyright 2020 yuzu Emulator Project +// Copyright 2021 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphere, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. - #pragma once #include "common/assert.h" @@ -26,7 +23,7 @@ class KAddressArbiter { public: using ThreadTree = KConditionVariable::ThreadTree; - explicit KAddressArbiter(Core::System& system); + explicit KAddressArbiter(Core::System& system_); ~KAddressArbiter(); [[nodiscard]] ResultCode SignalToAddress(VAddr addr, Svc::SignalType type, s32 value, diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 9fde168fd..49a068310 100755 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -1,10 +1,7 @@ -// Copyright 2020 yuzu Emulator Project +// Copyright 2021 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphere, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. - #include #include "core/arm/exclusive_monitor.h" @@ -63,8 +60,8 @@ bool UpdateLockAtomic(Core::System& system, u32* out, VAddr address, u32 if_zero } // namespace -KConditionVariable::KConditionVariable(Core::System& system) - : system{system}, kernel{system.Kernel()} {} +KConditionVariable::KConditionVariable(Core::System& system_) + : system{system_}, kernel{system.Kernel()} {} KConditionVariable::~KConditionVariable() = default; @@ -136,6 +133,7 @@ ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 val cur_thread->SetAddressKey(addr, value); owner_thread->AddWaiter(cur_thread); cur_thread->SetState(ThreadState::Waiting); + cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::ConditionVar); cur_thread->SetMutexWaitAddressForDebugging(addr); } } @@ -318,6 +316,7 @@ ResultCode KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) // If the timeout is non-zero, set the thread as waiting. if (timeout != 0) { cur_thread->SetState(ThreadState::Waiting); + cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::ConditionVar); cur_thread->SetMutexWaitAddressForDebugging(addr); } } diff --git a/src/core/hle/kernel/k_condition_variable.h b/src/core/hle/kernel/k_condition_variable.h index 6ed704f98..98ed5b323 100755 --- a/src/core/hle/kernel/k_condition_variable.h +++ b/src/core/hle/kernel/k_condition_variable.h @@ -1,10 +1,7 @@ -// Copyright 2020 yuzu Emulator Project +// Copyright 2021 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphere, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. - #pragma once #include "common/assert.h" @@ -25,7 +22,7 @@ class KConditionVariable { public: using ThreadTree = typename Thread::ConditionVariableThreadTreeType; - explicit KConditionVariable(Core::System& system); + explicit KConditionVariable(Core::System& system_); ~KConditionVariable(); // Arbitration diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp index 1b1dda672..1c508cb55 100755 --- a/src/core/hle/kernel/k_synchronization_object.cpp +++ b/src/core/hle/kernel/k_synchronization_object.cpp @@ -1,10 +1,7 @@ -// Copyright 2020 yuzu Emulator Project +// Copyright 2021 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphere, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. - #include "common/assert.h" #include "common/common_types.h" #include "core/hle/kernel/k_scheduler.h" @@ -75,12 +72,13 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, } // For debugging only - thread->SetWaitObjectsForDebugging(objects, num_objects); + thread->SetWaitObjectsForDebugging({objects, static_cast(num_objects)}); // Mark the thread as waiting. thread->SetCancellable(); thread->SetSyncedObject(nullptr, Svc::ResultTimedOut); thread->SetState(ThreadState::Waiting); + thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Synchronization); } // The lock/sleep is done, so we should be able to get our result. @@ -89,7 +87,7 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, thread->ClearCancellable(); // For debugging only - thread->SetWaitObjectsForDebugging(nullptr, 0); + thread->SetWaitObjectsForDebugging({}); // Cancel the timer as needed. if (timer != InvalidHandle) { diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h index 250318cb4..14d80ebf1 100755 --- a/src/core/hle/kernel/k_synchronization_object.h +++ b/src/core/hle/kernel/k_synchronization_object.h @@ -1,10 +1,7 @@ -// Copyright 2020 yuzu Emulator Project +// Copyright 2021 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphere, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. - #pragma once #include diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 8d03f16fb..c0ff287a6 100755 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -605,6 +605,8 @@ void KernelCore::Suspend(bool in_suspention) { const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { impl->suspend_threads[i]->SetState(state); + impl->suspend_threads[i]->SetWaitReasonForDebugging( + ThreadWaitReasonForDebugging::Suspended); } } } diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 21b6f9bd9..564e1f27d 100755 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -301,7 +301,7 @@ public: void LoadModule(CodeSet code_set, VAddr base_addr); - virtual bool IsSignaled() const override; + bool IsSignaled() const override; /////////////////////////////////////////////////////////////////////////////////////////////// // Thread-local storage management diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h index 95894db8d..34e477274 100755 --- a/src/core/hle/kernel/readable_event.h +++ b/src/core/hle/kernel/readable_event.h @@ -45,7 +45,7 @@ public: void Signal(); - virtual bool IsSignaled() const override; + bool IsSignaled() const override; private: explicit ReadableEvent(KernelCore& kernel); diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index 587d01e0a..6470df993 100755 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -79,7 +79,7 @@ public: /// waiting to be accepted by this port. void AppendPendingSession(std::shared_ptr pending_session); - virtual bool IsSignaled() const override; + bool IsSignaled() const override; private: /// ServerSessions waiting to be accepted by the port diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index bfeb05c8d..9155cf7f5 100755 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -124,7 +124,7 @@ public: convert_to_domain = true; } - virtual bool IsSignaled() const override; + bool IsSignaled() const override; private: /// Queues a sync request from the emulated application. diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 99bb4ea20..cc8b661af 100755 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -347,6 +347,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { { KScopedSchedulerLock lock(kernel); thread->SetState(ThreadState::Waiting); + thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index eda56c31c..d97323255 100755 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -215,7 +215,10 @@ VAddr Thread::GetCommandBufferAddress() const { void Thread::SetState(ThreadState state) { KScopedSchedulerLock sl(kernel); - SetMutexWaitAddressForDebugging(0); + // Clear debugging state + SetMutexWaitAddressForDebugging({}); + SetWaitReasonForDebugging({}); + const ThreadState old_state = thread_state; thread_state = static_cast((old_state & ~ThreadState::Mask) | (state & ThreadState::Mask)); @@ -386,6 +389,7 @@ ResultCode Thread::Sleep(s64 nanoseconds) { { KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds); SetState(ThreadState::Waiting); + SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Sleep); } if (event_handle != InvalidHandle) { diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index bf6bca2e4..6b66c9a0e 100755 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -113,6 +114,16 @@ enum class ThreadSchedFlags : u32 { KernelInitPauseFlag = 1 << 8, }; +enum class ThreadWaitReasonForDebugging : u32 { + None, ///< Thread is not waiting + Sleep, ///< Thread is waiting due to a SleepThread SVC + IPC, ///< Thread is waiting for the reply from an IPC request + Synchronization, ///< Thread is waiting due to a WaitSynchronization SVC + ConditionVar, ///< Thread is waiting due to a WaitProcessWideKey SVC + Arbitration, ///< Thread is waiting due to a SignalToAddress/WaitForAddress SVC + Suspended, ///< Thread is waiting due to process suspension +}; + class Thread final : public KSynchronizationObject, public boost::intrusive::list_base_hook<> { friend class KScheduler; friend class Process; @@ -514,11 +525,19 @@ public: disable_count--; } - void SetWaitObjectsForDebugging(KSynchronizationObject** objects, s32 num_objects) { + void SetWaitReasonForDebugging(ThreadWaitReasonForDebugging reason) { + wait_reason_for_debugging = reason; + } + + [[nodiscard]] ThreadWaitReasonForDebugging GetWaitReasonForDebugging() const { + return wait_reason_for_debugging; + } + + void SetWaitObjectsForDebugging(const std::span& objects) { wait_objects_for_debugging.clear(); - wait_objects_for_debugging.reserve(num_objects); - for (auto i = 0; i < num_objects; ++i) { - wait_objects_for_debugging.emplace_back(objects[i]); + wait_objects_for_debugging.reserve(objects.size()); + for (const auto& object : objects) { + wait_objects_for_debugging.emplace_back(object); } } @@ -548,11 +567,11 @@ public: return address_key_value; } - [[nodiscard]] void SetAddressKey(VAddr key) { + void SetAddressKey(VAddr key) { address_key = key; } - [[nodiscard]] void SetAddressKey(VAddr key, u32 val) { + void SetAddressKey(VAddr key, u32 val) { address_key = key; address_key_value = val; } @@ -560,11 +579,11 @@ public: private: static constexpr size_t PriorityInheritanceCountMax = 10; union SyncObjectBuffer { - std::array sync_objects; + std::array sync_objects{}; std::array handles; - constexpr SyncObjectBuffer() : sync_objects() {} + constexpr SyncObjectBuffer() {} }; static_assert(sizeof(SyncObjectBuffer::sync_objects) == sizeof(SyncObjectBuffer::handles)); @@ -707,6 +726,9 @@ private: /// The current mutex wait address. This is used for debugging only. VAddr mutex_wait_address_for_debugging{}; + /// The reason the thread is waiting. This is used for debugging only. + ThreadWaitReasonForDebugging wait_reason_for_debugging{}; + KSynchronizationObject* signaling_object; ResultCode signaling_result{RESULT_SUCCESS}; diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index 298f6d520..0bff97a37 100755 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp @@ -56,7 +56,7 @@ APM::APM(Core::System& system_, std::shared_ptr apm_, Controller& contro static const FunctionInfo functions[] = { {0, &APM::OpenSession, "OpenSession"}, {1, &APM::GetPerformanceMode, "GetPerformanceMode"}, - {6, nullptr, "IsCpuOverclockEnabled"}, + {6, &APM::IsCpuOverclockEnabled, "IsCpuOverclockEnabled"}, }; RegisterHandlers(functions); } @@ -78,6 +78,14 @@ void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) { rb.PushEnum(controller.GetCurrentPerformanceMode()); } +void APM::IsCpuOverclockEnabled(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_APM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(false); +} + APM_Sys::APM_Sys(Core::System& system_, Controller& controller_) : ServiceFramework{system_, "apm:sys"}, controller{controller_} { // clang-format off diff --git a/src/core/hle/service/apm/interface.h b/src/core/hle/service/apm/interface.h index 7d57c4978..063ad5308 100755 --- a/src/core/hle/service/apm/interface.h +++ b/src/core/hle/service/apm/interface.h @@ -20,6 +20,7 @@ public: private: void OpenSession(Kernel::HLERequestContext& ctx); void GetPerformanceMode(Kernel::HLERequestContext& ctx); + void IsCpuOverclockEnabled(Kernel::HLERequestContext& ctx); std::shared_ptr apm; Controller& controller; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index 0ac5fc6ae..644e7a209 100755 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -34,8 +34,7 @@ NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector& input, case 0xa: { if (command.length == 0x1c) { LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); - Tegra::ChCommandHeaderList cmdlist(1); - cmdlist[0] = Tegra::ChCommandHeader{0xDEADB33F}; + Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}}; system.GPU().PushCommandBuffer(cmdlist); system.GPU().MemoryManager().InvalidateQueuedCaches(); } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index 9118ab254..a2a08af42 100755 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -29,8 +29,13 @@ NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector& input, std::ve return GetWaitbase(input, output); case 0x9: return MapBuffer(input, output); - case 0xa: + case 0xa: { + if (command.length == 0x1c) { + Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}}; + system.GPU().PushCommandBuffer(cmdlist); + } return UnmapBuffer(input, output); + } default: break; } diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index c68905e19..5578181a4 100755 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -180,9 +180,11 @@ u32 BufferQueue::Query(QueryType type) { switch (type) { case QueryType::NativeWindowFormat: return static_cast(PixelFormat::RGBA8888); + case QueryType::NativeWindowWidth: + case QueryType::NativeWindowHeight: + break; } - - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented query type={}", type); return 0; } diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 5b637f3c5..8a606b448 100755 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -6,7 +6,6 @@ add_executable(tests common/ring_buffer.cpp core/core_timing.cpp tests.cpp - video_core/buffer_base.cpp ) create_target_directory_groups(tests) diff --git a/src/tests/common/ring_buffer.cpp b/src/tests/common/ring_buffer.cpp index c883c4d56..54def22da 100755 --- a/src/tests/common/ring_buffer.cpp +++ b/src/tests/common/ring_buffer.cpp @@ -20,60 +20,60 @@ TEST_CASE("RingBuffer: Basic Tests", "[common]") { for (std::size_t i = 0; i < 4; i++) { const char elem = static_cast(i); const std::size_t count = buf.Push(&elem, 1); - REQUIRE(count == 1); + REQUIRE(count == 1U); } - REQUIRE(buf.Size() == 4); + REQUIRE(buf.Size() == 4U); // Pushing values into a full ring buffer should fail. { const char elem = static_cast(42); const std::size_t count = buf.Push(&elem, 1); - REQUIRE(count == 0); + REQUIRE(count == 0U); } - REQUIRE(buf.Size() == 4); + REQUIRE(buf.Size() == 4U); // Popping multiple values from a ring buffer with values should succeed. { const std::vector popped = buf.Pop(2); - REQUIRE(popped.size() == 2); + REQUIRE(popped.size() == 2U); REQUIRE(popped[0] == 0); REQUIRE(popped[1] == 1); } - REQUIRE(buf.Size() == 2); + REQUIRE(buf.Size() == 2U); // Popping a single value from a ring buffer with values should succeed. { const std::vector popped = buf.Pop(1); - REQUIRE(popped.size() == 1); + REQUIRE(popped.size() == 1U); REQUIRE(popped[0] == 2); } - REQUIRE(buf.Size() == 1); + REQUIRE(buf.Size() == 1U); // Pushing more values than space available should partially suceed. { std::vector to_push(6); std::iota(to_push.begin(), to_push.end(), 88); const std::size_t count = buf.Push(to_push); - REQUIRE(count == 3); + REQUIRE(count == 3U); } - REQUIRE(buf.Size() == 4); + REQUIRE(buf.Size() == 4U); // Doing an unlimited pop should pop all values. { const std::vector popped = buf.Pop(); - REQUIRE(popped.size() == 4); + REQUIRE(popped.size() == 4U); REQUIRE(popped[0] == 3); REQUIRE(popped[1] == 88); REQUIRE(popped[2] == 89); REQUIRE(popped[3] == 90); } - REQUIRE(buf.Size() == 0); + REQUIRE(buf.Size() == 0U); } TEST_CASE("RingBuffer: Threaded Test", "[common]") { @@ -93,7 +93,7 @@ TEST_CASE("RingBuffer: Threaded Test", "[common]") { std::size_t i = 0; while (i < count) { if (const std::size_t c = buf.Push(&value[0], 1); c > 0) { - REQUIRE(c == 1); + REQUIRE(c == 1U); i++; next_value(value); } else { @@ -108,7 +108,7 @@ TEST_CASE("RingBuffer: Threaded Test", "[common]") { std::size_t i = 0; while (i < count) { if (const std::vector v = buf.Pop(1); v.size() > 0) { - REQUIRE(v.size() == 2); + REQUIRE(v.size() == 2U); REQUIRE(v[0] == value[0]); REQUIRE(v[1] == value[1]); i++; @@ -123,7 +123,7 @@ TEST_CASE("RingBuffer: Threaded Test", "[common]") { producer.join(); consumer.join(); - REQUIRE(buf.Size() == 0); + REQUIRE(buf.Size() == 0U); printf("RingBuffer: Threaded Test: full: %zu, empty: %zu\n", full, empty); } diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index e59d6d0ad..a1953a529 100755 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -1,7 +1,6 @@ add_subdirectory(host_shaders) add_library(video_core STATIC - buffer_cache/buffer_base.h buffer_cache/buffer_block.h buffer_cache/buffer_cache.h buffer_cache/map_interval.cpp diff --git a/src/video_core/cdma_pusher.cpp b/src/video_core/cdma_pusher.cpp index 94679d5d1..1228d38c8 100755 --- a/src/video_core/cdma_pusher.cpp +++ b/src/video_core/cdma_pusher.cpp @@ -37,59 +37,43 @@ CDmaPusher::CDmaPusher(GPU& gpu_) CDmaPusher::~CDmaPusher() = default; -void CDmaPusher::Push(ChCommandHeaderList&& entries) { - cdma_queue.push(std::move(entries)); -} - -void CDmaPusher::DispatchCalls() { - while (!cdma_queue.empty()) { - Step(); - } -} - -void CDmaPusher::Step() { - const auto entries{cdma_queue.front()}; - cdma_queue.pop(); - - std::vector values(entries.size()); - std::memcpy(values.data(), entries.data(), entries.size() * sizeof(u32)); - - for (const u32 value : values) { +void CDmaPusher::ProcessEntries(ChCommandHeaderList&& entries) { + for (const auto& value : entries) { if (mask != 0) { const u32 lbs = Common::CountTrailingZeroes32(mask); mask &= ~(1U << lbs); - ExecuteCommand(static_cast(offset + lbs), value); + ExecuteCommand(offset + lbs, value.raw); continue; } else if (count != 0) { --count; - ExecuteCommand(static_cast(offset), value); + ExecuteCommand(offset, value.raw); if (incrementing) { ++offset; } continue; } - const auto mode = static_cast((value >> 28) & 0xf); + const auto mode = value.submission_mode.Value(); switch (mode) { case ChSubmissionMode::SetClass: { - mask = value & 0x3f; - offset = (value >> 16) & 0xfff; - current_class = static_cast((value >> 6) & 0x3ff); + mask = value.value & 0x3f; + offset = value.method_offset; + current_class = static_cast((value.value >> 6) & 0x3ff); break; } case ChSubmissionMode::Incrementing: case ChSubmissionMode::NonIncrementing: - count = value & 0xffff; - offset = (value >> 16) & 0xfff; + count = value.value; + offset = value.method_offset; incrementing = mode == ChSubmissionMode::Incrementing; break; case ChSubmissionMode::Mask: - mask = value & 0xffff; - offset = (value >> 16) & 0xfff; + mask = value.value; + offset = value.method_offset; break; case ChSubmissionMode::Immediate: { - const u32 data = value & 0xfff; - offset = (value >> 16) & 0xfff; - ExecuteCommand(static_cast(offset), data); + const u32 data = value.value & 0xfff; + offset = value.method_offset; + ExecuteCommand(offset, data); break; } default: @@ -102,8 +86,8 @@ void CDmaPusher::Step() { void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { switch (current_class) { case ChClassId::NvDec: - ThiStateWrite(nvdec_thi_state, state_offset, {data}); - switch (static_cast(state_offset)) { + ThiStateWrite(nvdec_thi_state, offset, data); + switch (static_cast(offset)) { case ThiMethod::IncSyncpt: { LOG_DEBUG(Service_NVDRV, "NVDEC Class IncSyncpt Method"); const auto syncpoint_id = static_cast(data & 0xFF); @@ -120,7 +104,7 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { LOG_DEBUG(Service_NVDRV, "NVDEC method 0x{:X}", static_cast(nvdec_thi_state.method_0)); nvdec_processor->ProcessMethod(static_cast(nvdec_thi_state.method_0), - {data}); + data); break; default: break; @@ -144,7 +128,7 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { case ThiMethod::SetMethod1: LOG_DEBUG(Service_NVDRV, "VIC method 0x{:X}, Args=({})", static_cast(vic_thi_state.method_0), data); - vic_processor->ProcessMethod(static_cast(vic_thi_state.method_0), {data}); + vic_processor->ProcessMethod(static_cast(vic_thi_state.method_0), data); break; default: break; @@ -153,7 +137,7 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { case ChClassId::Host1x: // This device is mainly for syncpoint synchronization LOG_DEBUG(Service_NVDRV, "Host1X Class Method"); - host1x_processor->ProcessMethod(static_cast(state_offset), {data}); + host1x_processor->ProcessMethod(static_cast(offset), data); break; default: UNIMPLEMENTED_MSG("Current class not implemented {:X}", static_cast(current_class)); @@ -161,10 +145,9 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { } } -void CDmaPusher::ThiStateWrite(ThiRegisters& state, u32 state_offset, - const std::vector& arguments) { - u8* const state_offset_ptr = reinterpret_cast(&state) + sizeof(u32) * state_offset; - std::memcpy(state_offset_ptr, arguments.data(), sizeof(u32) * arguments.size()); +void CDmaPusher::ThiStateWrite(ThiRegisters& state, u32 state_offset, u32 argument) { + u8* const offset_ptr = reinterpret_cast(&state) + sizeof(u32) * state_offset; + std::memcpy(offset_ptr, &argument, sizeof(u32)); } } // namespace Tegra diff --git a/src/video_core/cdma_pusher.h b/src/video_core/cdma_pusher.h index 8ca70b6dd..1bada44dd 100755 --- a/src/video_core/cdma_pusher.h +++ b/src/video_core/cdma_pusher.h @@ -5,9 +5,7 @@ #pragma once #include -#include #include -#include #include "common/bit_field.h" #include "common/common_types.h" @@ -16,9 +14,9 @@ namespace Tegra { class GPU; +class Host1x; class Nvdec; class Vic; -class Host1x; enum class ChSubmissionMode : u32 { SetClass = 0, @@ -48,16 +46,10 @@ enum class ChClassId : u32 { NvDec = 0xf0 }; -enum class ChMethod : u32 { - Empty = 0, - SetMethod = 0x10, - SetData = 0x11, -}; - union ChCommandHeader { u32 raw; BitField<0, 16, u32> value; - BitField<16, 12, ChMethod> method_offset; + BitField<16, 12, u32> method_offset; BitField<28, 4, ChSubmissionMode> submission_mode; }; static_assert(sizeof(ChCommandHeader) == sizeof(u32), "ChCommand header is an invalid size"); @@ -99,21 +91,15 @@ public: explicit CDmaPusher(GPU& gpu_); ~CDmaPusher(); - /// Push NVDEC command buffer entries into queue - void Push(ChCommandHeaderList&& entries); - - /// Process queued command buffer entries - void DispatchCalls(); - - /// Process one queue element - void Step(); + /// Process the command entry + void ProcessEntries(ChCommandHeaderList&& entries); +private: /// Invoke command class devices to execute the command based on the current state void ExecuteCommand(u32 state_offset, u32 data); -private: /// Write arguments value to the ThiRegisters member at the specified offset - void ThiStateWrite(ThiRegisters& state, u32 state_offset, const std::vector& arguments); + void ThiStateWrite(ThiRegisters& state, u32 offset, u32 argument); GPU& gpu; std::shared_ptr nvdec_processor; @@ -124,13 +110,10 @@ private: ThiRegisters vic_thi_state{}; ThiRegisters nvdec_thi_state{}; - s32 count{}; - s32 offset{}; - s32 mask{}; + u32 count{}; + u32 offset{}; + u32 mask{}; bool incrementing{}; - - // Queue of command lists to be processed - std::queue cdma_queue; }; } // namespace Tegra diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp index 39bc923a5..d02dc6260 100755 --- a/src/video_core/command_classes/codecs/codec.cpp +++ b/src/video_core/command_classes/codecs/codec.cpp @@ -44,8 +44,10 @@ Codec::~Codec() { } void Codec::SetTargetCodec(NvdecCommon::VideoCodec codec) { - LOG_INFO(Service_NVDRV, "NVDEC video codec initialized to {}", codec); - current_codec = codec; + if (current_codec != codec) { + LOG_INFO(Service_NVDRV, "NVDEC video codec initialized to {}", static_cast(codec)); + current_codec = codec; + } } void Codec::StateWrite(u32 offset, u64 arguments) { @@ -55,7 +57,6 @@ void Codec::StateWrite(u32 offset, u64 arguments) { void Codec::Decode() { bool is_first_frame = false; - if (!initialized) { if (current_codec == NvdecCommon::VideoCodec::H264) { av_codec = avcodec_find_decoder(AV_CODEC_ID_H264); diff --git a/src/video_core/command_classes/nvdec.cpp b/src/video_core/command_classes/nvdec.cpp index 79e1f4e13..e4f919afd 100755 --- a/src/video_core/command_classes/nvdec.cpp +++ b/src/video_core/command_classes/nvdec.cpp @@ -12,16 +12,16 @@ Nvdec::Nvdec(GPU& gpu_) : gpu(gpu_), codec(std::make_unique(gpu)) {} Nvdec::~Nvdec() = default; -void Nvdec::ProcessMethod(Method method, const std::vector& arguments) { +void Nvdec::ProcessMethod(Method method, u32 argument) { if (method == Method::SetVideoCodec) { - codec->StateWrite(static_cast(method), arguments[0]); + codec->StateWrite(static_cast(method), argument); } else { - codec->StateWrite(static_cast(method), static_cast(arguments[0]) << 8); + codec->StateWrite(static_cast(method), static_cast(argument) << 8); } switch (method) { case Method::SetVideoCodec: - codec->SetTargetCodec(static_cast(arguments[0])); + codec->SetTargetCodec(static_cast(argument)); break; case Method::Execute: Execute(); diff --git a/src/video_core/command_classes/nvdec.h b/src/video_core/command_classes/nvdec.h index e4877c533..e66be80b8 100755 --- a/src/video_core/command_classes/nvdec.h +++ b/src/video_core/command_classes/nvdec.h @@ -23,7 +23,7 @@ public: ~Nvdec(); /// Writes the method into the state, Invoke Execute() if encountered - void ProcessMethod(Method method, const std::vector& arguments); + void ProcessMethod(Method method, u32 argument); /// Return most recently decoded frame [[nodiscard]] AVFramePtr GetFrame(); diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp index 55e632346..26ff755d0 100755 --- a/src/video_core/command_classes/vic.cpp +++ b/src/video_core/command_classes/vic.cpp @@ -18,18 +18,14 @@ extern "C" { namespace Tegra { Vic::Vic(GPU& gpu_, std::shared_ptr nvdec_processor_) - : gpu(gpu_), nvdec_processor(std::move(nvdec_processor_)) {} + : gpu(gpu_), + nvdec_processor(std::move(nvdec_processor_)), converted_frame_buffer{nullptr, av_free} {} + Vic::~Vic() = default; -void Vic::VicStateWrite(u32 offset, u32 arguments) { - u8* const state_offset = reinterpret_cast(&vic_state) + offset * sizeof(u32); - std::memcpy(state_offset, &arguments, sizeof(u32)); -} - -void Vic::ProcessMethod(Method method, const std::vector& arguments) { - LOG_DEBUG(HW_GPU, "Vic method 0x{:X}", method); - VicStateWrite(static_cast(method), arguments[0]); - const u64 arg = static_cast(arguments[0]) << 8; +void Vic::ProcessMethod(Method method, u32 argument) { + LOG_DEBUG(HW_GPU, "Vic method 0x{:X}", static_cast(method)); + const u64 arg = static_cast(argument) << 8; switch (method) { case Method::Execute: Execute(); @@ -53,8 +49,7 @@ void Vic::ProcessMethod(Method method, const std::vector& arguments) { void Vic::Execute() { if (output_surface_luma_address == 0) { - LOG_ERROR(Service_NVDRV, "VIC Luma address not set. Received 0x{:X}", - vic_state.output_surface.luma_offset); + LOG_ERROR(Service_NVDRV, "VIC Luma address not set."); return; } const VicConfig config{gpu.MemoryManager().Read(config_struct_address + 0x20)}; @@ -89,8 +84,10 @@ void Vic::Execute() { // Get Converted frame const std::size_t linear_size = frame->width * frame->height * 4; - using AVMallocPtr = std::unique_ptr; - AVMallocPtr converted_frame_buffer{static_cast(av_malloc(linear_size)), av_free}; + // Only allocate frame_buffer once per stream, as the size is not expected to change + if (!converted_frame_buffer) { + converted_frame_buffer = AVMallocPtr{static_cast(av_malloc(linear_size)), av_free}; + } const int converted_stride{frame->width * 4}; u8* const converted_frame_buf_addr{converted_frame_buffer.get()}; @@ -104,12 +101,12 @@ void Vic::Execute() { const u32 block_height = static_cast(config.block_linear_height_log2); const auto size = Tegra::Texture::CalculateSize(true, 4, frame->width, frame->height, 1, block_height, 0); - std::vector swizzled_data(size); + luma_buffer.resize(size); Tegra::Texture::SwizzleSubrect(frame->width, frame->height, frame->width * 4, - frame->width, 4, swizzled_data.data(), + frame->width, 4, luma_buffer.data(), converted_frame_buffer.get(), block_height, 0, 0); - gpu.MemoryManager().WriteBlock(output_surface_luma_address, swizzled_data.data(), size); + gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), size); gpu.Maxwell3D().OnMemoryWrite(); } else { // send pitch linear frame @@ -134,15 +131,15 @@ void Vic::Execute() { const auto stride = frame->linesize[0]; const auto half_stride = frame->linesize[1]; - std::vector luma_buffer(aligned_width * surface_height); - std::vector chroma_buffer(aligned_width * half_height); + luma_buffer.resize(aligned_width * surface_height); + chroma_buffer.resize(aligned_width * half_height); // Populate luma buffer for (std::size_t y = 0; y < surface_height - 1; ++y) { - std::size_t src = y * stride; - std::size_t dst = y * aligned_width; + const std::size_t src = y * stride; + const std::size_t dst = y * aligned_width; - std::size_t size = surface_width; + const std::size_t size = surface_width; for (std::size_t offset = 0; offset < size; ++offset) { luma_buffer[dst + offset] = luma_ptr[src + offset]; @@ -153,8 +150,8 @@ void Vic::Execute() { // Populate chroma buffer from both channels with interleaving. for (std::size_t y = 0; y < half_height; ++y) { - std::size_t src = y * half_stride; - std::size_t dst = y * aligned_width; + const std::size_t src = y * half_stride; + const std::size_t dst = y * aligned_width; for (std::size_t x = 0; x < half_width; ++x) { chroma_buffer[dst + x * 2] = chroma_b_ptr[src + x]; diff --git a/src/video_core/command_classes/vic.h b/src/video_core/command_classes/vic.h index 8c4e284a1..f5a2ed100 100755 --- a/src/video_core/command_classes/vic.h +++ b/src/video_core/command_classes/vic.h @@ -15,43 +15,6 @@ namespace Tegra { class GPU; class Nvdec; -struct PlaneOffsets { - u32 luma_offset{}; - u32 chroma_u_offset{}; - u32 chroma_v_offset{}; -}; - -struct VicRegisters { - INSERT_PADDING_WORDS(64); - u32 nop{}; - INSERT_PADDING_WORDS(15); - u32 pm_trigger{}; - INSERT_PADDING_WORDS(47); - u32 set_application_id{}; - u32 set_watchdog_timer{}; - INSERT_PADDING_WORDS(17); - u32 context_save_area{}; - u32 context_switch{}; - INSERT_PADDING_WORDS(43); - u32 execute{}; - INSERT_PADDING_WORDS(63); - std::array, 8> surfacex_slots{}; - u32 picture_index{}; - u32 control_params{}; - u32 config_struct_offset{}; - u32 filter_struct_offset{}; - u32 palette_offset{}; - u32 hist_offset{}; - u32 context_id{}; - u32 fce_ucode_size{}; - PlaneOffsets output_surface{}; - u32 fce_ucode_offset{}; - INSERT_PADDING_WORDS(4); - std::array slot_context_id{}; - INSERT_PADDING_WORDS(16); -}; -static_assert(sizeof(VicRegisters) == 0x7A0, "VicRegisters is an invalid size"); - class Vic { public: enum class Method : u32 { @@ -67,14 +30,11 @@ public: ~Vic(); /// Write to the device state. - void ProcessMethod(Method method, const std::vector& arguments); + void ProcessMethod(Method method, u32 argument); private: void Execute(); - void VicStateWrite(u32 offset, u32 arguments); - VicRegisters vic_state{}; - enum class VideoPixelFormat : u64_le { RGBA8 = 0x1f, BGRA8 = 0x20, @@ -88,8 +48,6 @@ private: BitField<9, 2, u64_le> chroma_loc_vert; BitField<11, 4, u64_le> block_linear_kind; BitField<15, 4, u64_le> block_linear_height_log2; - BitField<19, 3, u64_le> reserved0; - BitField<22, 10, u64_le> reserved1; BitField<32, 14, u64_le> surface_width_minus1; BitField<46, 14, u64_le> surface_height_minus1; }; @@ -97,6 +55,13 @@ private: GPU& gpu; std::shared_ptr nvdec_processor; + /// Avoid reallocation of the following buffers every frame, as their + /// size does not change during a stream + using AVMallocPtr = std::unique_ptr; + AVMallocPtr converted_frame_buffer; + std::vector luma_buffer; + std::vector chroma_buffer; + GPUVAddr config_struct_address{}; GPUVAddr output_surface_luma_address{}; GPUVAddr output_surface_chroma_u_address{}; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 6ab06775f..23bd793bb 100755 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -30,8 +30,7 @@ MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192)); GPU::GPU(Core::System& system_, bool is_async_, bool use_nvdec_) : system{system_}, memory_manager{std::make_unique(system)}, - dma_pusher{std::make_unique(system, *this)}, - cdma_pusher{std::make_unique(*this)}, use_nvdec{use_nvdec_}, + dma_pusher{std::make_unique(system, *this)}, use_nvdec{use_nvdec_}, maxwell_3d{std::make_unique(system, *memory_manager)}, fermi_2d{std::make_unique()}, kepler_compute{std::make_unique(system, *memory_manager)}, @@ -494,8 +493,7 @@ void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) { // TODO(ameerj): RE proper async nvdec operation // gpu_thread.SubmitCommandBuffer(std::move(entries)); - cdma_pusher->Push(std::move(entries)); - cdma_pusher->DispatchCalls(); + cdma_pusher->ProcessEntries(std::move(entries)); } void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 7e490bcc3..a43f725f3 100755 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -47,8 +47,7 @@ static void RunThread(Core::System& system, VideoCore::RendererBase& renderer, dma_pusher.DispatchCalls(); } else if (auto* command_list = std::get_if(&next.data)) { // NVDEC - cdma_pusher.Push(std::move(command_list->entries)); - cdma_pusher.DispatchCalls(); + cdma_pusher.ProcessEntries(std::move(command_list->entries)); } else if (const auto* data = std::get_if(&next.data)) { renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr); } else if (std::holds_alternative(next.data)) { diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index d134e54ba..ddfccc800 100755 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -475,7 +475,7 @@ bool GRenderWindow::TouchStart(const QTouchEvent::TouchPoint& touch_point) { bool GRenderWindow::TouchUpdate(const QTouchEvent::TouchPoint& touch_point) { for (std::size_t id = 0; id < touch_ids.size(); ++id) { - if (touch_ids[id] == touch_point.id() + 1) { + if (touch_ids[id] == static_cast(touch_point.id() + 1)) { const auto [x, y] = ScaleTouch(touch_point.pos()); this->TouchMoved(x, y, id + 1); return true; @@ -486,8 +486,9 @@ bool GRenderWindow::TouchUpdate(const QTouchEvent::TouchPoint& touch_point) { bool GRenderWindow::TouchExist(std::size_t id, const QList& touch_points) const { - return std::any_of(touch_points.begin(), touch_points.end(), - [id](const auto& point) { return id == point.id() + 1; }); + return std::any_of(touch_points.begin(), touch_points.end(), [id](const auto& point) { + return id == static_cast(point.id() + 1); + }); } bool GRenderWindow::event(QEvent* event) { diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index df34384df..5e4d22299 100755 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -508,7 +508,7 @@ void Config::ReadControlValues() { Settings::values.emulate_analog_keyboard = ReadSetting(QStringLiteral("emulate_analog_keyboard"), false).toBool(); - ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), false); + ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), true); ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled"), true); ReadSettingGlobal(Settings::values.enable_accurate_vibrations, @@ -1168,7 +1168,7 @@ void Config::SaveControlValues() { SaveTouchscreenValues(); SaveMotionTouchValues(); - WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false); + WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, true); WriteSettingGlobal(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled, true); WriteSettingGlobal(QStringLiteral("enable_accurate_vibrations"), diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp index d00b24048..4a09d0402 100755 --- a/src/yuzu/configuration/configure_motion_touch.cpp +++ b/src/yuzu/configuration/configure_motion_touch.cpp @@ -51,6 +51,8 @@ CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent, case CalibrationConfigurationJob::Status::Completed: text = tr("Configuration completed!"); break; + default: + break; } QMetaObject::invokeMethod(this, "UpdateLabelText", Q_ARG(QString, text)); if (status == CalibrationConfigurationJob::Status::Completed) { @@ -163,8 +165,9 @@ void ConfigureMotionTouch::ConnectEvents() { } void ConfigureMotionTouch::OnUDPAddServer() { - QRegExp re(tr(R"re(^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4]" - "[0-9]|[01]?[0-9][0-9]?)$)re")); // a valid ip address + // Validator for IP address + QRegExp re(QStringLiteral( + R"re(^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)re")); bool ok; QString port_text = ui->udp_port->text(); QString server_text = ui->udp_server->text(); diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 3ded85720..a93b5d3c2 100755 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -251,7 +251,29 @@ QString WaitTreeThread::GetText() const { } break; case Kernel::ThreadState::Waiting: - status = tr("waiting"); + switch (thread.GetWaitReasonForDebugging()) { + case Kernel::ThreadWaitReasonForDebugging::Sleep: + status = tr("sleeping"); + break; + case Kernel::ThreadWaitReasonForDebugging::IPC: + status = tr("waiting for IPC reply"); + break; + case Kernel::ThreadWaitReasonForDebugging::Synchronization: + status = tr("waiting for objects"); + break; + case Kernel::ThreadWaitReasonForDebugging::ConditionVar: + status = tr("waiting for condition variable"); + break; + case Kernel::ThreadWaitReasonForDebugging::Arbitration: + status = tr("waiting for address arbiter"); + break; + case Kernel::ThreadWaitReasonForDebugging::Suspended: + status = tr("waiting for suspend resume"); + break; + default: + status = tr("waiting"); + break; + } break; case Kernel::ThreadState::Initialized: status = tr("initialized"); @@ -259,6 +281,9 @@ QString WaitTreeThread::GetText() const { case Kernel::ThreadState::Terminated: status = tr("terminated"); break; + default: + status = tr("unknown"); + break; } const auto& context = thread.GetContext64(); @@ -285,7 +310,20 @@ QColor WaitTreeThread::GetColor() const { return QColor(WaitTreeColors[2][color_index]); } case Kernel::ThreadState::Waiting: - return QColor(WaitTreeColors[3][color_index]); + switch (thread.GetWaitReasonForDebugging()) { + case Kernel::ThreadWaitReasonForDebugging::IPC: + return QColor(WaitTreeColors[4][color_index]); + case Kernel::ThreadWaitReasonForDebugging::Sleep: + return QColor(WaitTreeColors[5][color_index]); + case Kernel::ThreadWaitReasonForDebugging::Synchronization: + case Kernel::ThreadWaitReasonForDebugging::ConditionVar: + case Kernel::ThreadWaitReasonForDebugging::Arbitration: + case Kernel::ThreadWaitReasonForDebugging::Suspended: + return QColor(WaitTreeColors[6][color_index]); + break; + default: + return QColor(WaitTreeColors[3][color_index]); + } case Kernel::ThreadState::Initialized: return QColor(WaitTreeColors[7][color_index]); case Kernel::ThreadState::Terminated: @@ -336,7 +374,9 @@ std::vector> WaitTreeThread::GetChildren() const { list.push_back(std::make_unique(tr("not waiting for mutex"))); } - if (thread.GetState() == Kernel::ThreadState::Waiting) { + if (thread.GetState() == Kernel::ThreadState::Waiting && + thread.GetWaitReasonForDebugging() == + Kernel::ThreadWaitReasonForDebugging::Synchronization) { list.push_back(std::make_unique(thread.GetWaitObjectsForDebugging(), thread.IsCancellable())); } diff --git a/src/yuzu/util/url_request_interceptor.cpp b/src/yuzu/util/url_request_interceptor.cpp index 2d491d8c0..b637e771e 100755 --- a/src/yuzu/util/url_request_interceptor.cpp +++ b/src/yuzu/util/url_request_interceptor.cpp @@ -22,6 +22,8 @@ void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo& info) { case QWebEngineUrlRequestInfo::ResourceTypeXhr: emit FrameChanged(); break; + default: + break; } } diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 966ebee39..f76102459 100755 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -340,7 +340,7 @@ void Config::ReadValues() { // System Settings::values.use_docked_mode.SetValue( - sdl2_config->GetBoolean("System", "use_docked_mode", false)); + sdl2_config->GetBoolean("System", "use_docked_mode", true)); Settings::values.current_user = std::clamp( sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1); diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 2d4b98d9a..3ee0e037d 100755 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h @@ -274,7 +274,7 @@ gamecard_path = [System] # Whether the system is docked -# 1: Yes, 0 (default): No +# 1 (default): Yes, 0: No use_docked_mode = # Allow the use of NFC in games diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 39e0d35aa..4faf62ede 100755 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -95,8 +95,6 @@ int main(int argc, char** argv) { int option_index = 0; InitializeLogging(); - - char* endarg; #ifdef _WIN32 int argc_w; auto argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w); diff --git a/src/yuzu_tester/config.cpp b/src/yuzu_tester/config.cpp index 4069d6027..efc795ef1 100755 --- a/src/yuzu_tester/config.cpp +++ b/src/yuzu_tester/config.cpp @@ -84,7 +84,7 @@ void Config::ReadValues() { Settings::values.touchscreen.diameter_y = 15; Settings::values.use_docked_mode.SetValue( - sdl2_config->GetBoolean("Controls", "use_docked_mode", false)); + sdl2_config->GetBoolean("Controls", "use_docked_mode", true)); // Data Storage Settings::values.use_virtual_sd = diff --git a/src/yuzu_tester/default_ini.h b/src/yuzu_tester/default_ini.h index 3eb64e9d7..779c3791b 100755 --- a/src/yuzu_tester/default_ini.h +++ b/src/yuzu_tester/default_ini.h @@ -116,7 +116,7 @@ use_virtual_sd = [System] # Whether the system is docked -# 1: Yes, 0 (default): No +# 1 (default): Yes, 0: No use_docked_mode = # Allow the use of NFC in games