Merge pull request #11253 from liamwhite/i-hate-this-toolchain

general: fix apple clang build
master
liamwhite 2023-08-11 16:53:20 +07:00 committed by GitHub
commit 640f7cd945
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 73 deletions

@ -1,7 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <functional>
#include <string> #include <string>
#include <vector>
#include "common/settings_common.h" #include "common/settings_common.h"
namespace Settings { namespace Settings {

@ -12,8 +12,8 @@ namespace Settings {
template <typename T> template <typename T>
struct EnumMetadata { struct EnumMetadata {
static constexpr std::vector<std::pair<std::string, T>> Canonicalizations(); static std::vector<std::pair<std::string, T>> Canonicalizations();
static constexpr u32 Index(); static u32 Index();
}; };
#define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__)) #define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__))
@ -66,11 +66,11 @@ struct EnumMetadata {
#define ENUM(NAME, ...) \ #define ENUM(NAME, ...) \
enum class NAME : u32 { __VA_ARGS__ }; \ enum class NAME : u32 { __VA_ARGS__ }; \
template <> \ template <> \
constexpr std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \ inline std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \
return {PAIR(NAME, __VA_ARGS__)}; \ return {PAIR(NAME, __VA_ARGS__)}; \
} \ } \
template <> \ template <> \
constexpr u32 EnumMetadata<NAME>::Index() { \ inline u32 EnumMetadata<NAME>::Index() { \
return __COUNTER__; \ return __COUNTER__; \
} }
@ -85,7 +85,7 @@ enum class AudioEngine : u32 {
}; };
template <> template <>
constexpr std::vector<std::pair<std::string, AudioEngine>> inline std::vector<std::pair<std::string, AudioEngine>>
EnumMetadata<AudioEngine>::Canonicalizations() { EnumMetadata<AudioEngine>::Canonicalizations() {
return { return {
{"auto", AudioEngine::Auto}, {"auto", AudioEngine::Auto},
@ -96,7 +96,7 @@ EnumMetadata<AudioEngine>::Canonicalizations() {
} }
template <> template <>
constexpr u32 EnumMetadata<AudioEngine>::Index() { inline u32 EnumMetadata<AudioEngine>::Index() {
// This is just a sufficiently large number that is more than the number of other enums declared // This is just a sufficiently large number that is more than the number of other enums declared
// here // here
return 100; return 100;
@ -147,7 +147,7 @@ ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
template <typename Type> template <typename Type>
constexpr std::string CanonicalizeEnum(Type id) { inline std::string CanonicalizeEnum(Type id) {
const auto group = EnumMetadata<Type>::Canonicalizations(); const auto group = EnumMetadata<Type>::Canonicalizations();
for (auto& [name, value] : group) { for (auto& [name, value] : group) {
if (value == id) { if (value == id) {
@ -158,7 +158,7 @@ constexpr std::string CanonicalizeEnum(Type id) {
} }
template <typename Type> template <typename Type>
constexpr Type ToEnum(const std::string& canonicalization) { inline Type ToEnum(const std::string& canonicalization) {
const auto group = EnumMetadata<Type>::Canonicalizations(); const auto group = EnumMetadata<Type>::Canonicalizations();
for (auto& [name, value] : group) { for (auto& [name, value] : group) {
if (name == canonicalization) { if (name == canonicalization) {

@ -190,7 +190,7 @@ public:
} }
} }
[[nodiscard]] std::string constexpr Canonicalize() const override final { [[nodiscard]] std::string Canonicalize() const override final {
if constexpr (std::is_enum_v<Type>) { if constexpr (std::is_enum_v<Type>) {
return CanonicalizeEnum(this->GetValue()); return CanonicalizeEnum(this->GetValue());
} else { } else {
@ -256,11 +256,11 @@ public:
* @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
* @param other_setting_ A second Setting to associate to this one in metadata * @param other_setting_ A second Setting to associate to this one in metadata
*/ */
template <typename T = BasicSetting>
explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name,
Category category_, u32 specialization_ = Specialization::Default, Category category_, u32 specialization_ = Specialization::Default,
bool save_ = true, bool runtime_modifiable_ = false, bool save_ = true, bool runtime_modifiable_ = false,
BasicSetting* other_setting_ = nullptr) typename std::enable_if<!ranged, T*>::type other_setting_ = nullptr)
requires(!ranged)
: Setting<Type, false>{ : Setting<Type, false>{
linkage, default_val, name, category_, specialization_, linkage, default_val, name, category_, specialization_,
save_, runtime_modifiable_, other_setting_} { save_, runtime_modifiable_, other_setting_} {
@ -282,12 +282,12 @@ public:
* @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
* @param other_setting_ A second Setting to associate to this one in metadata * @param other_setting_ A second Setting to associate to this one in metadata
*/ */
template <typename T = BasicSetting>
explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val, explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val,
const Type& max_val, const std::string& name, Category category_, const Type& max_val, const std::string& name, Category category_,
u32 specialization_ = Specialization::Default, bool save_ = true, u32 specialization_ = Specialization::Default, bool save_ = true,
bool runtime_modifiable_ = false, bool runtime_modifiable_ = false,
BasicSetting* other_setting_ = nullptr) typename std::enable_if<ranged, T*>::type other_setting_ = nullptr)
requires(ranged)
: Setting<Type, true>{linkage, default_val, min_val, : Setting<Type, true>{linkage, default_val, min_val,
max_val, name, category_, max_val, name, category_,
specialization_, save_, runtime_modifiable_, specialization_, save_, runtime_modifiable_,

@ -509,9 +509,9 @@ class GuestMemory {
public: public:
GuestMemory() = delete; GuestMemory() = delete;
explicit GuestMemory(M& memory_, u64 addr_, std::size_t size_, explicit GuestMemory(M& memory, u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr) Common::ScratchBuffer<T>* backup = nullptr)
: memory{memory_}, addr{addr_}, size{size_} { : m_memory{memory}, m_addr{addr}, m_size{size} {
static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write); static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write);
if constexpr (FLAGS & GuestMemoryFlags::Read) { if constexpr (FLAGS & GuestMemoryFlags::Read) {
Read(addr, size, backup); Read(addr, size, backup);
@ -521,89 +521,97 @@ public:
~GuestMemory() = default; ~GuestMemory() = default;
T* data() noexcept { T* data() noexcept {
return data_span.data(); return m_data_span.data();
} }
const T* data() const noexcept { const T* data() const noexcept {
return data_span.data(); return m_data_span.data();
}
size_t size() const noexcept {
return m_size;
}
size_t size_bytes() const noexcept {
return this->size() * sizeof(T);
} }
[[nodiscard]] T* begin() noexcept { [[nodiscard]] T* begin() noexcept {
return data(); return this->data();
} }
[[nodiscard]] const T* begin() const noexcept { [[nodiscard]] const T* begin() const noexcept {
return data(); return this->data();
} }
[[nodiscard]] T* end() noexcept { [[nodiscard]] T* end() noexcept {
return data() + size; return this->data() + this->size();
} }
[[nodiscard]] const T* end() const noexcept { [[nodiscard]] const T* end() const noexcept {
return data() + size; return this->data() + this->size();
} }
T& operator[](size_t index) noexcept { T& operator[](size_t index) noexcept {
return data_span[index]; return m_data_span[index];
} }
const T& operator[](size_t index) const noexcept { const T& operator[](size_t index) const noexcept {
return data_span[index]; return m_data_span[index];
} }
void SetAddressAndSize(u64 addr_, std::size_t size_) noexcept { void SetAddressAndSize(u64 addr, std::size_t size) noexcept {
addr = addr_; m_addr = addr;
size = size_; m_size = size;
addr_changed = true; m_addr_changed = true;
} }
std::span<T> Read(u64 addr_, std::size_t size_, std::span<T> Read(u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr) noexcept { Common::ScratchBuffer<T>* backup = nullptr) noexcept {
addr = addr_; m_addr = addr;
size = size_; m_size = size;
if (size == 0) { if (m_size == 0) {
is_data_copy = true; m_is_data_copy = true;
return {}; return {};
} }
if (TrySetSpan()) { if (this->TrySetSpan()) {
if constexpr (FLAGS & GuestMemoryFlags::Safe) { if constexpr (FLAGS & GuestMemoryFlags::Safe) {
memory.FlushRegion(addr, size * sizeof(T)); m_memory.FlushRegion(m_addr, this->size_bytes());
} }
} else { } else {
if (backup) { if (backup) {
backup->resize_destructive(size); backup->resize_destructive(this->size());
data_span = *backup; m_data_span = *backup;
} else { } else {
data_copy.resize(size); m_data_copy.resize(this->size());
data_span = std::span(data_copy); m_data_span = std::span(m_data_copy);
} }
is_data_copy = true; m_is_data_copy = true;
span_valid = true; m_span_valid = true;
if constexpr (FLAGS & GuestMemoryFlags::Safe) { if constexpr (FLAGS & GuestMemoryFlags::Safe) {
memory.ReadBlock(addr, data_span.data(), size * sizeof(T)); m_memory.ReadBlock(m_addr, this->data(), this->size_bytes());
} else { } else {
memory.ReadBlockUnsafe(addr, data_span.data(), size * sizeof(T)); m_memory.ReadBlockUnsafe(m_addr, this->data(), this->size_bytes());
} }
} }
return data_span; return m_data_span;
} }
void Write(std::span<T> write_data) noexcept { void Write(std::span<T> write_data) noexcept {
if constexpr (FLAGS & GuestMemoryFlags::Cached) { if constexpr (FLAGS & GuestMemoryFlags::Cached) {
memory.WriteBlockCached(addr, write_data.data(), size * sizeof(T)); m_memory.WriteBlockCached(m_addr, write_data.data(), this->size_bytes());
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) { } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
memory.WriteBlock(addr, write_data.data(), size * sizeof(T)); m_memory.WriteBlock(m_addr, write_data.data(), this->size_bytes());
} else { } else {
memory.WriteBlockUnsafe(addr, write_data.data(), size * sizeof(T)); m_memory.WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes());
} }
} }
bool TrySetSpan() noexcept { bool TrySetSpan() noexcept {
if (u8* ptr = memory.GetSpan(addr, size * sizeof(T)); ptr) { if (u8* ptr = m_memory.GetSpan(m_addr, this->size_bytes()); ptr) {
data_span = {reinterpret_cast<T*>(ptr), size}; m_data_span = {reinterpret_cast<T*>(ptr), this->size()};
span_valid = true; m_span_valid = true;
return true; return true;
} }
return false; return false;
@ -611,36 +619,36 @@ public:
protected: protected:
bool IsDataCopy() const noexcept { bool IsDataCopy() const noexcept {
return is_data_copy; return m_is_data_copy;
} }
bool AddressChanged() const noexcept { bool AddressChanged() const noexcept {
return addr_changed; return m_addr_changed;
} }
M& memory; M& m_memory;
u64 addr; u64 m_addr{};
size_t size; size_t m_size{};
std::span<T> data_span{}; std::span<T> m_data_span{};
std::vector<T> data_copy; std::vector<T> m_data_copy{};
bool span_valid{false}; bool m_span_valid{false};
bool is_data_copy{false}; bool m_is_data_copy{false};
bool addr_changed{false}; bool m_addr_changed{false};
}; };
template <typename M, typename T, GuestMemoryFlags FLAGS> template <typename M, typename T, GuestMemoryFlags FLAGS>
class GuestMemoryScoped : public GuestMemory<M, T, FLAGS> { class GuestMemoryScoped : public GuestMemory<M, T, FLAGS> {
public: public:
GuestMemoryScoped() = delete; GuestMemoryScoped() = delete;
explicit GuestMemoryScoped(M& memory_, u64 addr_, std::size_t size_, explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr) Common::ScratchBuffer<T>* backup = nullptr)
: GuestMemory<M, T, FLAGS>(memory_, addr_, size_, backup) { : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {
if constexpr (!(FLAGS & GuestMemoryFlags::Read)) { if constexpr (!(FLAGS & GuestMemoryFlags::Read)) {
if (!this->TrySetSpan()) { if (!this->TrySetSpan()) {
if (backup) { if (backup) {
this->data_span = *backup; this->m_data_span = *backup;
this->span_valid = true; this->m_span_valid = true;
this->is_data_copy = true; this->m_is_data_copy = true;
} }
} }
} }
@ -648,24 +656,21 @@ public:
~GuestMemoryScoped() { ~GuestMemoryScoped() {
if constexpr (FLAGS & GuestMemoryFlags::Write) { if constexpr (FLAGS & GuestMemoryFlags::Write) {
if (this->size == 0) [[unlikely]] { if (this->size() == 0) [[unlikely]] {
return; return;
} }
if (this->AddressChanged() || this->IsDataCopy()) { if (this->AddressChanged() || this->IsDataCopy()) {
ASSERT(this->span_valid); ASSERT(this->m_span_valid);
if constexpr (FLAGS & GuestMemoryFlags::Cached) { if constexpr (FLAGS & GuestMemoryFlags::Cached) {
this->memory.WriteBlockCached(this->addr, this->data_span.data(), this->m_memory.WriteBlockCached(this->m_addr, this->data(), this->size_bytes());
this->size * sizeof(T));
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) { } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
this->memory.WriteBlock(this->addr, this->data_span.data(), this->m_memory.WriteBlock(this->m_addr, this->data(), this->size_bytes());
this->size * sizeof(T));
} else { } else {
this->memory.WriteBlockUnsafe(this->addr, this->data_span.data(), this->m_memory.WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes());
this->size * sizeof(T));
} }
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) { } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
this->memory.InvalidateRegion(this->addr, this->size * sizeof(T)); this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes());
} }
} }
} }

@ -5,6 +5,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/microprofile.h" #include "common/microprofile.h"
#include "common/polyfill_ranges.h"
#include "common/settings.h" #include "common/settings.h"
#include "core/core.h" #include "core/core.h"
#include "core/memory.h" #include "core/memory.h"