summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/settings_common.cpp2
-rw-r--r--src/common/settings_enums.h16
-rw-r--r--src/common/settings_setting.h10
-rw-r--r--src/core/memory.h125
-rw-r--r--src/video_core/engines/maxwell_dma.cpp1
5 files changed, 81 insertions, 73 deletions
diff --git a/src/common/settings_common.cpp b/src/common/settings_common.cpp
index dedf5ef90..137b65d5f 100644
--- a/src/common/settings_common.cpp
+++ b/src/common/settings_common.cpp
@@ -1,7 +1,9 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <functional>
4#include <string> 5#include <string>
6#include <vector>
5#include "common/settings_common.h" 7#include "common/settings_common.h"
6 8
7namespace Settings { 9namespace Settings {
diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h
index a1a29ebf6..e7cb59ea5 100644
--- a/src/common/settings_enums.h
+++ b/src/common/settings_enums.h
@@ -12,8 +12,8 @@ namespace Settings {
12 12
13template <typename T> 13template <typename T>
14struct EnumMetadata { 14struct EnumMetadata {
15 static constexpr std::vector<std::pair<std::string, T>> Canonicalizations(); 15 static std::vector<std::pair<std::string, T>> Canonicalizations();
16 static constexpr u32 Index(); 16 static u32 Index();
17}; 17};
18 18
19#define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__)) 19#define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__))
@@ -66,11 +66,11 @@ struct EnumMetadata {
66#define ENUM(NAME, ...) \ 66#define ENUM(NAME, ...) \
67 enum class NAME : u32 { __VA_ARGS__ }; \ 67 enum class NAME : u32 { __VA_ARGS__ }; \
68 template <> \ 68 template <> \
69 constexpr std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \ 69 inline std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \
70 return {PAIR(NAME, __VA_ARGS__)}; \ 70 return {PAIR(NAME, __VA_ARGS__)}; \
71 } \ 71 } \
72 template <> \ 72 template <> \
73 constexpr u32 EnumMetadata<NAME>::Index() { \ 73 inline u32 EnumMetadata<NAME>::Index() { \
74 return __COUNTER__; \ 74 return __COUNTER__; \
75 } 75 }
76 76
@@ -85,7 +85,7 @@ enum class AudioEngine : u32 {
85}; 85};
86 86
87template <> 87template <>
88constexpr std::vector<std::pair<std::string, AudioEngine>> 88inline std::vector<std::pair<std::string, AudioEngine>>
89EnumMetadata<AudioEngine>::Canonicalizations() { 89EnumMetadata<AudioEngine>::Canonicalizations() {
90 return { 90 return {
91 {"auto", AudioEngine::Auto}, 91 {"auto", AudioEngine::Auto},
@@ -96,7 +96,7 @@ EnumMetadata<AudioEngine>::Canonicalizations() {
96} 96}
97 97
98template <> 98template <>
99constexpr u32 EnumMetadata<AudioEngine>::Index() { 99inline u32 EnumMetadata<AudioEngine>::Index() {
100 // This is just a sufficiently large number that is more than the number of other enums declared 100 // This is just a sufficiently large number that is more than the number of other enums declared
101 // here 101 // here
102 return 100; 102 return 100;
@@ -147,7 +147,7 @@ ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
147ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); 147ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
148 148
149template <typename Type> 149template <typename Type>
150constexpr std::string CanonicalizeEnum(Type id) { 150inline std::string CanonicalizeEnum(Type id) {
151 const auto group = EnumMetadata<Type>::Canonicalizations(); 151 const auto group = EnumMetadata<Type>::Canonicalizations();
152 for (auto& [name, value] : group) { 152 for (auto& [name, value] : group) {
153 if (value == id) { 153 if (value == id) {
@@ -158,7 +158,7 @@ constexpr std::string CanonicalizeEnum(Type id) {
158} 158}
159 159
160template <typename Type> 160template <typename Type>
161constexpr Type ToEnum(const std::string& canonicalization) { 161inline Type ToEnum(const std::string& canonicalization) {
162 const auto group = EnumMetadata<Type>::Canonicalizations(); 162 const auto group = EnumMetadata<Type>::Canonicalizations();
163 for (auto& [name, value] : group) { 163 for (auto& [name, value] : group) {
164 if (name == canonicalization) { 164 if (name == canonicalization) {
diff --git a/src/common/settings_setting.h b/src/common/settings_setting.h
index a8beb06e9..e10843c73 100644
--- a/src/common/settings_setting.h
+++ b/src/common/settings_setting.h
@@ -190,7 +190,7 @@ public:
190 } 190 }
191 } 191 }
192 192
193 [[nodiscard]] std::string constexpr Canonicalize() const override final { 193 [[nodiscard]] std::string Canonicalize() const override final {
194 if constexpr (std::is_enum_v<Type>) { 194 if constexpr (std::is_enum_v<Type>) {
195 return CanonicalizeEnum(this->GetValue()); 195 return CanonicalizeEnum(this->GetValue());
196 } else { 196 } else {
@@ -256,11 +256,11 @@ public:
256 * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded 256 * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
257 * @param other_setting_ A second Setting to associate to this one in metadata 257 * @param other_setting_ A second Setting to associate to this one in metadata
258 */ 258 */
259 template <typename T = BasicSetting>
259 explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, 260 explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name,
260 Category category_, u32 specialization_ = Specialization::Default, 261 Category category_, u32 specialization_ = Specialization::Default,
261 bool save_ = true, bool runtime_modifiable_ = false, 262 bool save_ = true, bool runtime_modifiable_ = false,
262 BasicSetting* other_setting_ = nullptr) 263 typename std::enable_if<!ranged, T*>::type other_setting_ = nullptr)
263 requires(!ranged)
264 : Setting<Type, false>{ 264 : Setting<Type, false>{
265 linkage, default_val, name, category_, specialization_, 265 linkage, default_val, name, category_, specialization_,
266 save_, runtime_modifiable_, other_setting_} { 266 save_, runtime_modifiable_, other_setting_} {
@@ -282,12 +282,12 @@ public:
282 * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded 282 * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
283 * @param other_setting_ A second Setting to associate to this one in metadata 283 * @param other_setting_ A second Setting to associate to this one in metadata
284 */ 284 */
285 template <typename T = BasicSetting>
285 explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val, 286 explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val,
286 const Type& max_val, const std::string& name, Category category_, 287 const Type& max_val, const std::string& name, Category category_,
287 u32 specialization_ = Specialization::Default, bool save_ = true, 288 u32 specialization_ = Specialization::Default, bool save_ = true,
288 bool runtime_modifiable_ = false, 289 bool runtime_modifiable_ = false,
289 BasicSetting* other_setting_ = nullptr) 290 typename std::enable_if<ranged, T*>::type other_setting_ = nullptr)
290 requires(ranged)
291 : Setting<Type, true>{linkage, default_val, min_val, 291 : Setting<Type, true>{linkage, default_val, min_val,
292 max_val, name, category_, 292 max_val, name, category_,
293 specialization_, save_, runtime_modifiable_, 293 specialization_, save_, runtime_modifiable_,
diff --git a/src/core/memory.h b/src/core/memory.h
index 2eb61ffd3..13047a545 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -509,9 +509,9 @@ class GuestMemory {
509 509
510public: 510public:
511 GuestMemory() = delete; 511 GuestMemory() = delete;
512 explicit GuestMemory(M& memory_, u64 addr_, std::size_t size_, 512 explicit GuestMemory(M& memory, u64 addr, std::size_t size,
513 Common::ScratchBuffer<T>* backup = nullptr) 513 Common::ScratchBuffer<T>* backup = nullptr)
514 : memory{memory_}, addr{addr_}, size{size_} { 514 : m_memory{memory}, m_addr{addr}, m_size{size} {
515 static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write); 515 static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write);
516 if constexpr (FLAGS & GuestMemoryFlags::Read) { 516 if constexpr (FLAGS & GuestMemoryFlags::Read) {
517 Read(addr, size, backup); 517 Read(addr, size, backup);
@@ -521,89 +521,97 @@ public:
521 ~GuestMemory() = default; 521 ~GuestMemory() = default;
522 522
523 T* data() noexcept { 523 T* data() noexcept {
524 return data_span.data(); 524 return m_data_span.data();
525 } 525 }
526 526
527 const T* data() const noexcept { 527 const T* data() const noexcept {
528 return data_span.data(); 528 return m_data_span.data();
529 }
530
531 size_t size() const noexcept {
532 return m_size;
533 }
534
535 size_t size_bytes() const noexcept {
536 return this->size() * sizeof(T);
529 } 537 }
530 538
531 [[nodiscard]] T* begin() noexcept { 539 [[nodiscard]] T* begin() noexcept {
532 return data(); 540 return this->data();
533 } 541 }
534 542
535 [[nodiscard]] const T* begin() const noexcept { 543 [[nodiscard]] const T* begin() const noexcept {
536 return data(); 544 return this->data();
537 } 545 }
538 546
539 [[nodiscard]] T* end() noexcept { 547 [[nodiscard]] T* end() noexcept {
540 return data() + size; 548 return this->data() + this->size();
541 } 549 }
542 550
543 [[nodiscard]] const T* end() const noexcept { 551 [[nodiscard]] const T* end() const noexcept {
544 return data() + size; 552 return this->data() + this->size();
545 } 553 }
546 554
547 T& operator[](size_t index) noexcept { 555 T& operator[](size_t index) noexcept {
548 return data_span[index]; 556 return m_data_span[index];
549 } 557 }
550 558
551 const T& operator[](size_t index) const noexcept { 559 const T& operator[](size_t index) const noexcept {
552 return data_span[index]; 560 return m_data_span[index];
553 } 561 }
554 562
555 void SetAddressAndSize(u64 addr_, std::size_t size_) noexcept { 563 void SetAddressAndSize(u64 addr, std::size_t size) noexcept {
556 addr = addr_; 564 m_addr = addr;
557 size = size_; 565 m_size = size;
558 addr_changed = true; 566 m_addr_changed = true;
559 } 567 }
560 568
561 std::span<T> Read(u64 addr_, std::size_t size_, 569 std::span<T> Read(u64 addr, std::size_t size,
562 Common::ScratchBuffer<T>* backup = nullptr) noexcept { 570 Common::ScratchBuffer<T>* backup = nullptr) noexcept {
563 addr = addr_; 571 m_addr = addr;
564 size = size_; 572 m_size = size;
565 if (size == 0) { 573 if (m_size == 0) {
566 is_data_copy = true; 574 m_is_data_copy = true;
567 return {}; 575 return {};
568 } 576 }
569 577
570 if (TrySetSpan()) { 578 if (this->TrySetSpan()) {
571 if constexpr (FLAGS & GuestMemoryFlags::Safe) { 579 if constexpr (FLAGS & GuestMemoryFlags::Safe) {
572 memory.FlushRegion(addr, size * sizeof(T)); 580 m_memory.FlushRegion(m_addr, this->size_bytes());
573 } 581 }
574 } else { 582 } else {
575 if (backup) { 583 if (backup) {
576 backup->resize_destructive(size); 584 backup->resize_destructive(this->size());
577 data_span = *backup; 585 m_data_span = *backup;
578 } else { 586 } else {
579 data_copy.resize(size); 587 m_data_copy.resize(this->size());
580 data_span = std::span(data_copy); 588 m_data_span = std::span(m_data_copy);
581 } 589 }
582 is_data_copy = true; 590 m_is_data_copy = true;
583 span_valid = true; 591 m_span_valid = true;
584 if constexpr (FLAGS & GuestMemoryFlags::Safe) { 592 if constexpr (FLAGS & GuestMemoryFlags::Safe) {
585 memory.ReadBlock(addr, data_span.data(), size * sizeof(T)); 593 m_memory.ReadBlock(m_addr, this->data(), this->size_bytes());
586 } else { 594 } else {
587 memory.ReadBlockUnsafe(addr, data_span.data(), size * sizeof(T)); 595 m_memory.ReadBlockUnsafe(m_addr, this->data(), this->size_bytes());
588 } 596 }
589 } 597 }
590 return data_span; 598 return m_data_span;
591 } 599 }
592 600
593 void Write(std::span<T> write_data) noexcept { 601 void Write(std::span<T> write_data) noexcept {
594 if constexpr (FLAGS & GuestMemoryFlags::Cached) { 602 if constexpr (FLAGS & GuestMemoryFlags::Cached) {
595 memory.WriteBlockCached(addr, write_data.data(), size * sizeof(T)); 603 m_memory.WriteBlockCached(m_addr, write_data.data(), this->size_bytes());
596 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) { 604 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
597 memory.WriteBlock(addr, write_data.data(), size * sizeof(T)); 605 m_memory.WriteBlock(m_addr, write_data.data(), this->size_bytes());
598 } else { 606 } else {
599 memory.WriteBlockUnsafe(addr, write_data.data(), size * sizeof(T)); 607 m_memory.WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes());
600 } 608 }
601 } 609 }
602 610
603 bool TrySetSpan() noexcept { 611 bool TrySetSpan() noexcept {
604 if (u8* ptr = memory.GetSpan(addr, size * sizeof(T)); ptr) { 612 if (u8* ptr = m_memory.GetSpan(m_addr, this->size_bytes()); ptr) {
605 data_span = {reinterpret_cast<T*>(ptr), size}; 613 m_data_span = {reinterpret_cast<T*>(ptr), this->size()};
606 span_valid = true; 614 m_span_valid = true;
607 return true; 615 return true;
608 } 616 }
609 return false; 617 return false;
@@ -611,36 +619,36 @@ public:
611 619
612protected: 620protected:
613 bool IsDataCopy() const noexcept { 621 bool IsDataCopy() const noexcept {
614 return is_data_copy; 622 return m_is_data_copy;
615 } 623 }
616 624
617 bool AddressChanged() const noexcept { 625 bool AddressChanged() const noexcept {
618 return addr_changed; 626 return m_addr_changed;
619 } 627 }
620 628
621 M& memory; 629 M& m_memory;
622 u64 addr; 630 u64 m_addr{};
623 size_t size; 631 size_t m_size{};
624 std::span<T> data_span{}; 632 std::span<T> m_data_span{};
625 std::vector<T> data_copy; 633 std::vector<T> m_data_copy{};
626 bool span_valid{false}; 634 bool m_span_valid{false};
627 bool is_data_copy{false}; 635 bool m_is_data_copy{false};
628 bool addr_changed{false}; 636 bool m_addr_changed{false};
629}; 637};
630 638
631template <typename M, typename T, GuestMemoryFlags FLAGS> 639template <typename M, typename T, GuestMemoryFlags FLAGS>
632class GuestMemoryScoped : public GuestMemory<M, T, FLAGS> { 640class GuestMemoryScoped : public GuestMemory<M, T, FLAGS> {
633public: 641public:
634 GuestMemoryScoped() = delete; 642 GuestMemoryScoped() = delete;
635 explicit GuestMemoryScoped(M& memory_, u64 addr_, std::size_t size_, 643 explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size,
636 Common::ScratchBuffer<T>* backup = nullptr) 644 Common::ScratchBuffer<T>* backup = nullptr)
637 : GuestMemory<M, T, FLAGS>(memory_, addr_, size_, backup) { 645 : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {
638 if constexpr (!(FLAGS & GuestMemoryFlags::Read)) { 646 if constexpr (!(FLAGS & GuestMemoryFlags::Read)) {
639 if (!this->TrySetSpan()) { 647 if (!this->TrySetSpan()) {
640 if (backup) { 648 if (backup) {
641 this->data_span = *backup; 649 this->m_data_span = *backup;
642 this->span_valid = true; 650 this->m_span_valid = true;
643 this->is_data_copy = true; 651 this->m_is_data_copy = true;
644 } 652 }
645 } 653 }
646 } 654 }
@@ -648,24 +656,21 @@ public:
648 656
649 ~GuestMemoryScoped() { 657 ~GuestMemoryScoped() {
650 if constexpr (FLAGS & GuestMemoryFlags::Write) { 658 if constexpr (FLAGS & GuestMemoryFlags::Write) {
651 if (this->size == 0) [[unlikely]] { 659 if (this->size() == 0) [[unlikely]] {
652 return; 660 return;
653 } 661 }
654 662
655 if (this->AddressChanged() || this->IsDataCopy()) { 663 if (this->AddressChanged() || this->IsDataCopy()) {
656 ASSERT(this->span_valid); 664 ASSERT(this->m_span_valid);
657 if constexpr (FLAGS & GuestMemoryFlags::Cached) { 665 if constexpr (FLAGS & GuestMemoryFlags::Cached) {
658 this->memory.WriteBlockCached(this->addr, this->data_span.data(), 666 this->m_memory.WriteBlockCached(this->m_addr, this->data(), this->size_bytes());
659 this->size * sizeof(T));
660 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) { 667 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
661 this->memory.WriteBlock(this->addr, this->data_span.data(), 668 this->m_memory.WriteBlock(this->m_addr, this->data(), this->size_bytes());
662 this->size * sizeof(T));
663 } else { 669 } else {
664 this->memory.WriteBlockUnsafe(this->addr, this->data_span.data(), 670 this->m_memory.WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes());
665 this->size * sizeof(T));
666 } 671 }
667 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) { 672 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
668 this->memory.InvalidateRegion(this->addr, this->size * sizeof(T)); 673 this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes());
669 } 674 }
670 } 675 }
671 } 676 }
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index cd8e24b0b..da8eab7ee 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -5,6 +5,7 @@
5#include "common/assert.h" 5#include "common/assert.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "common/microprofile.h" 7#include "common/microprofile.h"
8#include "common/polyfill_ranges.h"
8#include "common/settings.h" 9#include "common/settings.h"
9#include "core/core.h" 10#include "core/core.h"
10#include "core/memory.h" 11#include "core/memory.h"