summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/address_space.inc4
-rw-r--r--src/common/input.h2
-rw-r--r--src/common/intrusive_list.h631
-rw-r--r--src/common/settings.cpp10
-rw-r--r--src/common/settings.h16
-rw-r--r--src/common/vector_math.h14
6 files changed, 668 insertions, 9 deletions
diff --git a/src/common/address_space.inc b/src/common/address_space.inc
index 2195dabd5..1ee82df53 100644
--- a/src/common/address_space.inc
+++ b/src/common/address_space.inc
@@ -72,7 +72,7 @@ MAP_MEMBER(void)::MapLocked(VaType virt, PaType phys, VaType size, ExtraBlockInf
72 } 72 }
73 }()}; 73 }()};
74 74
75 if (block_end_predecessor->virt >= virt) { 75 if (block_end_predecessor != blocks.begin() && block_end_predecessor->virt >= virt) {
76 // If this block's start would be overlapped by the map then reuse it as a tail 76 // If this block's start would be overlapped by the map then reuse it as a tail
77 // block 77 // block
78 block_end_predecessor->virt = virt_end; 78 block_end_predecessor->virt = virt_end;
@@ -336,7 +336,7 @@ ALLOC_MEMBER(VaType)::Allocate(VaType size) {
336 ASSERT_MSG(false, "Unexpected allocator state!"); 336 ASSERT_MSG(false, "Unexpected allocator state!");
337 } 337 }
338 338
339 auto search_predecessor{this->blocks.begin()}; 339 auto search_predecessor{std::next(this->blocks.begin())};
340 auto search_successor{std::next(search_predecessor)}; 340 auto search_successor{std::next(search_predecessor)};
341 341
342 while (search_successor != this->blocks.end() && 342 while (search_successor != this->blocks.end() &&
diff --git a/src/common/input.h b/src/common/input.h
index 51b277c1f..66fb15f0a 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -111,6 +111,8 @@ struct AnalogProperties {
111 float offset{}; 111 float offset{};
112 // Invert direction of the sensor data 112 // Invert direction of the sensor data
113 bool inverted{}; 113 bool inverted{};
114 // Invert the state if it's converted to a button
115 bool inverted_button{};
114 // Press once to activate, press again to release 116 // Press once to activate, press again to release
115 bool toggle{}; 117 bool toggle{};
116}; 118};
diff --git a/src/common/intrusive_list.h b/src/common/intrusive_list.h
new file mode 100644
index 000000000..d330dc1c2
--- /dev/null
+++ b/src/common/intrusive_list.h
@@ -0,0 +1,631 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/common_funcs.h"
7#include "common/parent_of_member.h"
8
9namespace Common {
10
11// Forward declare implementation class for Node.
12namespace impl {
13
14class IntrusiveListImpl;
15
16}
17
18class IntrusiveListNode {
19 YUZU_NON_COPYABLE(IntrusiveListNode);
20
21private:
22 friend class impl::IntrusiveListImpl;
23
24 IntrusiveListNode* m_prev;
25 IntrusiveListNode* m_next;
26
27public:
28 constexpr IntrusiveListNode() : m_prev(this), m_next(this) {}
29
30 constexpr bool IsLinked() const {
31 return m_next != this;
32 }
33
34private:
35 constexpr void LinkPrev(IntrusiveListNode* node) {
36 // We can't link an already linked node.
37 ASSERT(!node->IsLinked());
38 this->SplicePrev(node, node);
39 }
40
41 constexpr void SplicePrev(IntrusiveListNode* first, IntrusiveListNode* last) {
42 // Splice a range into the list.
43 auto last_prev = last->m_prev;
44 first->m_prev = m_prev;
45 last_prev->m_next = this;
46 m_prev->m_next = first;
47 m_prev = last_prev;
48 }
49
50 constexpr void LinkNext(IntrusiveListNode* node) {
51 // We can't link an already linked node.
52 ASSERT(!node->IsLinked());
53 return this->SpliceNext(node, node);
54 }
55
56 constexpr void SpliceNext(IntrusiveListNode* first, IntrusiveListNode* last) {
57 // Splice a range into the list.
58 auto last_prev = last->m_prev;
59 first->m_prev = this;
60 last_prev->m_next = m_next;
61 m_next->m_prev = last_prev;
62 m_next = first;
63 }
64
65 constexpr void Unlink() {
66 this->Unlink(m_next);
67 }
68
69 constexpr void Unlink(IntrusiveListNode* last) {
70 // Unlink a node from a next node.
71 auto last_prev = last->m_prev;
72 m_prev->m_next = last;
73 last->m_prev = m_prev;
74 last_prev->m_next = this;
75 m_prev = last_prev;
76 }
77
78 constexpr IntrusiveListNode* GetPrev() {
79 return m_prev;
80 }
81
82 constexpr const IntrusiveListNode* GetPrev() const {
83 return m_prev;
84 }
85
86 constexpr IntrusiveListNode* GetNext() {
87 return m_next;
88 }
89
90 constexpr const IntrusiveListNode* GetNext() const {
91 return m_next;
92 }
93};
94// DEPRECATED: static_assert(std::is_literal_type<IntrusiveListNode>::value);
95
96namespace impl {
97
98class IntrusiveListImpl {
99 YUZU_NON_COPYABLE(IntrusiveListImpl);
100
101private:
102 IntrusiveListNode m_root_node;
103
104public:
105 template <bool Const>
106 class Iterator;
107
108 using value_type = IntrusiveListNode;
109 using size_type = size_t;
110 using difference_type = ptrdiff_t;
111 using pointer = value_type*;
112 using const_pointer = const value_type*;
113 using reference = value_type&;
114 using const_reference = const value_type&;
115 using iterator = Iterator<false>;
116 using const_iterator = Iterator<true>;
117 using reverse_iterator = std::reverse_iterator<iterator>;
118 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
119
120 template <bool Const>
121 class Iterator {
122 public:
123 using iterator_category = std::bidirectional_iterator_tag;
124 using value_type = typename IntrusiveListImpl::value_type;
125 using difference_type = typename IntrusiveListImpl::difference_type;
126 using pointer =
127 std::conditional_t<Const, IntrusiveListImpl::const_pointer, IntrusiveListImpl::pointer>;
128 using reference = std::conditional_t<Const, IntrusiveListImpl::const_reference,
129 IntrusiveListImpl::reference>;
130
131 private:
132 pointer m_node;
133
134 public:
135 constexpr explicit Iterator(pointer n) : m_node(n) {}
136
137 constexpr bool operator==(const Iterator& rhs) const {
138 return m_node == rhs.m_node;
139 }
140
141 constexpr pointer operator->() const {
142 return m_node;
143 }
144
145 constexpr reference operator*() const {
146 return *m_node;
147 }
148
149 constexpr Iterator& operator++() {
150 m_node = m_node->m_next;
151 return *this;
152 }
153
154 constexpr Iterator& operator--() {
155 m_node = m_node->m_prev;
156 return *this;
157 }
158
159 constexpr Iterator operator++(int) {
160 const Iterator it{*this};
161 ++(*this);
162 return it;
163 }
164
165 constexpr Iterator operator--(int) {
166 const Iterator it{*this};
167 --(*this);
168 return it;
169 }
170
171 constexpr operator Iterator<true>() const {
172 return Iterator<true>(m_node);
173 }
174
175 constexpr Iterator<false> GetNonConstIterator() const {
176 return Iterator<false>(const_cast<IntrusiveListImpl::pointer>(m_node));
177 }
178 };
179
180public:
181 constexpr IntrusiveListImpl() : m_root_node() {}
182
183 // Iterator accessors.
184 constexpr iterator begin() {
185 return iterator(m_root_node.GetNext());
186 }
187
188 constexpr const_iterator begin() const {
189 return const_iterator(m_root_node.GetNext());
190 }
191
192 constexpr iterator end() {
193 return iterator(std::addressof(m_root_node));
194 }
195
196 constexpr const_iterator end() const {
197 return const_iterator(std::addressof(m_root_node));
198 }
199
200 constexpr iterator iterator_to(reference v) {
201 // Only allow iterator_to for values in lists.
202 ASSERT(v.IsLinked());
203 return iterator(std::addressof(v));
204 }
205
206 constexpr const_iterator iterator_to(const_reference v) const {
207 // Only allow iterator_to for values in lists.
208 ASSERT(v.IsLinked());
209 return const_iterator(std::addressof(v));
210 }
211
212 // Content management.
213 constexpr bool empty() const {
214 return !m_root_node.IsLinked();
215 }
216
217 constexpr size_type size() const {
218 return static_cast<size_type>(std::distance(this->begin(), this->end()));
219 }
220
221 constexpr reference back() {
222 return *m_root_node.GetPrev();
223 }
224
225 constexpr const_reference back() const {
226 return *m_root_node.GetPrev();
227 }
228
229 constexpr reference front() {
230 return *m_root_node.GetNext();
231 }
232
233 constexpr const_reference front() const {
234 return *m_root_node.GetNext();
235 }
236
237 constexpr void push_back(reference node) {
238 m_root_node.LinkPrev(std::addressof(node));
239 }
240
241 constexpr void push_front(reference node) {
242 m_root_node.LinkNext(std::addressof(node));
243 }
244
245 constexpr void pop_back() {
246 m_root_node.GetPrev()->Unlink();
247 }
248
249 constexpr void pop_front() {
250 m_root_node.GetNext()->Unlink();
251 }
252
253 constexpr iterator insert(const_iterator pos, reference node) {
254 pos.GetNonConstIterator()->LinkPrev(std::addressof(node));
255 return iterator(std::addressof(node));
256 }
257
258 constexpr void splice(const_iterator pos, IntrusiveListImpl& o) {
259 splice_impl(pos, o.begin(), o.end());
260 }
261
262 constexpr void splice(const_iterator pos, IntrusiveListImpl& o, const_iterator first) {
263 const_iterator last(first);
264 std::advance(last, 1);
265 splice_impl(pos, first, last);
266 }
267
268 constexpr void splice(const_iterator pos, IntrusiveListImpl& o, const_iterator first,
269 const_iterator last) {
270 splice_impl(pos, first, last);
271 }
272
273 constexpr iterator erase(const_iterator pos) {
274 if (pos == this->end()) {
275 return this->end();
276 }
277 iterator it(pos.GetNonConstIterator());
278 (it++)->Unlink();
279 return it;
280 }
281
282 constexpr void clear() {
283 while (!this->empty()) {
284 this->pop_front();
285 }
286 }
287
288private:
289 constexpr void splice_impl(const_iterator _pos, const_iterator _first, const_iterator _last) {
290 if (_first == _last) {
291 return;
292 }
293 iterator pos(_pos.GetNonConstIterator());
294 iterator first(_first.GetNonConstIterator());
295 iterator last(_last.GetNonConstIterator());
296 first->Unlink(std::addressof(*last));
297 pos->SplicePrev(std::addressof(*first), std::addressof(*first));
298 }
299};
300
301} // namespace impl
302
303template <class T, class Traits>
304class IntrusiveList {
305 YUZU_NON_COPYABLE(IntrusiveList);
306
307private:
308 impl::IntrusiveListImpl m_impl;
309
310public:
311 template <bool Const>
312 class Iterator;
313
314 using value_type = T;
315 using size_type = size_t;
316 using difference_type = ptrdiff_t;
317 using pointer = value_type*;
318 using const_pointer = const value_type*;
319 using reference = value_type&;
320 using const_reference = const value_type&;
321 using iterator = Iterator<false>;
322 using const_iterator = Iterator<true>;
323 using reverse_iterator = std::reverse_iterator<iterator>;
324 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
325
326 template <bool Const>
327 class Iterator {
328 public:
329 friend class Common::IntrusiveList<T, Traits>;
330
331 using ImplIterator =
332 std::conditional_t<Const, Common::impl::IntrusiveListImpl::const_iterator,
333 Common::impl::IntrusiveListImpl::iterator>;
334
335 using iterator_category = std::bidirectional_iterator_tag;
336 using value_type = typename IntrusiveList::value_type;
337 using difference_type = typename IntrusiveList::difference_type;
338 using pointer =
339 std::conditional_t<Const, IntrusiveList::const_pointer, IntrusiveList::pointer>;
340 using reference =
341 std::conditional_t<Const, IntrusiveList::const_reference, IntrusiveList::reference>;
342
343 private:
344 ImplIterator m_iterator;
345
346 private:
347 constexpr explicit Iterator(ImplIterator it) : m_iterator(it) {}
348
349 constexpr ImplIterator GetImplIterator() const {
350 return m_iterator;
351 }
352
353 public:
354 constexpr bool operator==(const Iterator& rhs) const {
355 return m_iterator == rhs.m_iterator;
356 }
357
358 constexpr pointer operator->() const {
359 return std::addressof(Traits::GetParent(*m_iterator));
360 }
361
362 constexpr reference operator*() const {
363 return Traits::GetParent(*m_iterator);
364 }
365
366 constexpr Iterator& operator++() {
367 ++m_iterator;
368 return *this;
369 }
370
371 constexpr Iterator& operator--() {
372 --m_iterator;
373 return *this;
374 }
375
376 constexpr Iterator operator++(int) {
377 const Iterator it{*this};
378 ++m_iterator;
379 return it;
380 }
381
382 constexpr Iterator operator--(int) {
383 const Iterator it{*this};
384 --m_iterator;
385 return it;
386 }
387
388 constexpr operator Iterator<true>() const {
389 return Iterator<true>(m_iterator);
390 }
391 };
392
393private:
394 static constexpr IntrusiveListNode& GetNode(reference ref) {
395 return Traits::GetNode(ref);
396 }
397
398 static constexpr IntrusiveListNode const& GetNode(const_reference ref) {
399 return Traits::GetNode(ref);
400 }
401
402 static constexpr reference GetParent(IntrusiveListNode& node) {
403 return Traits::GetParent(node);
404 }
405
406 static constexpr const_reference GetParent(IntrusiveListNode const& node) {
407 return Traits::GetParent(node);
408 }
409
410public:
411 constexpr IntrusiveList() : m_impl() {}
412
413 // Iterator accessors.
414 constexpr iterator begin() {
415 return iterator(m_impl.begin());
416 }
417
418 constexpr const_iterator begin() const {
419 return const_iterator(m_impl.begin());
420 }
421
422 constexpr iterator end() {
423 return iterator(m_impl.end());
424 }
425
426 constexpr const_iterator end() const {
427 return const_iterator(m_impl.end());
428 }
429
430 constexpr const_iterator cbegin() const {
431 return this->begin();
432 }
433
434 constexpr const_iterator cend() const {
435 return this->end();
436 }
437
438 constexpr reverse_iterator rbegin() {
439 return reverse_iterator(this->end());
440 }
441
442 constexpr const_reverse_iterator rbegin() const {
443 return const_reverse_iterator(this->end());
444 }
445
446 constexpr reverse_iterator rend() {
447 return reverse_iterator(this->begin());
448 }
449
450 constexpr const_reverse_iterator rend() const {
451 return const_reverse_iterator(this->begin());
452 }
453
454 constexpr const_reverse_iterator crbegin() const {
455 return this->rbegin();
456 }
457
458 constexpr const_reverse_iterator crend() const {
459 return this->rend();
460 }
461
462 constexpr iterator iterator_to(reference v) {
463 return iterator(m_impl.iterator_to(GetNode(v)));
464 }
465
466 constexpr const_iterator iterator_to(const_reference v) const {
467 return const_iterator(m_impl.iterator_to(GetNode(v)));
468 }
469
470 // Content management.
471 constexpr bool empty() const {
472 return m_impl.empty();
473 }
474
475 constexpr size_type size() const {
476 return m_impl.size();
477 }
478
479 constexpr reference back() {
480 return GetParent(m_impl.back());
481 }
482
483 constexpr const_reference back() const {
484 return GetParent(m_impl.back());
485 }
486
487 constexpr reference front() {
488 return GetParent(m_impl.front());
489 }
490
491 constexpr const_reference front() const {
492 return GetParent(m_impl.front());
493 }
494
495 constexpr void push_back(reference ref) {
496 m_impl.push_back(GetNode(ref));
497 }
498
499 constexpr void push_front(reference ref) {
500 m_impl.push_front(GetNode(ref));
501 }
502
503 constexpr void pop_back() {
504 m_impl.pop_back();
505 }
506
507 constexpr void pop_front() {
508 m_impl.pop_front();
509 }
510
511 constexpr iterator insert(const_iterator pos, reference ref) {
512 return iterator(m_impl.insert(pos.GetImplIterator(), GetNode(ref)));
513 }
514
515 constexpr void splice(const_iterator pos, IntrusiveList& o) {
516 m_impl.splice(pos.GetImplIterator(), o.m_impl);
517 }
518
519 constexpr void splice(const_iterator pos, IntrusiveList& o, const_iterator first) {
520 m_impl.splice(pos.GetImplIterator(), o.m_impl, first.GetImplIterator());
521 }
522
523 constexpr void splice(const_iterator pos, IntrusiveList& o, const_iterator first,
524 const_iterator last) {
525 m_impl.splice(pos.GetImplIterator(), o.m_impl, first.GetImplIterator(),
526 last.GetImplIterator());
527 }
528
529 constexpr iterator erase(const_iterator pos) {
530 return iterator(m_impl.erase(pos.GetImplIterator()));
531 }
532
533 constexpr void clear() {
534 m_impl.clear();
535 }
536};
537
538template <auto T, class Derived = Common::impl::GetParentType<T>>
539class IntrusiveListMemberTraits;
540
541template <class Parent, IntrusiveListNode Parent::*Member, class Derived>
542class IntrusiveListMemberTraits<Member, Derived> {
543public:
544 using ListType = IntrusiveList<Derived, IntrusiveListMemberTraits>;
545
546private:
547 friend class IntrusiveList<Derived, IntrusiveListMemberTraits>;
548
549 static constexpr IntrusiveListNode& GetNode(Derived& parent) {
550 return parent.*Member;
551 }
552
553 static constexpr IntrusiveListNode const& GetNode(Derived const& parent) {
554 return parent.*Member;
555 }
556
557 static Derived& GetParent(IntrusiveListNode& node) {
558 return Common::GetParentReference<Member, Derived>(std::addressof(node));
559 }
560
561 static Derived const& GetParent(IntrusiveListNode const& node) {
562 return Common::GetParentReference<Member, Derived>(std::addressof(node));
563 }
564};
565
566template <auto T, class Derived = Common::impl::GetParentType<T>>
567class IntrusiveListMemberTraitsByNonConstexprOffsetOf;
568
569template <class Parent, IntrusiveListNode Parent::*Member, class Derived>
570class IntrusiveListMemberTraitsByNonConstexprOffsetOf<Member, Derived> {
571public:
572 using ListType = IntrusiveList<Derived, IntrusiveListMemberTraitsByNonConstexprOffsetOf>;
573
574private:
575 friend class IntrusiveList<Derived, IntrusiveListMemberTraitsByNonConstexprOffsetOf>;
576
577 static constexpr IntrusiveListNode& GetNode(Derived& parent) {
578 return parent.*Member;
579 }
580
581 static constexpr IntrusiveListNode const& GetNode(Derived const& parent) {
582 return parent.*Member;
583 }
584
585 static Derived& GetParent(IntrusiveListNode& node) {
586 return *reinterpret_cast<Derived*>(reinterpret_cast<char*>(std::addressof(node)) -
587 GetOffset());
588 }
589
590 static Derived const& GetParent(IntrusiveListNode const& node) {
591 return *reinterpret_cast<const Derived*>(
592 reinterpret_cast<const char*>(std::addressof(node)) - GetOffset());
593 }
594
595 static uintptr_t GetOffset() {
596 return reinterpret_cast<uintptr_t>(std::addressof(reinterpret_cast<Derived*>(0)->*Member));
597 }
598};
599
600template <class Derived>
601class IntrusiveListBaseNode : public IntrusiveListNode {};
602
603template <class Derived>
604class IntrusiveListBaseTraits {
605public:
606 using ListType = IntrusiveList<Derived, IntrusiveListBaseTraits>;
607
608private:
609 friend class IntrusiveList<Derived, IntrusiveListBaseTraits>;
610
611 static constexpr IntrusiveListNode& GetNode(Derived& parent) {
612 return static_cast<IntrusiveListNode&>(
613 static_cast<IntrusiveListBaseNode<Derived>&>(parent));
614 }
615
616 static constexpr IntrusiveListNode const& GetNode(Derived const& parent) {
617 return static_cast<const IntrusiveListNode&>(
618 static_cast<const IntrusiveListBaseNode<Derived>&>(parent));
619 }
620
621 static constexpr Derived& GetParent(IntrusiveListNode& node) {
622 return static_cast<Derived&>(static_cast<IntrusiveListBaseNode<Derived>&>(node));
623 }
624
625 static constexpr Derived const& GetParent(IntrusiveListNode const& node) {
626 return static_cast<const Derived&>(
627 static_cast<const IntrusiveListBaseNode<Derived>&>(node));
628 }
629};
630
631} // namespace Common
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 84955030b..db1774c71 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -45,6 +45,7 @@ void LogSettings() {
45 log_setting("System_LanguageIndex", values.language_index.GetValue()); 45 log_setting("System_LanguageIndex", values.language_index.GetValue());
46 log_setting("System_RegionIndex", values.region_index.GetValue()); 46 log_setting("System_RegionIndex", values.region_index.GetValue());
47 log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue()); 47 log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue());
48 log_setting("System_UnsafeMemoryLayout", values.use_unsafe_extended_memory_layout.GetValue());
48 log_setting("Core_UseMultiCore", values.use_multi_core.GetValue()); 49 log_setting("Core_UseMultiCore", values.use_multi_core.GetValue());
49 log_setting("CPU_Accuracy", values.cpu_accuracy.GetValue()); 50 log_setting("CPU_Accuracy", values.cpu_accuracy.GetValue());
50 log_setting("Renderer_UseResolutionScaling", values.resolution_setup.GetValue()); 51 log_setting("Renderer_UseResolutionScaling", values.resolution_setup.GetValue());
@@ -60,7 +61,8 @@ void LogSettings() {
60 log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue()); 61 log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue());
61 log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue()); 62 log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue());
62 log_setting("Renderer_AsyncASTC", values.async_astc.GetValue()); 63 log_setting("Renderer_AsyncASTC", values.async_astc.GetValue());
63 log_setting("Renderer_UseVsync", values.use_vsync.GetValue()); 64 log_setting("Renderer_UseVsync", values.vsync_mode.GetValue());
65 log_setting("Renderer_UseReactiveFlushing", values.use_reactive_flushing.GetValue());
64 log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue()); 66 log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue());
65 log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); 67 log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
66 log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); 68 log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
@@ -191,7 +193,7 @@ void RestoreGlobalState(bool is_powered_on) {
191 193
192 // Core 194 // Core
193 values.use_multi_core.SetGlobal(true); 195 values.use_multi_core.SetGlobal(true);
194 values.use_extended_memory_layout.SetGlobal(true); 196 values.use_unsafe_extended_memory_layout.SetGlobal(true);
195 197
196 // CPU 198 // CPU
197 values.cpu_accuracy.SetGlobal(true); 199 values.cpu_accuracy.SetGlobal(true);
@@ -205,6 +207,7 @@ void RestoreGlobalState(bool is_powered_on) {
205 // Renderer 207 // Renderer
206 values.fsr_sharpening_slider.SetGlobal(true); 208 values.fsr_sharpening_slider.SetGlobal(true);
207 values.renderer_backend.SetGlobal(true); 209 values.renderer_backend.SetGlobal(true);
210 values.async_presentation.SetGlobal(true);
208 values.renderer_force_max_clock.SetGlobal(true); 211 values.renderer_force_max_clock.SetGlobal(true);
209 values.vulkan_device.SetGlobal(true); 212 values.vulkan_device.SetGlobal(true);
210 values.fullscreen_mode.SetGlobal(true); 213 values.fullscreen_mode.SetGlobal(true);
@@ -221,11 +224,10 @@ void RestoreGlobalState(bool is_powered_on) {
221 values.nvdec_emulation.SetGlobal(true); 224 values.nvdec_emulation.SetGlobal(true);
222 values.accelerate_astc.SetGlobal(true); 225 values.accelerate_astc.SetGlobal(true);
223 values.async_astc.SetGlobal(true); 226 values.async_astc.SetGlobal(true);
224 values.use_vsync.SetGlobal(true); 227 values.use_reactive_flushing.SetGlobal(true);
225 values.shader_backend.SetGlobal(true); 228 values.shader_backend.SetGlobal(true);
226 values.use_asynchronous_shaders.SetGlobal(true); 229 values.use_asynchronous_shaders.SetGlobal(true);
227 values.use_fast_gpu_time.SetGlobal(true); 230 values.use_fast_gpu_time.SetGlobal(true);
228 values.use_pessimistic_flushes.SetGlobal(true);
229 values.use_vulkan_driver_pipeline_cache.SetGlobal(true); 231 values.use_vulkan_driver_pipeline_cache.SetGlobal(true);
230 values.bg_red.SetGlobal(true); 232 values.bg_red.SetGlobal(true);
231 values.bg_green.SetGlobal(true); 233 values.bg_green.SetGlobal(true);
diff --git a/src/common/settings.h b/src/common/settings.h
index b77a1580a..f4eb4e3cd 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -16,6 +16,13 @@
16 16
17namespace Settings { 17namespace Settings {
18 18
19enum class VSyncMode : u32 {
20 Immediate = 0,
21 Mailbox = 1,
22 FIFO = 2,
23 FIFORelaxed = 3,
24};
25
19enum class RendererBackend : u32 { 26enum class RendererBackend : u32 {
20 OpenGL = 0, 27 OpenGL = 0,
21 Vulkan = 1, 28 Vulkan = 1,
@@ -388,7 +395,8 @@ struct Values {
388 395
389 // Core 396 // Core
390 SwitchableSetting<bool> use_multi_core{true, "use_multi_core"}; 397 SwitchableSetting<bool> use_multi_core{true, "use_multi_core"};
391 SwitchableSetting<bool> use_extended_memory_layout{false, "use_extended_memory_layout"}; 398 SwitchableSetting<bool> use_unsafe_extended_memory_layout{false,
399 "use_unsafe_extended_memory_layout"};
392 400
393 // Cpu 401 // Cpu
394 SwitchableSetting<CPUAccuracy, true> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto, 402 SwitchableSetting<CPUAccuracy, true> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto,
@@ -422,6 +430,7 @@ struct Values {
422 // Renderer 430 // Renderer
423 SwitchableSetting<RendererBackend, true> renderer_backend{ 431 SwitchableSetting<RendererBackend, true> renderer_backend{
424 RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, "backend"}; 432 RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, "backend"};
433 SwitchableSetting<bool> async_presentation{false, "async_presentation"};
425 SwitchableSetting<bool> renderer_force_max_clock{false, "force_max_clock"}; 434 SwitchableSetting<bool> renderer_force_max_clock{false, "force_max_clock"};
426 Setting<bool> renderer_debug{false, "debug"}; 435 Setting<bool> renderer_debug{false, "debug"};
427 Setting<bool> renderer_shader_feedback{false, "shader_feedback"}; 436 Setting<bool> renderer_shader_feedback{false, "shader_feedback"};
@@ -454,12 +463,13 @@ struct Values {
454 SwitchableSetting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"}; 463 SwitchableSetting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"};
455 SwitchableSetting<bool> accelerate_astc{true, "accelerate_astc"}; 464 SwitchableSetting<bool> accelerate_astc{true, "accelerate_astc"};
456 SwitchableSetting<bool> async_astc{false, "async_astc"}; 465 SwitchableSetting<bool> async_astc{false, "async_astc"};
457 SwitchableSetting<bool> use_vsync{true, "use_vsync"}; 466 Setting<VSyncMode, true> vsync_mode{VSyncMode::FIFO, VSyncMode::Immediate,
467 VSyncMode::FIFORelaxed, "use_vsync"};
468 SwitchableSetting<bool> use_reactive_flushing{true, "use_reactive_flushing"};
458 SwitchableSetting<ShaderBackend, true> shader_backend{ShaderBackend::GLSL, ShaderBackend::GLSL, 469 SwitchableSetting<ShaderBackend, true> shader_backend{ShaderBackend::GLSL, ShaderBackend::GLSL,
459 ShaderBackend::SPIRV, "shader_backend"}; 470 ShaderBackend::SPIRV, "shader_backend"};
460 SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"}; 471 SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
461 SwitchableSetting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"}; 472 SwitchableSetting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"};
462 SwitchableSetting<bool> use_pessimistic_flushes{false, "use_pessimistic_flushes"};
463 SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{true, 473 SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{true,
464 "use_vulkan_driver_pipeline_cache"}; 474 "use_vulkan_driver_pipeline_cache"};
465 475
diff --git a/src/common/vector_math.h b/src/common/vector_math.h
index 0e2095c45..b4885835d 100644
--- a/src/common/vector_math.h
+++ b/src/common/vector_math.h
@@ -259,6 +259,20 @@ public:
259 return *this; 259 return *this;
260 } 260 }
261 261
262 void RotateFromOrigin(float roll, float pitch, float yaw) {
263 float temp = y;
264 y = std::cos(roll) * y - std::sin(roll) * z;
265 z = std::sin(roll) * temp + std::cos(roll) * z;
266
267 temp = x;
268 x = std::cos(pitch) * x + std::sin(pitch) * z;
269 z = -std::sin(pitch) * temp + std::cos(pitch) * z;
270
271 temp = x;
272 x = std::cos(yaw) * x - std::sin(yaw) * y;
273 y = std::sin(yaw) * temp + std::cos(yaw) * y;
274 }
275
262 [[nodiscard]] constexpr T Length2() const { 276 [[nodiscard]] constexpr T Length2() const {
263 return x * x + y * y + z * z; 277 return x * x + y * y + z * z;
264 } 278 }