diff options
author | pineappleEA <pineaea@gmail.com> | 2021-01-12 10:22:33 +0100 |
---|---|---|
committer | pineappleEA <pineaea@gmail.com> | 2021-01-12 10:22:33 +0100 |
commit | 4219fd41b91dd78cffdf70db1a07cc1bdf7c174e (patch) | |
tree | 145689d56256688aecbb41c7813637a674ddedce | |
parent | ebc2449a41ab3c8316796082658fe5b1f531c715 (diff) |
early-access version 1310EA-1310
49 files changed, 307 insertions, 341 deletions
@@ -1,7 +1,7 @@ | |||
1 | yuzu emulator early access | 1 | yuzu emulator early access |
2 | ============= | 2 | ============= |
3 | 3 | ||
4 | This is the source code for early-access 1298. | 4 | This is the source code for early-access 1310. |
5 | 5 | ||
6 | ## Legal Notice | 6 | ## Legal Notice |
7 | 7 | ||
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 @@ | |||
1 | diff --git a/CMakeModules/GenerateSCMRev.cmake b/CMakeModules/GenerateSCMRev.cmake | 1 | diff --git a/CMakeModules/GenerateSCMRev.cmake b/CMakeModules/GenerateSCMRev.cmake |
2 | index 311ba1c2e..79315b198 100644 | ||
3 | --- a/CMakeModules/GenerateSCMRev.cmake | 2 | --- a/CMakeModules/GenerateSCMRev.cmake |
4 | +++ b/CMakeModules/GenerateSCMRev.cmake | 3 | +++ b/CMakeModules/GenerateSCMRev.cmake |
5 | @@ -11,9 +11,9 @@ find_package(Git QUIET PATHS "${GIT_EXECUTABLE}") | 4 | @@ -11,10 +11,10 @@ |
6 | 5 | ||
7 | # generate git/build information | 6 | # generate git/build information |
8 | include(GetGitRevisionDescription) | 7 | include(GetGitRevisionDescription) |
9 | -get_git_head_revision(GIT_REF_SPEC GIT_REV) | 8 | -get_git_head_revision(GIT_REF_SPEC GIT_REV) |
10 | -git_describe(GIT_DESC --always --long --dirty) | 9 | -git_describe(GIT_DESC --always --long --dirty) |
11 | -git_branch_name(GIT_BRANCH) | 10 | -git_branch_name(GIT_BRANCH) |
11 | -get_timestamp(BUILD_DATE) | ||
12 | +#get_git_head_revision(GIT_REF_SPEC GIT_REV) | 12 | +#get_git_head_revision(GIT_REF_SPEC GIT_REV) |
13 | +#git_describe(GIT_DESC --always --long --dirty) | 13 | +#git_describe(GIT_DESC --always --long --dirty) |
14 | +#git_branch_name(GIT_BRANCH) | 14 | +#git_branch_name(GIT_BRANCH) |
15 | get_timestamp(BUILD_DATE) | 15 | +#get_timestamp(BUILD_DATE) |
16 | 16 | ||
17 | # Generate cpp with Git revision from template | 17 | # Generate cpp with Git revision from template |
18 | @@ -113,4 +113,5 @@ foreach (F IN LISTS HASH_FILES) | 18 | # Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well |
19 | @@ -113,4 +113,5 @@ | ||
19 | set(COMBINED "${COMBINED}${TMP}") | 20 | set(COMBINED "${COMBINED}${TMP}") |
20 | endforeach() | 21 | endforeach() |
21 | string(MD5 SHADER_CACHE_VERSION "${COMBINED}") | 22 | string(MD5 SHADER_CACHE_VERSION "${COMBINED}") |
22 | +set(BUILD_FULLNAME "${BUILD_FULLNAME} ") | 23 | +set(BUILD_FULLNAME "${BUILD_FULLNAME} ") |
23 | configure_file("${SRC_DIR}/src/common/scm_rev.cpp.in" "scm_rev.cpp" @ONLY) | 24 | configure_file("${SRC_DIR}/src/common/scm_rev.cpp.in" "scm_rev.cpp" @ONLY) |
24 | diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt | 25 | diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt |
25 | index d120c8d3d..bf3dcdbf6 100644 | ||
26 | --- a/src/common/CMakeLists.txt | 26 | --- a/src/common/CMakeLists.txt |
27 | +++ b/src/common/CMakeLists.txt | 27 | +++ b/src/common/CMakeLists.txt |
28 | @@ -28,6 +28,11 @@ add_custom_command(OUTPUT scm_rev.cpp | 28 | @@ -28,6 +28,12 @@ |
29 | -DBUILD_TAG="${BUILD_TAG}" | 29 | -DBUILD_TAG="${BUILD_TAG}" |
30 | -DBUILD_ID="${DISPLAY_VERSION}" | 30 | -DBUILD_ID="${DISPLAY_VERSION}" |
31 | -DGIT_EXECUTABLE="${GIT_EXECUTABLE}" | 31 | -DGIT_EXECUTABLE="${GIT_EXECUTABLE}" |
@@ -34,6 +34,7 @@ index d120c8d3d..bf3dcdbf6 100644 | |||
34 | + -DGIT_DESC="${GIT_DESC}" | 34 | + -DGIT_DESC="${GIT_DESC}" |
35 | + -DGIT_BRANCH="${GIT_BRANCH}" | 35 | + -DGIT_BRANCH="${GIT_BRANCH}" |
36 | + -DBUILD_FULLNAME="${BUILD_FULLNAME}" | 36 | + -DBUILD_FULLNAME="${BUILD_FULLNAME}" |
37 | + -DBUILD_DATE="${BUILD_DATE}" | ||
37 | -P "${CMAKE_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake" | 38 | -P "${CMAKE_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake" |
38 | DEPENDS | 39 | DEPENDS |
39 | # WARNING! It was too much work to try and make a common location for this list, | 40 | # 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) | |||
45 | 45 | ||
46 | # Warnings | 46 | # Warnings |
47 | /W3 | 47 | /W3 |
48 | /we4062 # enumerator 'identifier' in a switch of enum 'enumeration' is not handled | ||
49 | /we4101 # 'identifier': unreferenced local variable | ||
50 | /we4265 # 'class': class has virtual functions, but destructor is not virtual | ||
51 | /we4388 # signed/unsigned mismatch | ||
48 | /we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect | 52 | /we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect |
49 | /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? | 53 | /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? |
50 | /we4555 # Expression has no effect; expected expression with side-effect | 54 | /we4555 # Expression has no effect; expected expression with side-effect |
51 | /we4834 # Discarding return value of function with 'nodiscard' attribute | 55 | /we4834 # Discarding return value of function with 'nodiscard' attribute |
56 | /we5038 # data member 'member1' will be initialized after data member 'member2' | ||
52 | ) | 57 | ) |
53 | 58 | ||
54 | # /GS- - No stack buffer overflow checks | 59 | # /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 { | |||
11 | 11 | ||
12 | /// Ceiled integer division. | 12 | /// Ceiled integer division. |
13 | template <typename N, typename D> | 13 | template <typename N, typename D> |
14 | requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeil( | 14 | requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeil(N number, |
15 | N number, D divisor) { | 15 | D divisor) { |
16 | return (static_cast<D>(number) + divisor - 1) / divisor; | 16 | return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor); |
17 | } | 17 | } |
18 | 18 | ||
19 | /// Ceiled integer division with logarithmic divisor in base 2 | 19 | /// Ceiled integer division with logarithmic divisor in base 2 |
20 | template <typename N, typename D> | 20 | template <typename N, typename D> |
21 | requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeilLog2( | 21 | requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeilLog2( |
22 | N value, D alignment_log2) { | 22 | N value, D alignment_log2) { |
23 | return (static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2; | 23 | return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2); |
24 | } | 24 | } |
25 | 25 | ||
26 | } // namespace Common | 26 | } // 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 @@ | |||
1 | /* | 1 | // Copyright 2021 yuzu Emulator Project |
2 | * Copyright (c) 2018-2020 Atmosphère-NX | 2 | // Licensed under GPLv2 or any later version |
3 | * | 3 | // Refer to the license.txt file included. |
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | 4 | ||
17 | #pragma once | 5 | #pragma once |
18 | 6 | ||
@@ -30,7 +18,7 @@ class IntrusiveRedBlackTreeImpl; | |||
30 | struct IntrusiveRedBlackTreeNode { | 18 | struct IntrusiveRedBlackTreeNode { |
31 | 19 | ||
32 | private: | 20 | private: |
33 | RB_ENTRY(IntrusiveRedBlackTreeNode) entry; | 21 | RB_ENTRY(IntrusiveRedBlackTreeNode) entry{}; |
34 | 22 | ||
35 | friend class impl::IntrusiveRedBlackTreeImpl; | 23 | friend class impl::IntrusiveRedBlackTreeImpl; |
36 | 24 | ||
@@ -38,8 +26,7 @@ private: | |||
38 | friend class IntrusiveRedBlackTree; | 26 | friend class IntrusiveRedBlackTree; |
39 | 27 | ||
40 | public: | 28 | public: |
41 | constexpr IntrusiveRedBlackTreeNode() : entry() { /* ... */ | 29 | constexpr IntrusiveRedBlackTreeNode() = default; |
42 | } | ||
43 | }; | 30 | }; |
44 | 31 | ||
45 | template <class T, class Traits, class Comparator> | 32 | template <class T, class Traits, class Comparator> |
@@ -80,18 +67,16 @@ public: | |||
80 | using iterator_category = std::bidirectional_iterator_tag; | 67 | using iterator_category = std::bidirectional_iterator_tag; |
81 | using value_type = typename IntrusiveRedBlackTreeImpl::value_type; | 68 | using value_type = typename IntrusiveRedBlackTreeImpl::value_type; |
82 | using difference_type = typename IntrusiveRedBlackTreeImpl::difference_type; | 69 | using difference_type = typename IntrusiveRedBlackTreeImpl::difference_type; |
83 | using pointer = typename std::conditional<Const, IntrusiveRedBlackTreeImpl::const_pointer, | 70 | using pointer = std::conditional_t<Const, IntrusiveRedBlackTreeImpl::const_pointer, |
84 | IntrusiveRedBlackTreeImpl::pointer>::type; | 71 | IntrusiveRedBlackTreeImpl::pointer>; |
85 | using reference = | 72 | using reference = std::conditional_t<Const, IntrusiveRedBlackTreeImpl::const_reference, |
86 | typename std::conditional<Const, IntrusiveRedBlackTreeImpl::const_reference, | 73 | IntrusiveRedBlackTreeImpl::reference>; |
87 | IntrusiveRedBlackTreeImpl::reference>::type; | ||
88 | 74 | ||
89 | private: | 75 | private: |
90 | pointer node; | 76 | pointer node; |
91 | 77 | ||
92 | public: | 78 | public: |
93 | explicit Iterator(pointer n) : node(n) { /* ... */ | 79 | explicit Iterator(pointer n) : node(n) {} |
94 | } | ||
95 | 80 | ||
96 | bool operator==(const Iterator& rhs) const { | 81 | bool operator==(const Iterator& rhs) const { |
97 | return this->node == rhs.node; | 82 | return this->node == rhs.node; |
@@ -137,12 +122,11 @@ public: | |||
137 | }; | 122 | }; |
138 | 123 | ||
139 | protected: | 124 | protected: |
140 | /* Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot. | 125 | // Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot. |
141 | */ | ||
142 | RB_GENERATE_WITHOUT_COMPARE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry); | 126 | RB_GENERATE_WITHOUT_COMPARE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry); |
143 | 127 | ||
144 | private: | 128 | private: |
145 | /* Define accessors using RB_* functions. */ | 129 | // Define accessors using RB_* functions. |
146 | constexpr void InitializeImpl() { | 130 | constexpr void InitializeImpl() { |
147 | RB_INIT(&this->root); | 131 | RB_INIT(&this->root); |
148 | } | 132 | } |
@@ -174,12 +158,12 @@ public: | |||
174 | return RB_PREV(IntrusiveRedBlackTreeRoot, nullptr, node); | 158 | return RB_PREV(IntrusiveRedBlackTreeRoot, nullptr, node); |
175 | } | 159 | } |
176 | 160 | ||
177 | static IntrusiveRedBlackTreeNode const* GetNext(IntrusiveRedBlackTreeNode const* node) { | 161 | static IntrusiveRedBlackTreeNode const* GetNext(const IntrusiveRedBlackTreeNode* node) { |
178 | return static_cast<const IntrusiveRedBlackTreeNode*>( | 162 | return static_cast<const IntrusiveRedBlackTreeNode*>( |
179 | GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node))); | 163 | GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node))); |
180 | } | 164 | } |
181 | 165 | ||
182 | static IntrusiveRedBlackTreeNode const* GetPrev(IntrusiveRedBlackTreeNode const* node) { | 166 | static IntrusiveRedBlackTreeNode const* GetPrev(const IntrusiveRedBlackTreeNode* node) { |
183 | return static_cast<const IntrusiveRedBlackTreeNode*>( | 167 | return static_cast<const IntrusiveRedBlackTreeNode*>( |
184 | GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node))); | 168 | GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node))); |
185 | } | 169 | } |
@@ -189,7 +173,7 @@ public: | |||
189 | this->InitializeImpl(); | 173 | this->InitializeImpl(); |
190 | } | 174 | } |
191 | 175 | ||
192 | /* Iterator accessors. */ | 176 | // Iterator accessors. |
193 | iterator begin() { | 177 | iterator begin() { |
194 | return iterator(this->GetMinImpl()); | 178 | return iterator(this->GetMinImpl()); |
195 | } | 179 | } |
@@ -222,7 +206,7 @@ public: | |||
222 | return const_iterator(&ref); | 206 | return const_iterator(&ref); |
223 | } | 207 | } |
224 | 208 | ||
225 | /* Content management. */ | 209 | // Content management. |
226 | bool empty() const { | 210 | bool empty() const { |
227 | return this->EmptyImpl(); | 211 | return this->EmptyImpl(); |
228 | } | 212 | } |
@@ -273,8 +257,7 @@ consteval auto* GetLightCompareType() { | |||
273 | } // namespace impl | 257 | } // namespace impl |
274 | 258 | ||
275 | template <typename T, typename Default> | 259 | template <typename T, typename Default> |
276 | using LightCompareType = | 260 | using LightCompareType = std::remove_pointer_t<decltype(impl::GetLightCompareType<T, Default>())>; |
277 | typename std::remove_pointer<decltype(impl::GetLightCompareType<T, Default>())>::type; | ||
278 | 261 | ||
279 | template <class T, class Traits, class Comparator> | 262 | template <class T, class Traits, class Comparator> |
280 | class IntrusiveRedBlackTree { | 263 | class IntrusiveRedBlackTree { |
@@ -283,7 +266,7 @@ public: | |||
283 | using ImplType = impl::IntrusiveRedBlackTreeImpl; | 266 | using ImplType = impl::IntrusiveRedBlackTreeImpl; |
284 | 267 | ||
285 | private: | 268 | private: |
286 | ImplType impl; | 269 | ImplType impl{}; |
287 | 270 | ||
288 | public: | 271 | public: |
289 | struct IntrusiveRedBlackTreeRootWithCompare : ImplType::IntrusiveRedBlackTreeRoot {}; | 272 | struct IntrusiveRedBlackTreeRootWithCompare : ImplType::IntrusiveRedBlackTreeRoot {}; |
@@ -311,27 +294,25 @@ public: | |||
311 | friend class IntrusiveRedBlackTree<T, Traits, Comparator>; | 294 | friend class IntrusiveRedBlackTree<T, Traits, Comparator>; |
312 | 295 | ||
313 | using ImplIterator = | 296 | using ImplIterator = |
314 | typename std::conditional<Const, ImplType::const_iterator, ImplType::iterator>::type; | 297 | std::conditional_t<Const, ImplType::const_iterator, ImplType::iterator>; |
315 | 298 | ||
316 | using iterator_category = std::bidirectional_iterator_tag; | 299 | using iterator_category = std::bidirectional_iterator_tag; |
317 | using value_type = typename IntrusiveRedBlackTree::value_type; | 300 | using value_type = typename IntrusiveRedBlackTree::value_type; |
318 | using difference_type = typename IntrusiveRedBlackTree::difference_type; | 301 | using difference_type = typename IntrusiveRedBlackTree::difference_type; |
319 | using pointer = typename std::conditional<Const, IntrusiveRedBlackTree::const_pointer, | 302 | using pointer = std::conditional_t<Const, IntrusiveRedBlackTree::const_pointer, |
320 | IntrusiveRedBlackTree::pointer>::type; | 303 | IntrusiveRedBlackTree::pointer>; |
321 | using reference = typename std::conditional<Const, IntrusiveRedBlackTree::const_reference, | 304 | using reference = std::conditional_t<Const, IntrusiveRedBlackTree::const_reference, |
322 | IntrusiveRedBlackTree::reference>::type; | 305 | IntrusiveRedBlackTree::reference>; |
323 | 306 | ||
324 | private: | 307 | private: |
325 | ImplIterator iterator; | 308 | ImplIterator iterator; |
326 | 309 | ||
327 | private: | 310 | private: |
328 | explicit Iterator(ImplIterator it) : iterator(it) { /* ... */ | 311 | explicit Iterator(ImplIterator it) : iterator(it) {} |
329 | } | ||
330 | 312 | ||
331 | explicit Iterator(typename std::conditional<Const, ImplType::const_iterator, | 313 | explicit Iterator(typename std::conditional<Const, ImplType::const_iterator, |
332 | ImplType::iterator>::type::pointer ptr) | 314 | ImplType::iterator>::type::pointer ptr) |
333 | : iterator(ptr) { /* ... */ | 315 | : iterator(ptr) {} |
334 | } | ||
335 | 316 | ||
336 | ImplIterator GetImplIterator() const { | 317 | ImplIterator GetImplIterator() const { |
337 | return this->iterator; | 318 | return this->iterator; |
@@ -382,7 +363,7 @@ public: | |||
382 | }; | 363 | }; |
383 | 364 | ||
384 | private: | 365 | private: |
385 | /* Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot. */ | 366 | // Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot. |
386 | RB_GENERATE_WITH_COMPARE_STATIC(IntrusiveRedBlackTreeRootWithCompare, IntrusiveRedBlackTreeNode, | 367 | RB_GENERATE_WITH_COMPARE_STATIC(IntrusiveRedBlackTreeRootWithCompare, IntrusiveRedBlackTreeNode, |
387 | entry, CompareImpl, LightCompareImpl); | 368 | entry, CompareImpl, LightCompareImpl); |
388 | 369 | ||
@@ -396,14 +377,14 @@ private: | |||
396 | return Comparator::Compare(*static_cast<const_light_pointer>(elm), *Traits::GetParent(rhs)); | 377 | return Comparator::Compare(*static_cast<const_light_pointer>(elm), *Traits::GetParent(rhs)); |
397 | } | 378 | } |
398 | 379 | ||
399 | /* Define accessors using RB_* functions. */ | 380 | // Define accessors using RB_* functions. |
400 | IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) { | 381 | IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) { |
401 | return RB_INSERT(IntrusiveRedBlackTreeRootWithCompare, | 382 | return RB_INSERT(IntrusiveRedBlackTreeRootWithCompare, |
402 | static_cast<IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root), | 383 | static_cast<IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root), |
403 | node); | 384 | node); |
404 | } | 385 | } |
405 | 386 | ||
406 | IntrusiveRedBlackTreeNode* FindImpl(IntrusiveRedBlackTreeNode const* node) const { | 387 | IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const { |
407 | return RB_FIND( | 388 | return RB_FIND( |
408 | IntrusiveRedBlackTreeRootWithCompare, | 389 | IntrusiveRedBlackTreeRootWithCompare, |
409 | const_cast<IntrusiveRedBlackTreeRootWithCompare*>( | 390 | const_cast<IntrusiveRedBlackTreeRootWithCompare*>( |
@@ -411,7 +392,7 @@ private: | |||
411 | const_cast<IntrusiveRedBlackTreeNode*>(node)); | 392 | const_cast<IntrusiveRedBlackTreeNode*>(node)); |
412 | } | 393 | } |
413 | 394 | ||
414 | IntrusiveRedBlackTreeNode* NFindImpl(IntrusiveRedBlackTreeNode const* node) const { | 395 | IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const { |
415 | return RB_NFIND( | 396 | return RB_NFIND( |
416 | IntrusiveRedBlackTreeRootWithCompare, | 397 | IntrusiveRedBlackTreeRootWithCompare, |
417 | const_cast<IntrusiveRedBlackTreeRootWithCompare*>( | 398 | const_cast<IntrusiveRedBlackTreeRootWithCompare*>( |
@@ -436,10 +417,9 @@ private: | |||
436 | } | 417 | } |
437 | 418 | ||
438 | public: | 419 | public: |
439 | constexpr IntrusiveRedBlackTree() : impl() { /* ... */ | 420 | constexpr IntrusiveRedBlackTree() = default; |
440 | } | ||
441 | 421 | ||
442 | /* Iterator accessors. */ | 422 | // Iterator accessors. |
443 | iterator begin() { | 423 | iterator begin() { |
444 | return iterator(this->impl.begin()); | 424 | return iterator(this->impl.begin()); |
445 | } | 425 | } |
@@ -472,7 +452,7 @@ public: | |||
472 | return const_iterator(this->impl.iterator_to(*Traits::GetNode(std::addressof(ref)))); | 452 | return const_iterator(this->impl.iterator_to(*Traits::GetNode(std::addressof(ref)))); |
473 | } | 453 | } |
474 | 454 | ||
475 | /* Content management. */ | 455 | // Content management. |
476 | bool empty() const { | 456 | bool empty() const { |
477 | return this->impl.empty(); | 457 | return this->impl.empty(); |
478 | } | 458 | } |
@@ -548,12 +528,12 @@ private: | |||
548 | return GetParentPointer<Member, Derived>(node); | 528 | return GetParentPointer<Member, Derived>(node); |
549 | } | 529 | } |
550 | 530 | ||
551 | static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) { | 531 | static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { |
552 | return GetParentPointer<Member, Derived>(node); | 532 | return GetParentPointer<Member, Derived>(node); |
553 | } | 533 | } |
554 | 534 | ||
555 | private: | 535 | private: |
556 | static constexpr TYPED_STORAGE(Derived) DerivedStorage = {}; | 536 | static constexpr TypedStorage<Derived> DerivedStorage = {}; |
557 | static_assert(GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage)); | 537 | static_assert(GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage)); |
558 | }; | 538 | }; |
559 | 539 | ||
@@ -569,7 +549,7 @@ public: | |||
569 | using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl; | 549 | using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl; |
570 | 550 | ||
571 | static constexpr bool IsValid() { | 551 | static constexpr bool IsValid() { |
572 | TYPED_STORAGE(Derived) DerivedStorage = {}; | 552 | TypedStorage<Derived> DerivedStorage = {}; |
573 | return GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage); | 553 | return GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage); |
574 | } | 554 | } |
575 | 555 | ||
@@ -591,7 +571,7 @@ private: | |||
591 | return GetParentPointer<Member, Derived>(node); | 571 | return GetParentPointer<Member, Derived>(node); |
592 | } | 572 | } |
593 | 573 | ||
594 | static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) { | 574 | static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { |
595 | return GetParentPointer<Member, Derived>(node); | 575 | return GetParentPointer<Member, Derived>(node); |
596 | } | 576 | } |
597 | }; | 577 | }; |
@@ -639,7 +619,7 @@ private: | |||
639 | return static_cast<Derived*>(node); | 619 | return static_cast<Derived*>(node); |
640 | } | 620 | } |
641 | 621 | ||
642 | static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) { | 622 | static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) { |
643 | return static_cast<const Derived*>(node); | 623 | return static_cast<const Derived*>(node); |
644 | } | 624 | } |
645 | }; | 625 | }; |
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 @@ | |||
1 | /* | 1 | // Copyright 2021 yuzu Emulator Project |
2 | * Copyright (c) 2018-2020 Atmosphère-NX | 2 | // Licensed under GPLv2 or any later version |
3 | * | 3 | // Refer to the license.txt file included. |
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | 4 | ||
17 | #pragma once | 5 | #pragma once |
18 | 6 | ||
@@ -22,22 +10,24 @@ | |||
22 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
23 | 11 | ||
24 | namespace Common { | 12 | namespace Common { |
25 | 13 | namespace detail { | |
26 | template <typename T, size_t Size, size_t Align> | 14 | template <typename T, size_t Size, size_t Align> |
27 | struct TypedStorage { | 15 | struct TypedStorageImpl { |
28 | typename std::aligned_storage<Size, Align>::type _storage; | 16 | std::aligned_storage_t<Size, Align> storage_; |
29 | }; | 17 | }; |
18 | } // namespace detail | ||
30 | 19 | ||
31 | #define TYPED_STORAGE(...) TypedStorage<__VA_ARGS__, sizeof(__VA_ARGS__), alignof(__VA_ARGS__)> | 20 | template <typename T> |
21 | using TypedStorage = detail::TypedStorageImpl<T, sizeof(T), alignof(T)>; | ||
32 | 22 | ||
33 | template <typename T> | 23 | template <typename T> |
34 | static constexpr T* GetPointer(TYPED_STORAGE(T) & ts) { | 24 | static constexpr T* GetPointer(TypedStorage<T>& ts) { |
35 | return static_cast<T*>(static_cast<void*>(std::addressof(ts._storage))); | 25 | return static_cast<T*>(static_cast<void*>(std::addressof(ts.storage_))); |
36 | } | 26 | } |
37 | 27 | ||
38 | template <typename T> | 28 | template <typename T> |
39 | static constexpr const T* GetPointer(const TYPED_STORAGE(T) & ts) { | 29 | static constexpr const T* GetPointer(const TypedStorage<T>& ts) { |
40 | return static_cast<const T*>(static_cast<const void*>(std::addressof(ts._storage))); | 30 | return static_cast<const T*>(static_cast<const void*>(std::addressof(ts.storage_))); |
41 | } | 31 | } |
42 | 32 | ||
43 | namespace impl { | 33 | namespace impl { |
@@ -73,8 +63,7 @@ struct OffsetOfUnionHolder { | |||
73 | }; | 63 | }; |
74 | 64 | ||
75 | template <typename ParentType, typename MemberType> | 65 | template <typename ParentType, typename MemberType> |
76 | union UnionImpl<ParentType, MemberType, MaxDepth> { /* Empty ... */ | 66 | union UnionImpl<ParentType, MemberType, MaxDepth> {}; |
77 | }; | ||
78 | }; | 67 | }; |
79 | 68 | ||
80 | template <typename ParentType, typename MemberType> | 69 | template <typename ParentType, typename MemberType> |
@@ -83,13 +72,11 @@ struct OffsetOfCalculator { | |||
83 | typename OffsetOfUnionHolder<sizeof(MemberType)>::template UnionImpl<ParentType, MemberType, | 72 | typename OffsetOfUnionHolder<sizeof(MemberType)>::template UnionImpl<ParentType, MemberType, |
84 | 0>; | 73 | 0>; |
85 | union Union { | 74 | union Union { |
86 | char c; | 75 | char c{}; |
87 | UnionHolder first_union; | 76 | UnionHolder first_union; |
88 | TYPED_STORAGE(ParentType) parent; | 77 | TypedStorage<ParentType> parent; |
89 | 78 | ||
90 | /* This coerces the active member to be c. */ | 79 | constexpr Union() : c() {} |
91 | constexpr Union() : c() { /* ... */ | ||
92 | } | ||
93 | }; | 80 | }; |
94 | static constexpr Union U = {}; | 81 | static constexpr Union U = {}; |
95 | 82 | ||
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: | |||
71 | } | 71 | } |
72 | 72 | ||
73 | void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override { | 73 | void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override { |
74 | switch (exception) { | ||
75 | case Dynarmic::A32::Exception::UndefinedInstruction: | ||
76 | case Dynarmic::A32::Exception::UnpredictableInstruction: | ||
77 | break; | ||
78 | case Dynarmic::A32::Exception::Breakpoint: | ||
79 | break; | ||
80 | } | ||
81 | LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", | 74 | LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", |
82 | static_cast<std::size_t>(exception), pc, MemoryReadCode(pc)); | 75 | exception, pc, MemoryReadCode(pc)); |
83 | UNIMPLEMENTED(); | 76 | UNIMPLEMENTED(); |
84 | } | 77 | } |
85 | 78 | ||
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: | |||
67 | virtual void Refresh() = 0; | 67 | virtual void Refresh() = 0; |
68 | 68 | ||
69 | virtual bool HasEntry(u64 title_id, ContentRecordType type) const = 0; | 69 | virtual bool HasEntry(u64 title_id, ContentRecordType type) const = 0; |
70 | virtual bool HasEntry(ContentProviderEntry entry) const; | 70 | bool HasEntry(ContentProviderEntry entry) const; |
71 | 71 | ||
72 | virtual std::optional<u32> GetEntryVersion(u64 title_id) const = 0; | 72 | virtual std::optional<u32> GetEntryVersion(u64 title_id) const = 0; |
73 | 73 | ||
74 | virtual VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const = 0; | 74 | virtual VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const = 0; |
75 | virtual VirtualFile GetEntryUnparsed(ContentProviderEntry entry) const; | 75 | VirtualFile GetEntryUnparsed(ContentProviderEntry entry) const; |
76 | 76 | ||
77 | virtual VirtualFile GetEntryRaw(u64 title_id, ContentRecordType type) const = 0; | 77 | virtual VirtualFile GetEntryRaw(u64 title_id, ContentRecordType type) const = 0; |
78 | virtual VirtualFile GetEntryRaw(ContentProviderEntry entry) const; | 78 | VirtualFile GetEntryRaw(ContentProviderEntry entry) const; |
79 | 79 | ||
80 | virtual std::unique_ptr<NCA> GetEntry(u64 title_id, ContentRecordType type) const = 0; | 80 | virtual std::unique_ptr<NCA> GetEntry(u64 title_id, ContentRecordType type) const = 0; |
81 | virtual std::unique_ptr<NCA> GetEntry(ContentProviderEntry entry) const; | 81 | std::unique_ptr<NCA> GetEntry(ContentProviderEntry entry) const; |
82 | 82 | ||
83 | virtual std::vector<ContentProviderEntry> ListEntries() const; | 83 | virtual std::vector<ContentProviderEntry> ListEntries() const; |
84 | 84 | ||
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 @@ | |||
1 | // Copyright 2020 yuzu Emulator Project | 1 | // Copyright 2021 yuzu Emulator Project |
2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
4 | 4 | ||
5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
7 | |||
8 | #include "core/arm/exclusive_monitor.h" | 5 | #include "core/arm/exclusive_monitor.h" |
9 | #include "core/core.h" | 6 | #include "core/core.h" |
10 | #include "core/hle/kernel/k_address_arbiter.h" | 7 | #include "core/hle/kernel/k_address_arbiter.h" |
@@ -18,7 +15,8 @@ | |||
18 | 15 | ||
19 | namespace Kernel { | 16 | namespace Kernel { |
20 | 17 | ||
21 | KAddressArbiter::KAddressArbiter(Core::System& system) : system{system}, kernel{system.Kernel()} {} | 18 | KAddressArbiter::KAddressArbiter(Core::System& system_) |
19 | : system{system_}, kernel{system.Kernel()} {} | ||
22 | KAddressArbiter::~KAddressArbiter() = default; | 20 | KAddressArbiter::~KAddressArbiter() = default; |
23 | 21 | ||
24 | namespace { | 22 | namespace { |
@@ -278,6 +276,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement | |||
278 | cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr); | 276 | cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr); |
279 | thread_tree.insert(*cur_thread); | 277 | thread_tree.insert(*cur_thread); |
280 | cur_thread->SetState(ThreadState::Waiting); | 278 | cur_thread->SetState(ThreadState::Waiting); |
279 | cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); | ||
281 | } | 280 | } |
282 | 281 | ||
283 | // Cancel the timer wait. | 282 | // Cancel the timer wait. |
@@ -341,6 +340,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { | |||
341 | cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr); | 340 | cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr); |
342 | thread_tree.insert(*cur_thread); | 341 | thread_tree.insert(*cur_thread); |
343 | cur_thread->SetState(ThreadState::Waiting); | 342 | cur_thread->SetState(ThreadState::Waiting); |
343 | cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); | ||
344 | } | 344 | } |
345 | 345 | ||
346 | // Cancel the timer wait. | 346 | // 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 @@ | |||
1 | // Copyright 2020 yuzu Emulator Project | 1 | // Copyright 2021 yuzu Emulator Project |
2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
4 | 4 | ||
5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
7 | |||
8 | #pragma once | 5 | #pragma once |
9 | 6 | ||
10 | #include "common/assert.h" | 7 | #include "common/assert.h" |
@@ -26,7 +23,7 @@ class KAddressArbiter { | |||
26 | public: | 23 | public: |
27 | using ThreadTree = KConditionVariable::ThreadTree; | 24 | using ThreadTree = KConditionVariable::ThreadTree; |
28 | 25 | ||
29 | explicit KAddressArbiter(Core::System& system); | 26 | explicit KAddressArbiter(Core::System& system_); |
30 | ~KAddressArbiter(); | 27 | ~KAddressArbiter(); |
31 | 28 | ||
32 | [[nodiscard]] ResultCode SignalToAddress(VAddr addr, Svc::SignalType type, s32 value, | 29 | [[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 @@ | |||
1 | // Copyright 2020 yuzu Emulator Project | 1 | // Copyright 2021 yuzu Emulator Project |
2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
4 | 4 | ||
5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
7 | |||
8 | #include <vector> | 5 | #include <vector> |
9 | 6 | ||
10 | #include "core/arm/exclusive_monitor.h" | 7 | #include "core/arm/exclusive_monitor.h" |
@@ -63,8 +60,8 @@ bool UpdateLockAtomic(Core::System& system, u32* out, VAddr address, u32 if_zero | |||
63 | 60 | ||
64 | } // namespace | 61 | } // namespace |
65 | 62 | ||
66 | KConditionVariable::KConditionVariable(Core::System& system) | 63 | KConditionVariable::KConditionVariable(Core::System& system_) |
67 | : system{system}, kernel{system.Kernel()} {} | 64 | : system{system_}, kernel{system.Kernel()} {} |
68 | 65 | ||
69 | KConditionVariable::~KConditionVariable() = default; | 66 | KConditionVariable::~KConditionVariable() = default; |
70 | 67 | ||
@@ -136,6 +133,7 @@ ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 val | |||
136 | cur_thread->SetAddressKey(addr, value); | 133 | cur_thread->SetAddressKey(addr, value); |
137 | owner_thread->AddWaiter(cur_thread); | 134 | owner_thread->AddWaiter(cur_thread); |
138 | cur_thread->SetState(ThreadState::Waiting); | 135 | cur_thread->SetState(ThreadState::Waiting); |
136 | cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::ConditionVar); | ||
139 | cur_thread->SetMutexWaitAddressForDebugging(addr); | 137 | cur_thread->SetMutexWaitAddressForDebugging(addr); |
140 | } | 138 | } |
141 | } | 139 | } |
@@ -318,6 +316,7 @@ ResultCode KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) | |||
318 | // If the timeout is non-zero, set the thread as waiting. | 316 | // If the timeout is non-zero, set the thread as waiting. |
319 | if (timeout != 0) { | 317 | if (timeout != 0) { |
320 | cur_thread->SetState(ThreadState::Waiting); | 318 | cur_thread->SetState(ThreadState::Waiting); |
319 | cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::ConditionVar); | ||
321 | cur_thread->SetMutexWaitAddressForDebugging(addr); | 320 | cur_thread->SetMutexWaitAddressForDebugging(addr); |
322 | } | 321 | } |
323 | } | 322 | } |
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 @@ | |||
1 | // Copyright 2020 yuzu Emulator Project | 1 | // Copyright 2021 yuzu Emulator Project |
2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
4 | 4 | ||
5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
7 | |||
8 | #pragma once | 5 | #pragma once |
9 | 6 | ||
10 | #include "common/assert.h" | 7 | #include "common/assert.h" |
@@ -25,7 +22,7 @@ class KConditionVariable { | |||
25 | public: | 22 | public: |
26 | using ThreadTree = typename Thread::ConditionVariableThreadTreeType; | 23 | using ThreadTree = typename Thread::ConditionVariableThreadTreeType; |
27 | 24 | ||
28 | explicit KConditionVariable(Core::System& system); | 25 | explicit KConditionVariable(Core::System& system_); |
29 | ~KConditionVariable(); | 26 | ~KConditionVariable(); |
30 | 27 | ||
31 | // Arbitration | 28 | // 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 @@ | |||
1 | // Copyright 2020 yuzu Emulator Project | 1 | // Copyright 2021 yuzu Emulator Project |
2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
4 | 4 | ||
5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
7 | |||
8 | #include "common/assert.h" | 5 | #include "common/assert.h" |
9 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
10 | #include "core/hle/kernel/k_scheduler.h" | 7 | #include "core/hle/kernel/k_scheduler.h" |
@@ -75,12 +72,13 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, | |||
75 | } | 72 | } |
76 | 73 | ||
77 | // For debugging only | 74 | // For debugging only |
78 | thread->SetWaitObjectsForDebugging(objects, num_objects); | 75 | thread->SetWaitObjectsForDebugging({objects, static_cast<std::size_t>(num_objects)}); |
79 | 76 | ||
80 | // Mark the thread as waiting. | 77 | // Mark the thread as waiting. |
81 | thread->SetCancellable(); | 78 | thread->SetCancellable(); |
82 | thread->SetSyncedObject(nullptr, Svc::ResultTimedOut); | 79 | thread->SetSyncedObject(nullptr, Svc::ResultTimedOut); |
83 | thread->SetState(ThreadState::Waiting); | 80 | thread->SetState(ThreadState::Waiting); |
81 | thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Synchronization); | ||
84 | } | 82 | } |
85 | 83 | ||
86 | // The lock/sleep is done, so we should be able to get our result. | 84 | // 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, | |||
89 | thread->ClearCancellable(); | 87 | thread->ClearCancellable(); |
90 | 88 | ||
91 | // For debugging only | 89 | // For debugging only |
92 | thread->SetWaitObjectsForDebugging(nullptr, 0); | 90 | thread->SetWaitObjectsForDebugging({}); |
93 | 91 | ||
94 | // Cancel the timer as needed. | 92 | // Cancel the timer as needed. |
95 | if (timer != InvalidHandle) { | 93 | 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 @@ | |||
1 | // Copyright 2020 yuzu Emulator Project | 1 | // Copyright 2021 yuzu Emulator Project |
2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
4 | 4 | ||
5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
7 | |||
8 | #pragma once | 5 | #pragma once |
9 | 6 | ||
10 | #include <vector> | 7 | #include <vector> |
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) { | |||
605 | const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; | 605 | const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; |
606 | for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { | 606 | for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { |
607 | impl->suspend_threads[i]->SetState(state); | 607 | impl->suspend_threads[i]->SetState(state); |
608 | impl->suspend_threads[i]->SetWaitReasonForDebugging( | ||
609 | ThreadWaitReasonForDebugging::Suspended); | ||
608 | } | 610 | } |
609 | } | 611 | } |
610 | } | 612 | } |
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: | |||
301 | 301 | ||
302 | void LoadModule(CodeSet code_set, VAddr base_addr); | 302 | void LoadModule(CodeSet code_set, VAddr base_addr); |
303 | 303 | ||
304 | virtual bool IsSignaled() const override; | 304 | bool IsSignaled() const override; |
305 | 305 | ||
306 | /////////////////////////////////////////////////////////////////////////////////////////////// | 306 | /////////////////////////////////////////////////////////////////////////////////////////////// |
307 | // Thread-local storage management | 307 | // 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: | |||
45 | 45 | ||
46 | void Signal(); | 46 | void Signal(); |
47 | 47 | ||
48 | virtual bool IsSignaled() const override; | 48 | bool IsSignaled() const override; |
49 | 49 | ||
50 | private: | 50 | private: |
51 | explicit ReadableEvent(KernelCore& kernel); | 51 | 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: | |||
79 | /// waiting to be accepted by this port. | 79 | /// waiting to be accepted by this port. |
80 | void AppendPendingSession(std::shared_ptr<ServerSession> pending_session); | 80 | void AppendPendingSession(std::shared_ptr<ServerSession> pending_session); |
81 | 81 | ||
82 | virtual bool IsSignaled() const override; | 82 | bool IsSignaled() const override; |
83 | 83 | ||
84 | private: | 84 | private: |
85 | /// ServerSessions waiting to be accepted by the port | 85 | /// 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: | |||
124 | convert_to_domain = true; | 124 | convert_to_domain = true; |
125 | } | 125 | } |
126 | 126 | ||
127 | virtual bool IsSignaled() const override; | 127 | bool IsSignaled() const override; |
128 | 128 | ||
129 | private: | 129 | private: |
130 | /// Queues a sync request from the emulated application. | 130 | /// 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) { | |||
347 | { | 347 | { |
348 | KScopedSchedulerLock lock(kernel); | 348 | KScopedSchedulerLock lock(kernel); |
349 | thread->SetState(ThreadState::Waiting); | 349 | thread->SetState(ThreadState::Waiting); |
350 | thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); | ||
350 | session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); | 351 | session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); |
351 | } | 352 | } |
352 | 353 | ||
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 { | |||
215 | void Thread::SetState(ThreadState state) { | 215 | void Thread::SetState(ThreadState state) { |
216 | KScopedSchedulerLock sl(kernel); | 216 | KScopedSchedulerLock sl(kernel); |
217 | 217 | ||
218 | SetMutexWaitAddressForDebugging(0); | 218 | // Clear debugging state |
219 | SetMutexWaitAddressForDebugging({}); | ||
220 | SetWaitReasonForDebugging({}); | ||
221 | |||
219 | const ThreadState old_state = thread_state; | 222 | const ThreadState old_state = thread_state; |
220 | thread_state = | 223 | thread_state = |
221 | static_cast<ThreadState>((old_state & ~ThreadState::Mask) | (state & ThreadState::Mask)); | 224 | static_cast<ThreadState>((old_state & ~ThreadState::Mask) | (state & ThreadState::Mask)); |
@@ -386,6 +389,7 @@ ResultCode Thread::Sleep(s64 nanoseconds) { | |||
386 | { | 389 | { |
387 | KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds); | 390 | KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds); |
388 | SetState(ThreadState::Waiting); | 391 | SetState(ThreadState::Waiting); |
392 | SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Sleep); | ||
389 | } | 393 | } |
390 | 394 | ||
391 | if (event_handle != InvalidHandle) { | 395 | 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 @@ | |||
6 | 6 | ||
7 | #include <array> | 7 | #include <array> |
8 | #include <functional> | 8 | #include <functional> |
9 | #include <span> | ||
9 | #include <string> | 10 | #include <string> |
10 | #include <utility> | 11 | #include <utility> |
11 | #include <vector> | 12 | #include <vector> |
@@ -113,6 +114,16 @@ enum class ThreadSchedFlags : u32 { | |||
113 | KernelInitPauseFlag = 1 << 8, | 114 | KernelInitPauseFlag = 1 << 8, |
114 | }; | 115 | }; |
115 | 116 | ||
117 | enum class ThreadWaitReasonForDebugging : u32 { | ||
118 | None, ///< Thread is not waiting | ||
119 | Sleep, ///< Thread is waiting due to a SleepThread SVC | ||
120 | IPC, ///< Thread is waiting for the reply from an IPC request | ||
121 | Synchronization, ///< Thread is waiting due to a WaitSynchronization SVC | ||
122 | ConditionVar, ///< Thread is waiting due to a WaitProcessWideKey SVC | ||
123 | Arbitration, ///< Thread is waiting due to a SignalToAddress/WaitForAddress SVC | ||
124 | Suspended, ///< Thread is waiting due to process suspension | ||
125 | }; | ||
126 | |||
116 | class Thread final : public KSynchronizationObject, public boost::intrusive::list_base_hook<> { | 127 | class Thread final : public KSynchronizationObject, public boost::intrusive::list_base_hook<> { |
117 | friend class KScheduler; | 128 | friend class KScheduler; |
118 | friend class Process; | 129 | friend class Process; |
@@ -514,11 +525,19 @@ public: | |||
514 | disable_count--; | 525 | disable_count--; |
515 | } | 526 | } |
516 | 527 | ||
517 | void SetWaitObjectsForDebugging(KSynchronizationObject** objects, s32 num_objects) { | 528 | void SetWaitReasonForDebugging(ThreadWaitReasonForDebugging reason) { |
529 | wait_reason_for_debugging = reason; | ||
530 | } | ||
531 | |||
532 | [[nodiscard]] ThreadWaitReasonForDebugging GetWaitReasonForDebugging() const { | ||
533 | return wait_reason_for_debugging; | ||
534 | } | ||
535 | |||
536 | void SetWaitObjectsForDebugging(const std::span<KSynchronizationObject*>& objects) { | ||
518 | wait_objects_for_debugging.clear(); | 537 | wait_objects_for_debugging.clear(); |
519 | wait_objects_for_debugging.reserve(num_objects); | 538 | wait_objects_for_debugging.reserve(objects.size()); |
520 | for (auto i = 0; i < num_objects; ++i) { | 539 | for (const auto& object : objects) { |
521 | wait_objects_for_debugging.emplace_back(objects[i]); | 540 | wait_objects_for_debugging.emplace_back(object); |
522 | } | 541 | } |
523 | } | 542 | } |
524 | 543 | ||
@@ -548,11 +567,11 @@ public: | |||
548 | return address_key_value; | 567 | return address_key_value; |
549 | } | 568 | } |
550 | 569 | ||
551 | [[nodiscard]] void SetAddressKey(VAddr key) { | 570 | void SetAddressKey(VAddr key) { |
552 | address_key = key; | 571 | address_key = key; |
553 | } | 572 | } |
554 | 573 | ||
555 | [[nodiscard]] void SetAddressKey(VAddr key, u32 val) { | 574 | void SetAddressKey(VAddr key, u32 val) { |
556 | address_key = key; | 575 | address_key = key; |
557 | address_key_value = val; | 576 | address_key_value = val; |
558 | } | 577 | } |
@@ -560,11 +579,11 @@ public: | |||
560 | private: | 579 | private: |
561 | static constexpr size_t PriorityInheritanceCountMax = 10; | 580 | static constexpr size_t PriorityInheritanceCountMax = 10; |
562 | union SyncObjectBuffer { | 581 | union SyncObjectBuffer { |
563 | std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects; | 582 | std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{}; |
564 | std::array<Handle, | 583 | std::array<Handle, |
565 | Svc::ArgumentHandleCountMax*(sizeof(KSynchronizationObject*) / sizeof(Handle))> | 584 | Svc::ArgumentHandleCountMax*(sizeof(KSynchronizationObject*) / sizeof(Handle))> |
566 | handles; | 585 | handles; |
567 | constexpr SyncObjectBuffer() : sync_objects() {} | 586 | constexpr SyncObjectBuffer() {} |
568 | }; | 587 | }; |
569 | static_assert(sizeof(SyncObjectBuffer::sync_objects) == sizeof(SyncObjectBuffer::handles)); | 588 | static_assert(sizeof(SyncObjectBuffer::sync_objects) == sizeof(SyncObjectBuffer::handles)); |
570 | 589 | ||
@@ -707,6 +726,9 @@ private: | |||
707 | /// The current mutex wait address. This is used for debugging only. | 726 | /// The current mutex wait address. This is used for debugging only. |
708 | VAddr mutex_wait_address_for_debugging{}; | 727 | VAddr mutex_wait_address_for_debugging{}; |
709 | 728 | ||
729 | /// The reason the thread is waiting. This is used for debugging only. | ||
730 | ThreadWaitReasonForDebugging wait_reason_for_debugging{}; | ||
731 | |||
710 | KSynchronizationObject* signaling_object; | 732 | KSynchronizationObject* signaling_object; |
711 | ResultCode signaling_result{RESULT_SUCCESS}; | 733 | ResultCode signaling_result{RESULT_SUCCESS}; |
712 | 734 | ||
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<Module> apm_, Controller& contro | |||
56 | static const FunctionInfo functions[] = { | 56 | static const FunctionInfo functions[] = { |
57 | {0, &APM::OpenSession, "OpenSession"}, | 57 | {0, &APM::OpenSession, "OpenSession"}, |
58 | {1, &APM::GetPerformanceMode, "GetPerformanceMode"}, | 58 | {1, &APM::GetPerformanceMode, "GetPerformanceMode"}, |
59 | {6, nullptr, "IsCpuOverclockEnabled"}, | 59 | {6, &APM::IsCpuOverclockEnabled, "IsCpuOverclockEnabled"}, |
60 | }; | 60 | }; |
61 | RegisterHandlers(functions); | 61 | RegisterHandlers(functions); |
62 | } | 62 | } |
@@ -78,6 +78,14 @@ void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) { | |||
78 | rb.PushEnum(controller.GetCurrentPerformanceMode()); | 78 | rb.PushEnum(controller.GetCurrentPerformanceMode()); |
79 | } | 79 | } |
80 | 80 | ||
81 | void APM::IsCpuOverclockEnabled(Kernel::HLERequestContext& ctx) { | ||
82 | LOG_WARNING(Service_APM, "(STUBBED) called"); | ||
83 | |||
84 | IPC::ResponseBuilder rb{ctx, 3}; | ||
85 | rb.Push(RESULT_SUCCESS); | ||
86 | rb.Push(false); | ||
87 | } | ||
88 | |||
81 | APM_Sys::APM_Sys(Core::System& system_, Controller& controller_) | 89 | APM_Sys::APM_Sys(Core::System& system_, Controller& controller_) |
82 | : ServiceFramework{system_, "apm:sys"}, controller{controller_} { | 90 | : ServiceFramework{system_, "apm:sys"}, controller{controller_} { |
83 | // clang-format off | 91 | // 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: | |||
20 | private: | 20 | private: |
21 | void OpenSession(Kernel::HLERequestContext& ctx); | 21 | void OpenSession(Kernel::HLERequestContext& ctx); |
22 | void GetPerformanceMode(Kernel::HLERequestContext& ctx); | 22 | void GetPerformanceMode(Kernel::HLERequestContext& ctx); |
23 | void IsCpuOverclockEnabled(Kernel::HLERequestContext& ctx); | ||
23 | 24 | ||
24 | std::shared_ptr<Module> apm; | 25 | std::shared_ptr<Module> apm; |
25 | Controller& controller; | 26 | 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<u8>& input, | |||
34 | case 0xa: { | 34 | case 0xa: { |
35 | if (command.length == 0x1c) { | 35 | if (command.length == 0x1c) { |
36 | LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); | 36 | LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); |
37 | Tegra::ChCommandHeaderList cmdlist(1); | 37 | Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}}; |
38 | cmdlist[0] = Tegra::ChCommandHeader{0xDEADB33F}; | ||
39 | system.GPU().PushCommandBuffer(cmdlist); | 38 | system.GPU().PushCommandBuffer(cmdlist); |
40 | system.GPU().MemoryManager().InvalidateQueuedCaches(); | 39 | system.GPU().MemoryManager().InvalidateQueuedCaches(); |
41 | } | 40 | } |
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<u8>& input, std::ve | |||
29 | return GetWaitbase(input, output); | 29 | return GetWaitbase(input, output); |
30 | case 0x9: | 30 | case 0x9: |
31 | return MapBuffer(input, output); | 31 | return MapBuffer(input, output); |
32 | case 0xa: | 32 | case 0xa: { |
33 | if (command.length == 0x1c) { | ||
34 | Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}}; | ||
35 | system.GPU().PushCommandBuffer(cmdlist); | ||
36 | } | ||
33 | return UnmapBuffer(input, output); | 37 | return UnmapBuffer(input, output); |
38 | } | ||
34 | default: | 39 | default: |
35 | break; | 40 | break; |
36 | } | 41 | } |
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) { | |||
180 | switch (type) { | 180 | switch (type) { |
181 | case QueryType::NativeWindowFormat: | 181 | case QueryType::NativeWindowFormat: |
182 | return static_cast<u32>(PixelFormat::RGBA8888); | 182 | return static_cast<u32>(PixelFormat::RGBA8888); |
183 | case QueryType::NativeWindowWidth: | ||
184 | case QueryType::NativeWindowHeight: | ||
185 | break; | ||
183 | } | 186 | } |
184 | 187 | UNIMPLEMENTED_MSG("Unimplemented query type={}", type); | |
185 | UNIMPLEMENTED(); | ||
186 | return 0; | 188 | return 0; |
187 | } | 189 | } |
188 | 190 | ||
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 | |||
6 | common/ring_buffer.cpp | 6 | common/ring_buffer.cpp |
7 | core/core_timing.cpp | 7 | core/core_timing.cpp |
8 | tests.cpp | 8 | tests.cpp |
9 | video_core/buffer_base.cpp | ||
10 | ) | 9 | ) |
11 | 10 | ||
12 | create_target_directory_groups(tests) | 11 | 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]") { | |||
20 | for (std::size_t i = 0; i < 4; i++) { | 20 | for (std::size_t i = 0; i < 4; i++) { |
21 | const char elem = static_cast<char>(i); | 21 | const char elem = static_cast<char>(i); |
22 | const std::size_t count = buf.Push(&elem, 1); | 22 | const std::size_t count = buf.Push(&elem, 1); |
23 | REQUIRE(count == 1); | 23 | REQUIRE(count == 1U); |
24 | } | 24 | } |
25 | 25 | ||
26 | REQUIRE(buf.Size() == 4); | 26 | REQUIRE(buf.Size() == 4U); |
27 | 27 | ||
28 | // Pushing values into a full ring buffer should fail. | 28 | // Pushing values into a full ring buffer should fail. |
29 | { | 29 | { |
30 | const char elem = static_cast<char>(42); | 30 | const char elem = static_cast<char>(42); |
31 | const std::size_t count = buf.Push(&elem, 1); | 31 | const std::size_t count = buf.Push(&elem, 1); |
32 | REQUIRE(count == 0); | 32 | REQUIRE(count == 0U); |
33 | } | 33 | } |
34 | 34 | ||
35 | REQUIRE(buf.Size() == 4); | 35 | REQUIRE(buf.Size() == 4U); |
36 | 36 | ||
37 | // Popping multiple values from a ring buffer with values should succeed. | 37 | // Popping multiple values from a ring buffer with values should succeed. |
38 | { | 38 | { |
39 | const std::vector<char> popped = buf.Pop(2); | 39 | const std::vector<char> popped = buf.Pop(2); |
40 | REQUIRE(popped.size() == 2); | 40 | REQUIRE(popped.size() == 2U); |
41 | REQUIRE(popped[0] == 0); | 41 | REQUIRE(popped[0] == 0); |
42 | REQUIRE(popped[1] == 1); | 42 | REQUIRE(popped[1] == 1); |
43 | } | 43 | } |
44 | 44 | ||
45 | REQUIRE(buf.Size() == 2); | 45 | REQUIRE(buf.Size() == 2U); |
46 | 46 | ||
47 | // Popping a single value from a ring buffer with values should succeed. | 47 | // Popping a single value from a ring buffer with values should succeed. |
48 | { | 48 | { |
49 | const std::vector<char> popped = buf.Pop(1); | 49 | const std::vector<char> popped = buf.Pop(1); |
50 | REQUIRE(popped.size() == 1); | 50 | REQUIRE(popped.size() == 1U); |
51 | REQUIRE(popped[0] == 2); | 51 | REQUIRE(popped[0] == 2); |
52 | } | 52 | } |
53 | 53 | ||
54 | REQUIRE(buf.Size() == 1); | 54 | REQUIRE(buf.Size() == 1U); |
55 | 55 | ||
56 | // Pushing more values than space available should partially suceed. | 56 | // Pushing more values than space available should partially suceed. |
57 | { | 57 | { |
58 | std::vector<char> to_push(6); | 58 | std::vector<char> to_push(6); |
59 | std::iota(to_push.begin(), to_push.end(), 88); | 59 | std::iota(to_push.begin(), to_push.end(), 88); |
60 | const std::size_t count = buf.Push(to_push); | 60 | const std::size_t count = buf.Push(to_push); |
61 | REQUIRE(count == 3); | 61 | REQUIRE(count == 3U); |
62 | } | 62 | } |
63 | 63 | ||
64 | REQUIRE(buf.Size() == 4); | 64 | REQUIRE(buf.Size() == 4U); |
65 | 65 | ||
66 | // Doing an unlimited pop should pop all values. | 66 | // Doing an unlimited pop should pop all values. |
67 | { | 67 | { |
68 | const std::vector<char> popped = buf.Pop(); | 68 | const std::vector<char> popped = buf.Pop(); |
69 | REQUIRE(popped.size() == 4); | 69 | REQUIRE(popped.size() == 4U); |
70 | REQUIRE(popped[0] == 3); | 70 | REQUIRE(popped[0] == 3); |
71 | REQUIRE(popped[1] == 88); | 71 | REQUIRE(popped[1] == 88); |
72 | REQUIRE(popped[2] == 89); | 72 | REQUIRE(popped[2] == 89); |
73 | REQUIRE(popped[3] == 90); | 73 | REQUIRE(popped[3] == 90); |
74 | } | 74 | } |
75 | 75 | ||
76 | REQUIRE(buf.Size() == 0); | 76 | REQUIRE(buf.Size() == 0U); |
77 | } | 77 | } |
78 | 78 | ||
79 | TEST_CASE("RingBuffer: Threaded Test", "[common]") { | 79 | TEST_CASE("RingBuffer: Threaded Test", "[common]") { |
@@ -93,7 +93,7 @@ TEST_CASE("RingBuffer: Threaded Test", "[common]") { | |||
93 | std::size_t i = 0; | 93 | std::size_t i = 0; |
94 | while (i < count) { | 94 | while (i < count) { |
95 | if (const std::size_t c = buf.Push(&value[0], 1); c > 0) { | 95 | if (const std::size_t c = buf.Push(&value[0], 1); c > 0) { |
96 | REQUIRE(c == 1); | 96 | REQUIRE(c == 1U); |
97 | i++; | 97 | i++; |
98 | next_value(value); | 98 | next_value(value); |
99 | } else { | 99 | } else { |
@@ -108,7 +108,7 @@ TEST_CASE("RingBuffer: Threaded Test", "[common]") { | |||
108 | std::size_t i = 0; | 108 | std::size_t i = 0; |
109 | while (i < count) { | 109 | while (i < count) { |
110 | if (const std::vector<char> v = buf.Pop(1); v.size() > 0) { | 110 | if (const std::vector<char> v = buf.Pop(1); v.size() > 0) { |
111 | REQUIRE(v.size() == 2); | 111 | REQUIRE(v.size() == 2U); |
112 | REQUIRE(v[0] == value[0]); | 112 | REQUIRE(v[0] == value[0]); |
113 | REQUIRE(v[1] == value[1]); | 113 | REQUIRE(v[1] == value[1]); |
114 | i++; | 114 | i++; |
@@ -123,7 +123,7 @@ TEST_CASE("RingBuffer: Threaded Test", "[common]") { | |||
123 | producer.join(); | 123 | producer.join(); |
124 | consumer.join(); | 124 | consumer.join(); |
125 | 125 | ||
126 | REQUIRE(buf.Size() == 0); | 126 | REQUIRE(buf.Size() == 0U); |
127 | printf("RingBuffer: Threaded Test: full: %zu, empty: %zu\n", full, empty); | 127 | printf("RingBuffer: Threaded Test: full: %zu, empty: %zu\n", full, empty); |
128 | } | 128 | } |
129 | 129 | ||
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 @@ | |||
1 | add_subdirectory(host_shaders) | 1 | add_subdirectory(host_shaders) |
2 | 2 | ||
3 | add_library(video_core STATIC | 3 | add_library(video_core STATIC |
4 | buffer_cache/buffer_base.h | ||
5 | buffer_cache/buffer_block.h | 4 | buffer_cache/buffer_block.h |
6 | buffer_cache/buffer_cache.h | 5 | buffer_cache/buffer_cache.h |
7 | buffer_cache/map_interval.cpp | 6 | 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_) | |||
37 | 37 | ||
38 | CDmaPusher::~CDmaPusher() = default; | 38 | CDmaPusher::~CDmaPusher() = default; |
39 | 39 | ||
40 | void CDmaPusher::Push(ChCommandHeaderList&& entries) { | 40 | void CDmaPusher::ProcessEntries(ChCommandHeaderList&& entries) { |
41 | cdma_queue.push(std::move(entries)); | 41 | for (const auto& value : entries) { |
42 | } | ||
43 | |||
44 | void CDmaPusher::DispatchCalls() { | ||
45 | while (!cdma_queue.empty()) { | ||
46 | Step(); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | void CDmaPusher::Step() { | ||
51 | const auto entries{cdma_queue.front()}; | ||
52 | cdma_queue.pop(); | ||
53 | |||
54 | std::vector<u32> values(entries.size()); | ||
55 | std::memcpy(values.data(), entries.data(), entries.size() * sizeof(u32)); | ||
56 | |||
57 | for (const u32 value : values) { | ||
58 | if (mask != 0) { | 42 | if (mask != 0) { |
59 | const u32 lbs = Common::CountTrailingZeroes32(mask); | 43 | const u32 lbs = Common::CountTrailingZeroes32(mask); |
60 | mask &= ~(1U << lbs); | 44 | mask &= ~(1U << lbs); |
61 | ExecuteCommand(static_cast<u32>(offset + lbs), value); | 45 | ExecuteCommand(offset + lbs, value.raw); |
62 | continue; | 46 | continue; |
63 | } else if (count != 0) { | 47 | } else if (count != 0) { |
64 | --count; | 48 | --count; |
65 | ExecuteCommand(static_cast<u32>(offset), value); | 49 | ExecuteCommand(offset, value.raw); |
66 | if (incrementing) { | 50 | if (incrementing) { |
67 | ++offset; | 51 | ++offset; |
68 | } | 52 | } |
69 | continue; | 53 | continue; |
70 | } | 54 | } |
71 | const auto mode = static_cast<ChSubmissionMode>((value >> 28) & 0xf); | 55 | const auto mode = value.submission_mode.Value(); |
72 | switch (mode) { | 56 | switch (mode) { |
73 | case ChSubmissionMode::SetClass: { | 57 | case ChSubmissionMode::SetClass: { |
74 | mask = value & 0x3f; | 58 | mask = value.value & 0x3f; |
75 | offset = (value >> 16) & 0xfff; | 59 | offset = value.method_offset; |
76 | current_class = static_cast<ChClassId>((value >> 6) & 0x3ff); | 60 | current_class = static_cast<ChClassId>((value.value >> 6) & 0x3ff); |
77 | break; | 61 | break; |
78 | } | 62 | } |
79 | case ChSubmissionMode::Incrementing: | 63 | case ChSubmissionMode::Incrementing: |
80 | case ChSubmissionMode::NonIncrementing: | 64 | case ChSubmissionMode::NonIncrementing: |
81 | count = value & 0xffff; | 65 | count = value.value; |
82 | offset = (value >> 16) & 0xfff; | 66 | offset = value.method_offset; |
83 | incrementing = mode == ChSubmissionMode::Incrementing; | 67 | incrementing = mode == ChSubmissionMode::Incrementing; |
84 | break; | 68 | break; |
85 | case ChSubmissionMode::Mask: | 69 | case ChSubmissionMode::Mask: |
86 | mask = value & 0xffff; | 70 | mask = value.value; |
87 | offset = (value >> 16) & 0xfff; | 71 | offset = value.method_offset; |
88 | break; | 72 | break; |
89 | case ChSubmissionMode::Immediate: { | 73 | case ChSubmissionMode::Immediate: { |
90 | const u32 data = value & 0xfff; | 74 | const u32 data = value.value & 0xfff; |
91 | offset = (value >> 16) & 0xfff; | 75 | offset = value.method_offset; |
92 | ExecuteCommand(static_cast<u32>(offset), data); | 76 | ExecuteCommand(offset, data); |
93 | break; | 77 | break; |
94 | } | 78 | } |
95 | default: | 79 | default: |
@@ -102,8 +86,8 @@ void CDmaPusher::Step() { | |||
102 | void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { | 86 | void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { |
103 | switch (current_class) { | 87 | switch (current_class) { |
104 | case ChClassId::NvDec: | 88 | case ChClassId::NvDec: |
105 | ThiStateWrite(nvdec_thi_state, state_offset, {data}); | 89 | ThiStateWrite(nvdec_thi_state, offset, data); |
106 | switch (static_cast<ThiMethod>(state_offset)) { | 90 | switch (static_cast<ThiMethod>(offset)) { |
107 | case ThiMethod::IncSyncpt: { | 91 | case ThiMethod::IncSyncpt: { |
108 | LOG_DEBUG(Service_NVDRV, "NVDEC Class IncSyncpt Method"); | 92 | LOG_DEBUG(Service_NVDRV, "NVDEC Class IncSyncpt Method"); |
109 | const auto syncpoint_id = static_cast<u32>(data & 0xFF); | 93 | const auto syncpoint_id = static_cast<u32>(data & 0xFF); |
@@ -120,7 +104,7 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { | |||
120 | LOG_DEBUG(Service_NVDRV, "NVDEC method 0x{:X}", | 104 | LOG_DEBUG(Service_NVDRV, "NVDEC method 0x{:X}", |
121 | static_cast<u32>(nvdec_thi_state.method_0)); | 105 | static_cast<u32>(nvdec_thi_state.method_0)); |
122 | nvdec_processor->ProcessMethod(static_cast<Nvdec::Method>(nvdec_thi_state.method_0), | 106 | nvdec_processor->ProcessMethod(static_cast<Nvdec::Method>(nvdec_thi_state.method_0), |
123 | {data}); | 107 | data); |
124 | break; | 108 | break; |
125 | default: | 109 | default: |
126 | break; | 110 | break; |
@@ -144,7 +128,7 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { | |||
144 | case ThiMethod::SetMethod1: | 128 | case ThiMethod::SetMethod1: |
145 | LOG_DEBUG(Service_NVDRV, "VIC method 0x{:X}, Args=({})", | 129 | LOG_DEBUG(Service_NVDRV, "VIC method 0x{:X}, Args=({})", |
146 | static_cast<u32>(vic_thi_state.method_0), data); | 130 | static_cast<u32>(vic_thi_state.method_0), data); |
147 | vic_processor->ProcessMethod(static_cast<Vic::Method>(vic_thi_state.method_0), {data}); | 131 | vic_processor->ProcessMethod(static_cast<Vic::Method>(vic_thi_state.method_0), data); |
148 | break; | 132 | break; |
149 | default: | 133 | default: |
150 | break; | 134 | break; |
@@ -153,7 +137,7 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { | |||
153 | case ChClassId::Host1x: | 137 | case ChClassId::Host1x: |
154 | // This device is mainly for syncpoint synchronization | 138 | // This device is mainly for syncpoint synchronization |
155 | LOG_DEBUG(Service_NVDRV, "Host1X Class Method"); | 139 | LOG_DEBUG(Service_NVDRV, "Host1X Class Method"); |
156 | host1x_processor->ProcessMethod(static_cast<Host1x::Method>(state_offset), {data}); | 140 | host1x_processor->ProcessMethod(static_cast<Host1x::Method>(offset), data); |
157 | break; | 141 | break; |
158 | default: | 142 | default: |
159 | UNIMPLEMENTED_MSG("Current class not implemented {:X}", static_cast<u32>(current_class)); | 143 | UNIMPLEMENTED_MSG("Current class not implemented {:X}", static_cast<u32>(current_class)); |
@@ -161,10 +145,9 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { | |||
161 | } | 145 | } |
162 | } | 146 | } |
163 | 147 | ||
164 | void CDmaPusher::ThiStateWrite(ThiRegisters& state, u32 state_offset, | 148 | void CDmaPusher::ThiStateWrite(ThiRegisters& state, u32 state_offset, u32 argument) { |
165 | const std::vector<u32>& arguments) { | 149 | u8* const offset_ptr = reinterpret_cast<u8*>(&state) + sizeof(u32) * state_offset; |
166 | u8* const state_offset_ptr = reinterpret_cast<u8*>(&state) + sizeof(u32) * state_offset; | 150 | std::memcpy(offset_ptr, &argument, sizeof(u32)); |
167 | std::memcpy(state_offset_ptr, arguments.data(), sizeof(u32) * arguments.size()); | ||
168 | } | 151 | } |
169 | 152 | ||
170 | } // namespace Tegra | 153 | } // 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 @@ | |||
5 | #pragma once | 5 | #pragma once |
6 | 6 | ||
7 | #include <memory> | 7 | #include <memory> |
8 | #include <unordered_map> | ||
9 | #include <vector> | 8 | #include <vector> |
10 | #include <queue> | ||
11 | 9 | ||
12 | #include "common/bit_field.h" | 10 | #include "common/bit_field.h" |
13 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
@@ -16,9 +14,9 @@ | |||
16 | namespace Tegra { | 14 | namespace Tegra { |
17 | 15 | ||
18 | class GPU; | 16 | class GPU; |
17 | class Host1x; | ||
19 | class Nvdec; | 18 | class Nvdec; |
20 | class Vic; | 19 | class Vic; |
21 | class Host1x; | ||
22 | 20 | ||
23 | enum class ChSubmissionMode : u32 { | 21 | enum class ChSubmissionMode : u32 { |
24 | SetClass = 0, | 22 | SetClass = 0, |
@@ -48,16 +46,10 @@ enum class ChClassId : u32 { | |||
48 | NvDec = 0xf0 | 46 | NvDec = 0xf0 |
49 | }; | 47 | }; |
50 | 48 | ||
51 | enum class ChMethod : u32 { | ||
52 | Empty = 0, | ||
53 | SetMethod = 0x10, | ||
54 | SetData = 0x11, | ||
55 | }; | ||
56 | |||
57 | union ChCommandHeader { | 49 | union ChCommandHeader { |
58 | u32 raw; | 50 | u32 raw; |
59 | BitField<0, 16, u32> value; | 51 | BitField<0, 16, u32> value; |
60 | BitField<16, 12, ChMethod> method_offset; | 52 | BitField<16, 12, u32> method_offset; |
61 | BitField<28, 4, ChSubmissionMode> submission_mode; | 53 | BitField<28, 4, ChSubmissionMode> submission_mode; |
62 | }; | 54 | }; |
63 | static_assert(sizeof(ChCommandHeader) == sizeof(u32), "ChCommand header is an invalid size"); | 55 | static_assert(sizeof(ChCommandHeader) == sizeof(u32), "ChCommand header is an invalid size"); |
@@ -99,21 +91,15 @@ public: | |||
99 | explicit CDmaPusher(GPU& gpu_); | 91 | explicit CDmaPusher(GPU& gpu_); |
100 | ~CDmaPusher(); | 92 | ~CDmaPusher(); |
101 | 93 | ||
102 | /// Push NVDEC command buffer entries into queue | 94 | /// Process the command entry |
103 | void Push(ChCommandHeaderList&& entries); | 95 | void ProcessEntries(ChCommandHeaderList&& entries); |
104 | |||
105 | /// Process queued command buffer entries | ||
106 | void DispatchCalls(); | ||
107 | |||
108 | /// Process one queue element | ||
109 | void Step(); | ||
110 | 96 | ||
97 | private: | ||
111 | /// Invoke command class devices to execute the command based on the current state | 98 | /// Invoke command class devices to execute the command based on the current state |
112 | void ExecuteCommand(u32 state_offset, u32 data); | 99 | void ExecuteCommand(u32 state_offset, u32 data); |
113 | 100 | ||
114 | private: | ||
115 | /// Write arguments value to the ThiRegisters member at the specified offset | 101 | /// Write arguments value to the ThiRegisters member at the specified offset |
116 | void ThiStateWrite(ThiRegisters& state, u32 state_offset, const std::vector<u32>& arguments); | 102 | void ThiStateWrite(ThiRegisters& state, u32 offset, u32 argument); |
117 | 103 | ||
118 | GPU& gpu; | 104 | GPU& gpu; |
119 | std::shared_ptr<Tegra::Nvdec> nvdec_processor; | 105 | std::shared_ptr<Tegra::Nvdec> nvdec_processor; |
@@ -124,13 +110,10 @@ private: | |||
124 | ThiRegisters vic_thi_state{}; | 110 | ThiRegisters vic_thi_state{}; |
125 | ThiRegisters nvdec_thi_state{}; | 111 | ThiRegisters nvdec_thi_state{}; |
126 | 112 | ||
127 | s32 count{}; | 113 | u32 count{}; |
128 | s32 offset{}; | 114 | u32 offset{}; |
129 | s32 mask{}; | 115 | u32 mask{}; |
130 | bool incrementing{}; | 116 | bool incrementing{}; |
131 | |||
132 | // Queue of command lists to be processed | ||
133 | std::queue<ChCommandHeaderList> cdma_queue; | ||
134 | }; | 117 | }; |
135 | 118 | ||
136 | } // namespace Tegra | 119 | } // 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() { | |||
44 | } | 44 | } |
45 | 45 | ||
46 | void Codec::SetTargetCodec(NvdecCommon::VideoCodec codec) { | 46 | void Codec::SetTargetCodec(NvdecCommon::VideoCodec codec) { |
47 | LOG_INFO(Service_NVDRV, "NVDEC video codec initialized to {}", codec); | 47 | if (current_codec != codec) { |
48 | current_codec = codec; | 48 | LOG_INFO(Service_NVDRV, "NVDEC video codec initialized to {}", static_cast<u32>(codec)); |
49 | current_codec = codec; | ||
50 | } | ||
49 | } | 51 | } |
50 | 52 | ||
51 | void Codec::StateWrite(u32 offset, u64 arguments) { | 53 | void Codec::StateWrite(u32 offset, u64 arguments) { |
@@ -55,7 +57,6 @@ void Codec::StateWrite(u32 offset, u64 arguments) { | |||
55 | 57 | ||
56 | void Codec::Decode() { | 58 | void Codec::Decode() { |
57 | bool is_first_frame = false; | 59 | bool is_first_frame = false; |
58 | |||
59 | if (!initialized) { | 60 | if (!initialized) { |
60 | if (current_codec == NvdecCommon::VideoCodec::H264) { | 61 | if (current_codec == NvdecCommon::VideoCodec::H264) { |
61 | av_codec = avcodec_find_decoder(AV_CODEC_ID_H264); | 62 | 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<Codec>(gpu)) {} | |||
12 | 12 | ||
13 | Nvdec::~Nvdec() = default; | 13 | Nvdec::~Nvdec() = default; |
14 | 14 | ||
15 | void Nvdec::ProcessMethod(Method method, const std::vector<u32>& arguments) { | 15 | void Nvdec::ProcessMethod(Method method, u32 argument) { |
16 | if (method == Method::SetVideoCodec) { | 16 | if (method == Method::SetVideoCodec) { |
17 | codec->StateWrite(static_cast<u32>(method), arguments[0]); | 17 | codec->StateWrite(static_cast<u32>(method), argument); |
18 | } else { | 18 | } else { |
19 | codec->StateWrite(static_cast<u32>(method), static_cast<u64>(arguments[0]) << 8); | 19 | codec->StateWrite(static_cast<u32>(method), static_cast<u64>(argument) << 8); |
20 | } | 20 | } |
21 | 21 | ||
22 | switch (method) { | 22 | switch (method) { |
23 | case Method::SetVideoCodec: | 23 | case Method::SetVideoCodec: |
24 | codec->SetTargetCodec(static_cast<NvdecCommon::VideoCodec>(arguments[0])); | 24 | codec->SetTargetCodec(static_cast<NvdecCommon::VideoCodec>(argument)); |
25 | break; | 25 | break; |
26 | case Method::Execute: | 26 | case Method::Execute: |
27 | Execute(); | 27 | 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: | |||
23 | ~Nvdec(); | 23 | ~Nvdec(); |
24 | 24 | ||
25 | /// Writes the method into the state, Invoke Execute() if encountered | 25 | /// Writes the method into the state, Invoke Execute() if encountered |
26 | void ProcessMethod(Method method, const std::vector<u32>& arguments); | 26 | void ProcessMethod(Method method, u32 argument); |
27 | 27 | ||
28 | /// Return most recently decoded frame | 28 | /// Return most recently decoded frame |
29 | [[nodiscard]] AVFramePtr GetFrame(); | 29 | [[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" { | |||
18 | namespace Tegra { | 18 | namespace Tegra { |
19 | 19 | ||
20 | Vic::Vic(GPU& gpu_, std::shared_ptr<Nvdec> nvdec_processor_) | 20 | Vic::Vic(GPU& gpu_, std::shared_ptr<Nvdec> nvdec_processor_) |
21 | : gpu(gpu_), nvdec_processor(std::move(nvdec_processor_)) {} | 21 | : gpu(gpu_), |
22 | Vic::~Vic() = default; | 22 | nvdec_processor(std::move(nvdec_processor_)), converted_frame_buffer{nullptr, av_free} {} |
23 | 23 | ||
24 | void Vic::VicStateWrite(u32 offset, u32 arguments) { | 24 | Vic::~Vic() = default; |
25 | u8* const state_offset = reinterpret_cast<u8*>(&vic_state) + offset * sizeof(u32); | ||
26 | std::memcpy(state_offset, &arguments, sizeof(u32)); | ||
27 | } | ||
28 | 25 | ||
29 | void Vic::ProcessMethod(Method method, const std::vector<u32>& arguments) { | 26 | void Vic::ProcessMethod(Method method, u32 argument) { |
30 | LOG_DEBUG(HW_GPU, "Vic method 0x{:X}", method); | 27 | LOG_DEBUG(HW_GPU, "Vic method 0x{:X}", static_cast<u32>(method)); |
31 | VicStateWrite(static_cast<u32>(method), arguments[0]); | 28 | const u64 arg = static_cast<u64>(argument) << 8; |
32 | const u64 arg = static_cast<u64>(arguments[0]) << 8; | ||
33 | switch (method) { | 29 | switch (method) { |
34 | case Method::Execute: | 30 | case Method::Execute: |
35 | Execute(); | 31 | Execute(); |
@@ -53,8 +49,7 @@ void Vic::ProcessMethod(Method method, const std::vector<u32>& arguments) { | |||
53 | 49 | ||
54 | void Vic::Execute() { | 50 | void Vic::Execute() { |
55 | if (output_surface_luma_address == 0) { | 51 | if (output_surface_luma_address == 0) { |
56 | LOG_ERROR(Service_NVDRV, "VIC Luma address not set. Received 0x{:X}", | 52 | LOG_ERROR(Service_NVDRV, "VIC Luma address not set."); |
57 | vic_state.output_surface.luma_offset); | ||
58 | return; | 53 | return; |
59 | } | 54 | } |
60 | const VicConfig config{gpu.MemoryManager().Read<u64>(config_struct_address + 0x20)}; | 55 | const VicConfig config{gpu.MemoryManager().Read<u64>(config_struct_address + 0x20)}; |
@@ -89,8 +84,10 @@ void Vic::Execute() { | |||
89 | // Get Converted frame | 84 | // Get Converted frame |
90 | const std::size_t linear_size = frame->width * frame->height * 4; | 85 | const std::size_t linear_size = frame->width * frame->height * 4; |
91 | 86 | ||
92 | using AVMallocPtr = std::unique_ptr<u8, decltype(&av_free)>; | 87 | // Only allocate frame_buffer once per stream, as the size is not expected to change |
93 | AVMallocPtr converted_frame_buffer{static_cast<u8*>(av_malloc(linear_size)), av_free}; | 88 | if (!converted_frame_buffer) { |
89 | converted_frame_buffer = AVMallocPtr{static_cast<u8*>(av_malloc(linear_size)), av_free}; | ||
90 | } | ||
94 | 91 | ||
95 | const int converted_stride{frame->width * 4}; | 92 | const int converted_stride{frame->width * 4}; |
96 | u8* const converted_frame_buf_addr{converted_frame_buffer.get()}; | 93 | u8* const converted_frame_buf_addr{converted_frame_buffer.get()}; |
@@ -104,12 +101,12 @@ void Vic::Execute() { | |||
104 | const u32 block_height = static_cast<u32>(config.block_linear_height_log2); | 101 | const u32 block_height = static_cast<u32>(config.block_linear_height_log2); |
105 | const auto size = Tegra::Texture::CalculateSize(true, 4, frame->width, frame->height, 1, | 102 | const auto size = Tegra::Texture::CalculateSize(true, 4, frame->width, frame->height, 1, |
106 | block_height, 0); | 103 | block_height, 0); |
107 | std::vector<u8> swizzled_data(size); | 104 | luma_buffer.resize(size); |
108 | Tegra::Texture::SwizzleSubrect(frame->width, frame->height, frame->width * 4, | 105 | Tegra::Texture::SwizzleSubrect(frame->width, frame->height, frame->width * 4, |
109 | frame->width, 4, swizzled_data.data(), | 106 | frame->width, 4, luma_buffer.data(), |
110 | converted_frame_buffer.get(), block_height, 0, 0); | 107 | converted_frame_buffer.get(), block_height, 0, 0); |
111 | 108 | ||
112 | gpu.MemoryManager().WriteBlock(output_surface_luma_address, swizzled_data.data(), size); | 109 | gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), size); |
113 | gpu.Maxwell3D().OnMemoryWrite(); | 110 | gpu.Maxwell3D().OnMemoryWrite(); |
114 | } else { | 111 | } else { |
115 | // send pitch linear frame | 112 | // send pitch linear frame |
@@ -134,15 +131,15 @@ void Vic::Execute() { | |||
134 | const auto stride = frame->linesize[0]; | 131 | const auto stride = frame->linesize[0]; |
135 | const auto half_stride = frame->linesize[1]; | 132 | const auto half_stride = frame->linesize[1]; |
136 | 133 | ||
137 | std::vector<u8> luma_buffer(aligned_width * surface_height); | 134 | luma_buffer.resize(aligned_width * surface_height); |
138 | std::vector<u8> chroma_buffer(aligned_width * half_height); | 135 | chroma_buffer.resize(aligned_width * half_height); |
139 | 136 | ||
140 | // Populate luma buffer | 137 | // Populate luma buffer |
141 | for (std::size_t y = 0; y < surface_height - 1; ++y) { | 138 | for (std::size_t y = 0; y < surface_height - 1; ++y) { |
142 | std::size_t src = y * stride; | 139 | const std::size_t src = y * stride; |
143 | std::size_t dst = y * aligned_width; | 140 | const std::size_t dst = y * aligned_width; |
144 | 141 | ||
145 | std::size_t size = surface_width; | 142 | const std::size_t size = surface_width; |
146 | 143 | ||
147 | for (std::size_t offset = 0; offset < size; ++offset) { | 144 | for (std::size_t offset = 0; offset < size; ++offset) { |
148 | luma_buffer[dst + offset] = luma_ptr[src + offset]; | 145 | luma_buffer[dst + offset] = luma_ptr[src + offset]; |
@@ -153,8 +150,8 @@ void Vic::Execute() { | |||
153 | 150 | ||
154 | // Populate chroma buffer from both channels with interleaving. | 151 | // Populate chroma buffer from both channels with interleaving. |
155 | for (std::size_t y = 0; y < half_height; ++y) { | 152 | for (std::size_t y = 0; y < half_height; ++y) { |
156 | std::size_t src = y * half_stride; | 153 | const std::size_t src = y * half_stride; |
157 | std::size_t dst = y * aligned_width; | 154 | const std::size_t dst = y * aligned_width; |
158 | 155 | ||
159 | for (std::size_t x = 0; x < half_width; ++x) { | 156 | for (std::size_t x = 0; x < half_width; ++x) { |
160 | chroma_buffer[dst + x * 2] = chroma_b_ptr[src + x]; | 157 | 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 { | |||
15 | class GPU; | 15 | class GPU; |
16 | class Nvdec; | 16 | class Nvdec; |
17 | 17 | ||
18 | struct PlaneOffsets { | ||
19 | u32 luma_offset{}; | ||
20 | u32 chroma_u_offset{}; | ||
21 | u32 chroma_v_offset{}; | ||
22 | }; | ||
23 | |||
24 | struct VicRegisters { | ||
25 | INSERT_PADDING_WORDS(64); | ||
26 | u32 nop{}; | ||
27 | INSERT_PADDING_WORDS(15); | ||
28 | u32 pm_trigger{}; | ||
29 | INSERT_PADDING_WORDS(47); | ||
30 | u32 set_application_id{}; | ||
31 | u32 set_watchdog_timer{}; | ||
32 | INSERT_PADDING_WORDS(17); | ||
33 | u32 context_save_area{}; | ||
34 | u32 context_switch{}; | ||
35 | INSERT_PADDING_WORDS(43); | ||
36 | u32 execute{}; | ||
37 | INSERT_PADDING_WORDS(63); | ||
38 | std::array<std::array<PlaneOffsets, 8>, 8> surfacex_slots{}; | ||
39 | u32 picture_index{}; | ||
40 | u32 control_params{}; | ||
41 | u32 config_struct_offset{}; | ||
42 | u32 filter_struct_offset{}; | ||
43 | u32 palette_offset{}; | ||
44 | u32 hist_offset{}; | ||
45 | u32 context_id{}; | ||
46 | u32 fce_ucode_size{}; | ||
47 | PlaneOffsets output_surface{}; | ||
48 | u32 fce_ucode_offset{}; | ||
49 | INSERT_PADDING_WORDS(4); | ||
50 | std::array<u32, 8> slot_context_id{}; | ||
51 | INSERT_PADDING_WORDS(16); | ||
52 | }; | ||
53 | static_assert(sizeof(VicRegisters) == 0x7A0, "VicRegisters is an invalid size"); | ||
54 | |||
55 | class Vic { | 18 | class Vic { |
56 | public: | 19 | public: |
57 | enum class Method : u32 { | 20 | enum class Method : u32 { |
@@ -67,14 +30,11 @@ public: | |||
67 | ~Vic(); | 30 | ~Vic(); |
68 | 31 | ||
69 | /// Write to the device state. | 32 | /// Write to the device state. |
70 | void ProcessMethod(Method method, const std::vector<u32>& arguments); | 33 | void ProcessMethod(Method method, u32 argument); |
71 | 34 | ||
72 | private: | 35 | private: |
73 | void Execute(); | 36 | void Execute(); |
74 | 37 | ||
75 | void VicStateWrite(u32 offset, u32 arguments); | ||
76 | VicRegisters vic_state{}; | ||
77 | |||
78 | enum class VideoPixelFormat : u64_le { | 38 | enum class VideoPixelFormat : u64_le { |
79 | RGBA8 = 0x1f, | 39 | RGBA8 = 0x1f, |
80 | BGRA8 = 0x20, | 40 | BGRA8 = 0x20, |
@@ -88,8 +48,6 @@ private: | |||
88 | BitField<9, 2, u64_le> chroma_loc_vert; | 48 | BitField<9, 2, u64_le> chroma_loc_vert; |
89 | BitField<11, 4, u64_le> block_linear_kind; | 49 | BitField<11, 4, u64_le> block_linear_kind; |
90 | BitField<15, 4, u64_le> block_linear_height_log2; | 50 | BitField<15, 4, u64_le> block_linear_height_log2; |
91 | BitField<19, 3, u64_le> reserved0; | ||
92 | BitField<22, 10, u64_le> reserved1; | ||
93 | BitField<32, 14, u64_le> surface_width_minus1; | 51 | BitField<32, 14, u64_le> surface_width_minus1; |
94 | BitField<46, 14, u64_le> surface_height_minus1; | 52 | BitField<46, 14, u64_le> surface_height_minus1; |
95 | }; | 53 | }; |
@@ -97,6 +55,13 @@ private: | |||
97 | GPU& gpu; | 55 | GPU& gpu; |
98 | std::shared_ptr<Tegra::Nvdec> nvdec_processor; | 56 | std::shared_ptr<Tegra::Nvdec> nvdec_processor; |
99 | 57 | ||
58 | /// Avoid reallocation of the following buffers every frame, as their | ||
59 | /// size does not change during a stream | ||
60 | using AVMallocPtr = std::unique_ptr<u8, decltype(&av_free)>; | ||
61 | AVMallocPtr converted_frame_buffer; | ||
62 | std::vector<u8> luma_buffer; | ||
63 | std::vector<u8> chroma_buffer; | ||
64 | |||
100 | GPUVAddr config_struct_address{}; | 65 | GPUVAddr config_struct_address{}; |
101 | GPUVAddr output_surface_luma_address{}; | 66 | GPUVAddr output_surface_luma_address{}; |
102 | GPUVAddr output_surface_chroma_u_address{}; | 67 | 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)); | |||
30 | 30 | ||
31 | GPU::GPU(Core::System& system_, bool is_async_, bool use_nvdec_) | 31 | GPU::GPU(Core::System& system_, bool is_async_, bool use_nvdec_) |
32 | : system{system_}, memory_manager{std::make_unique<Tegra::MemoryManager>(system)}, | 32 | : system{system_}, memory_manager{std::make_unique<Tegra::MemoryManager>(system)}, |
33 | dma_pusher{std::make_unique<Tegra::DmaPusher>(system, *this)}, | 33 | dma_pusher{std::make_unique<Tegra::DmaPusher>(system, *this)}, use_nvdec{use_nvdec_}, |
34 | cdma_pusher{std::make_unique<Tegra::CDmaPusher>(*this)}, use_nvdec{use_nvdec_}, | ||
35 | maxwell_3d{std::make_unique<Engines::Maxwell3D>(system, *memory_manager)}, | 34 | maxwell_3d{std::make_unique<Engines::Maxwell3D>(system, *memory_manager)}, |
36 | fermi_2d{std::make_unique<Engines::Fermi2D>()}, | 35 | fermi_2d{std::make_unique<Engines::Fermi2D>()}, |
37 | kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)}, | 36 | kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)}, |
@@ -494,8 +493,7 @@ void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) { | |||
494 | // TODO(ameerj): RE proper async nvdec operation | 493 | // TODO(ameerj): RE proper async nvdec operation |
495 | // gpu_thread.SubmitCommandBuffer(std::move(entries)); | 494 | // gpu_thread.SubmitCommandBuffer(std::move(entries)); |
496 | 495 | ||
497 | cdma_pusher->Push(std::move(entries)); | 496 | cdma_pusher->ProcessEntries(std::move(entries)); |
498 | cdma_pusher->DispatchCalls(); | ||
499 | } | 497 | } |
500 | 498 | ||
501 | void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | 499 | 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, | |||
47 | dma_pusher.DispatchCalls(); | 47 | dma_pusher.DispatchCalls(); |
48 | } else if (auto* command_list = std::get_if<SubmitChCommandEntries>(&next.data)) { | 48 | } else if (auto* command_list = std::get_if<SubmitChCommandEntries>(&next.data)) { |
49 | // NVDEC | 49 | // NVDEC |
50 | cdma_pusher.Push(std::move(command_list->entries)); | 50 | cdma_pusher.ProcessEntries(std::move(command_list->entries)); |
51 | cdma_pusher.DispatchCalls(); | ||
52 | } else if (const auto* data = std::get_if<SwapBuffersCommand>(&next.data)) { | 51 | } else if (const auto* data = std::get_if<SwapBuffersCommand>(&next.data)) { |
53 | renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr); | 52 | renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr); |
54 | } else if (std::holds_alternative<OnCommandListEndCommand>(next.data)) { | 53 | } else if (std::holds_alternative<OnCommandListEndCommand>(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) { | |||
475 | 475 | ||
476 | bool GRenderWindow::TouchUpdate(const QTouchEvent::TouchPoint& touch_point) { | 476 | bool GRenderWindow::TouchUpdate(const QTouchEvent::TouchPoint& touch_point) { |
477 | for (std::size_t id = 0; id < touch_ids.size(); ++id) { | 477 | for (std::size_t id = 0; id < touch_ids.size(); ++id) { |
478 | if (touch_ids[id] == touch_point.id() + 1) { | 478 | if (touch_ids[id] == static_cast<std::size_t>(touch_point.id() + 1)) { |
479 | const auto [x, y] = ScaleTouch(touch_point.pos()); | 479 | const auto [x, y] = ScaleTouch(touch_point.pos()); |
480 | this->TouchMoved(x, y, id + 1); | 480 | this->TouchMoved(x, y, id + 1); |
481 | return true; | 481 | return true; |
@@ -486,8 +486,9 @@ bool GRenderWindow::TouchUpdate(const QTouchEvent::TouchPoint& touch_point) { | |||
486 | 486 | ||
487 | bool GRenderWindow::TouchExist(std::size_t id, | 487 | bool GRenderWindow::TouchExist(std::size_t id, |
488 | const QList<QTouchEvent::TouchPoint>& touch_points) const { | 488 | const QList<QTouchEvent::TouchPoint>& touch_points) const { |
489 | return std::any_of(touch_points.begin(), touch_points.end(), | 489 | return std::any_of(touch_points.begin(), touch_points.end(), [id](const auto& point) { |
490 | [id](const auto& point) { return id == point.id() + 1; }); | 490 | return id == static_cast<std::size_t>(point.id() + 1); |
491 | }); | ||
491 | } | 492 | } |
492 | 493 | ||
493 | bool GRenderWindow::event(QEvent* event) { | 494 | 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() { | |||
508 | Settings::values.emulate_analog_keyboard = | 508 | Settings::values.emulate_analog_keyboard = |
509 | ReadSetting(QStringLiteral("emulate_analog_keyboard"), false).toBool(); | 509 | ReadSetting(QStringLiteral("emulate_analog_keyboard"), false).toBool(); |
510 | 510 | ||
511 | ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), false); | 511 | ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), true); |
512 | ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled"), | 512 | ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled"), |
513 | true); | 513 | true); |
514 | ReadSettingGlobal(Settings::values.enable_accurate_vibrations, | 514 | ReadSettingGlobal(Settings::values.enable_accurate_vibrations, |
@@ -1168,7 +1168,7 @@ void Config::SaveControlValues() { | |||
1168 | SaveTouchscreenValues(); | 1168 | SaveTouchscreenValues(); |
1169 | SaveMotionTouchValues(); | 1169 | SaveMotionTouchValues(); |
1170 | 1170 | ||
1171 | WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false); | 1171 | WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, true); |
1172 | WriteSettingGlobal(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled, | 1172 | WriteSettingGlobal(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled, |
1173 | true); | 1173 | true); |
1174 | WriteSettingGlobal(QStringLiteral("enable_accurate_vibrations"), | 1174 | 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, | |||
51 | case CalibrationConfigurationJob::Status::Completed: | 51 | case CalibrationConfigurationJob::Status::Completed: |
52 | text = tr("Configuration completed!"); | 52 | text = tr("Configuration completed!"); |
53 | break; | 53 | break; |
54 | default: | ||
55 | break; | ||
54 | } | 56 | } |
55 | QMetaObject::invokeMethod(this, "UpdateLabelText", Q_ARG(QString, text)); | 57 | QMetaObject::invokeMethod(this, "UpdateLabelText", Q_ARG(QString, text)); |
56 | if (status == CalibrationConfigurationJob::Status::Completed) { | 58 | if (status == CalibrationConfigurationJob::Status::Completed) { |
@@ -163,8 +165,9 @@ void ConfigureMotionTouch::ConnectEvents() { | |||
163 | } | 165 | } |
164 | 166 | ||
165 | void ConfigureMotionTouch::OnUDPAddServer() { | 167 | void ConfigureMotionTouch::OnUDPAddServer() { |
166 | 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]" | 168 | // Validator for IP address |
167 | "[0-9]|[01]?[0-9][0-9]?)$)re")); // a valid ip address | 169 | QRegExp re(QStringLiteral( |
170 | 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")); | ||
168 | bool ok; | 171 | bool ok; |
169 | QString port_text = ui->udp_port->text(); | 172 | QString port_text = ui->udp_port->text(); |
170 | QString server_text = ui->udp_server->text(); | 173 | 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 { | |||
251 | } | 251 | } |
252 | break; | 252 | break; |
253 | case Kernel::ThreadState::Waiting: | 253 | case Kernel::ThreadState::Waiting: |
254 | status = tr("waiting"); | 254 | switch (thread.GetWaitReasonForDebugging()) { |
255 | case Kernel::ThreadWaitReasonForDebugging::Sleep: | ||
256 | status = tr("sleeping"); | ||
257 | break; | ||
258 | case Kernel::ThreadWaitReasonForDebugging::IPC: | ||
259 | status = tr("waiting for IPC reply"); | ||
260 | break; | ||
261 | case Kernel::ThreadWaitReasonForDebugging::Synchronization: | ||
262 | status = tr("waiting for objects"); | ||
263 | break; | ||
264 | case Kernel::ThreadWaitReasonForDebugging::ConditionVar: | ||
265 | status = tr("waiting for condition variable"); | ||
266 | break; | ||
267 | case Kernel::ThreadWaitReasonForDebugging::Arbitration: | ||
268 | status = tr("waiting for address arbiter"); | ||
269 | break; | ||
270 | case Kernel::ThreadWaitReasonForDebugging::Suspended: | ||
271 | status = tr("waiting for suspend resume"); | ||
272 | break; | ||
273 | default: | ||
274 | status = tr("waiting"); | ||
275 | break; | ||
276 | } | ||
255 | break; | 277 | break; |
256 | case Kernel::ThreadState::Initialized: | 278 | case Kernel::ThreadState::Initialized: |
257 | status = tr("initialized"); | 279 | status = tr("initialized"); |
@@ -259,6 +281,9 @@ QString WaitTreeThread::GetText() const { | |||
259 | case Kernel::ThreadState::Terminated: | 281 | case Kernel::ThreadState::Terminated: |
260 | status = tr("terminated"); | 282 | status = tr("terminated"); |
261 | break; | 283 | break; |
284 | default: | ||
285 | status = tr("unknown"); | ||
286 | break; | ||
262 | } | 287 | } |
263 | 288 | ||
264 | const auto& context = thread.GetContext64(); | 289 | const auto& context = thread.GetContext64(); |
@@ -285,7 +310,20 @@ QColor WaitTreeThread::GetColor() const { | |||
285 | return QColor(WaitTreeColors[2][color_index]); | 310 | return QColor(WaitTreeColors[2][color_index]); |
286 | } | 311 | } |
287 | case Kernel::ThreadState::Waiting: | 312 | case Kernel::ThreadState::Waiting: |
288 | return QColor(WaitTreeColors[3][color_index]); | 313 | switch (thread.GetWaitReasonForDebugging()) { |
314 | case Kernel::ThreadWaitReasonForDebugging::IPC: | ||
315 | return QColor(WaitTreeColors[4][color_index]); | ||
316 | case Kernel::ThreadWaitReasonForDebugging::Sleep: | ||
317 | return QColor(WaitTreeColors[5][color_index]); | ||
318 | case Kernel::ThreadWaitReasonForDebugging::Synchronization: | ||
319 | case Kernel::ThreadWaitReasonForDebugging::ConditionVar: | ||
320 | case Kernel::ThreadWaitReasonForDebugging::Arbitration: | ||
321 | case Kernel::ThreadWaitReasonForDebugging::Suspended: | ||
322 | return QColor(WaitTreeColors[6][color_index]); | ||
323 | break; | ||
324 | default: | ||
325 | return QColor(WaitTreeColors[3][color_index]); | ||
326 | } | ||
289 | case Kernel::ThreadState::Initialized: | 327 | case Kernel::ThreadState::Initialized: |
290 | return QColor(WaitTreeColors[7][color_index]); | 328 | return QColor(WaitTreeColors[7][color_index]); |
291 | case Kernel::ThreadState::Terminated: | 329 | case Kernel::ThreadState::Terminated: |
@@ -336,7 +374,9 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { | |||
336 | list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex"))); | 374 | list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex"))); |
337 | } | 375 | } |
338 | 376 | ||
339 | if (thread.GetState() == Kernel::ThreadState::Waiting) { | 377 | if (thread.GetState() == Kernel::ThreadState::Waiting && |
378 | thread.GetWaitReasonForDebugging() == | ||
379 | Kernel::ThreadWaitReasonForDebugging::Synchronization) { | ||
340 | list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetWaitObjectsForDebugging(), | 380 | list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetWaitObjectsForDebugging(), |
341 | thread.IsCancellable())); | 381 | thread.IsCancellable())); |
342 | } | 382 | } |
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) { | |||
22 | case QWebEngineUrlRequestInfo::ResourceTypeXhr: | 22 | case QWebEngineUrlRequestInfo::ResourceTypeXhr: |
23 | emit FrameChanged(); | 23 | emit FrameChanged(); |
24 | break; | 24 | break; |
25 | default: | ||
26 | break; | ||
25 | } | 27 | } |
26 | } | 28 | } |
27 | 29 | ||
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() { | |||
340 | 340 | ||
341 | // System | 341 | // System |
342 | Settings::values.use_docked_mode.SetValue( | 342 | Settings::values.use_docked_mode.SetValue( |
343 | sdl2_config->GetBoolean("System", "use_docked_mode", false)); | 343 | sdl2_config->GetBoolean("System", "use_docked_mode", true)); |
344 | 344 | ||
345 | Settings::values.current_user = std::clamp<int>( | 345 | Settings::values.current_user = std::clamp<int>( |
346 | sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1); | 346 | 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 = | |||
274 | 274 | ||
275 | [System] | 275 | [System] |
276 | # Whether the system is docked | 276 | # Whether the system is docked |
277 | # 1: Yes, 0 (default): No | 277 | # 1 (default): Yes, 0: No |
278 | use_docked_mode = | 278 | use_docked_mode = |
279 | 279 | ||
280 | # Allow the use of NFC in games | 280 | # 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) { | |||
95 | int option_index = 0; | 95 | int option_index = 0; |
96 | 96 | ||
97 | InitializeLogging(); | 97 | InitializeLogging(); |
98 | |||
99 | char* endarg; | ||
100 | #ifdef _WIN32 | 98 | #ifdef _WIN32 |
101 | int argc_w; | 99 | int argc_w; |
102 | auto argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w); | 100 | 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() { | |||
84 | Settings::values.touchscreen.diameter_y = 15; | 84 | Settings::values.touchscreen.diameter_y = 15; |
85 | 85 | ||
86 | Settings::values.use_docked_mode.SetValue( | 86 | Settings::values.use_docked_mode.SetValue( |
87 | sdl2_config->GetBoolean("Controls", "use_docked_mode", false)); | 87 | sdl2_config->GetBoolean("Controls", "use_docked_mode", true)); |
88 | 88 | ||
89 | // Data Storage | 89 | // Data Storage |
90 | Settings::values.use_virtual_sd = | 90 | 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 = | |||
116 | 116 | ||
117 | [System] | 117 | [System] |
118 | # Whether the system is docked | 118 | # Whether the system is docked |
119 | # 1: Yes, 0 (default): No | 119 | # 1 (default): Yes, 0: No |
120 | use_docked_mode = | 120 | use_docked_mode = |
121 | 121 | ||
122 | # Allow the use of NFC in games | 122 | # Allow the use of NFC in games |