diff --git a/.clang-tidy b/.clang-tidy index 48098124..6a4d98b7 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -4,6 +4,7 @@ Checks: > modernize-*, performance-*, readability-*, + -bugprone-easily-swappable-parameters, -bugprone-exception-escape, -bugprone-unchecked-optional-access, @@ -18,6 +19,7 @@ Checks: > -cppcoreguidelines-avoid-do-while, -cppcoreguidelines-pro-type-static-cast-downcast, -cppcoreguidelines-avoid-const-or-ref-data-members, + -cppcoreguidelines-init-variables, -modernize-use-trailing-return-type, -modernize-use-integer-sign-comparison, -readability-magic-numbers, @@ -28,10 +30,10 @@ Checks: > -readability-else-after-return, -readability-avoid-nested-conditional-operator, -readability-math-missing-parentheses, + -readability-redundant-declaration, -bugprone-macro-parentheses, -cppcoreguidelines-pro-type-member-init, - -cppcoreguidelines-init-variables, -cppcoreguidelines-non-private-member-variables-in-classes, -cppcoreguidelines-pro-bounds-constant-array-index, -cppcoreguidelines-owning-memory, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 17b50c15..d6b7c3d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,9 @@ include_directories(.) +set(ZTD_PRECOMPILE_HEADERS ON) +set(ZTD_CLANG_TIDY_ENABLED ${CLANG_TIDY_ENABLED}) +add_subdirectory(ztd) + if (CLANG_TIDY_ENABLED) set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-use-color;-extra-arg-before=-Wno-unknown-warning-option") endif () diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index bf9a75c7..3b49bfa1 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,30 +1,19 @@ add_library(hydra-common - platform.hpp macros.hpp type_aliases.hpp types.hpp - range.hpp traits.hpp functions.hpp atomic.hpp - literals.hpp string.hpp - time.hpp - hash.hpp - linked_list.hpp - pool.hpp - static_pool.hpp - dynamic_pool.hpp small_cache.hpp filesystem.hpp log.cpp log.hpp - lz4.cpp - lz4.hpp toml_helper.hpp + fmt_helper.hpp config.cpp config.hpp - common.hpp io/stream.hpp io/continuous_stream.hpp io/memory_stream.hpp @@ -33,11 +22,11 @@ add_library(hydra-common io/sparse_stream.hpp ) -target_link_libraries(hydra-common PRIVATE hydra_compile_options) -target_link_libraries(hydra-common PUBLIC fmt::fmt toml11::toml11) - target_precompile_headers(hydra-common PUBLIC common.hpp) +target_link_libraries(hydra-common PRIVATE hydra_compile_options) +target_link_libraries(hydra-common PUBLIC fmt::fmt toml11::toml11 ztd::ztd) + if (CMAKE_SYSTEM_NAME STREQUAL "iOS") set_target_properties(hydra-common PROPERTIES XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET ${IOS_DEPLOYMENT_TARGET} diff --git a/src/common/common.hpp b/src/common/common.hpp index 86236154..77e23388 100644 --- a/src/common/common.hpp +++ b/src/common/common.hpp @@ -11,23 +11,16 @@ #include "common/atomic.hpp" #include "common/config.hpp" -#include "common/dynamic_pool.hpp" #include "common/filesystem.hpp" +#include "common/fmt_helper.hpp" #include "common/functions.hpp" -#include "common/hash.hpp" #include "common/io/iostream_stream.hpp" #include "common/io/memory_stream.hpp" #include "common/io/sparse_stream.hpp" #include "common/io/stream_view.hpp" -#include "common/linked_list.hpp" -#include "common/literals.hpp" #include "common/log.hpp" #include "common/objc.hpp" -#include "common/platform.hpp" -#include "common/range.hpp" #include "common/small_cache.hpp" -#include "common/static_pool.hpp" #include "common/string.hpp" -#include "common/time.hpp" #include "common/toml_helper.hpp" #include "common/traits.hpp" diff --git a/src/common/config.cpp b/src/common/config.cpp index 8febaedc..2fa6f24b 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -63,7 +63,7 @@ struct into { namespace hydra { Config::Config() { -#ifdef PLATFORM_APPLE +#ifdef ZTD_PLATFORM_APPLE if (const char* home = std::getenv("HOME")) { app_data_path = fmt::format("{}/Library/Application Support/" APP_NAME, home); @@ -72,7 +72,7 @@ Config::Config() { } else { LOG_FATAL(Other, "Failed to find HOME path"); } -#elifdef PLATFORM_WINDOWS +#elifdef ZTD_PLATFORM_WINDOWS if (const char* app_data = std::getenv("APPDATA")) { app_data_path = fmt::format("{}/" APP_NAME, app_data); logs_path = fmt::format("{}/logs", app_data_path); // TODO @@ -85,7 +85,7 @@ Config::Config() { } else { LOG_FATAL(Other, "Failed to find USERPROFILE path"); } -#elif defined(PLATFORM_LINUX) +#elifdef ZTD_PLATFORM_LINUX if (const char* xdg_config = std::getenv("XDG_CONFIG_HOME")) { app_data_path = fmt::format("{}/" APP_NAME, xdg_config); logs_path = fmt::format("{}/logs", app_data_path); @@ -111,7 +111,7 @@ Config::Config() { std::filesystem::create_directories(app_data_path); std::filesystem::create_directories(logs_path); // HACK -#ifndef PLATFORM_IOS +#ifndef ZTD_PLATFORM_IOS std::filesystem::create_directories(pictures_path); #endif diff --git a/src/common/config.hpp b/src/common/config.hpp index 3f2ff14f..7d551d03 100644 --- a/src/common/config.hpp +++ b/src/common/config.hpp @@ -1,9 +1,11 @@ #pragma once +#include + #include +#include "common/fmt_helper.hpp" #include "common/log.hpp" -#include "common/platform.hpp" #include "common/types.hpp" #define CONFIG_INSTANCE Config::GetInstance() @@ -104,7 +106,7 @@ class Config { static std::vector GetDefaultLoaderPlugins() { return {}; } static std::vector GetDefaultPatchPaths() { return {}; } static InputBackend GetDefaultInputBackend() { -#ifdef PLATFORM_APPLE +#ifdef ZTD_PLATFORM_APPLE return InputBackend::AppleGameController; #else return InputBackend::Sdl; @@ -121,7 +123,7 @@ class Config { #endif } static GpuRenderer GetDefaultGpuRenderer() { -#ifdef PLATFORM_APPLE +#ifdef ZTD_PLATFORM_APPLE return GpuRenderer::Metal; #else return GpuRenderer::Null; diff --git a/src/common/dynamic_pool.hpp b/src/common/dynamic_pool.hpp deleted file mode 100644 index 8dc7fc33..00000000 --- a/src/common/dynamic_pool.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "common/pool.hpp" - -namespace hydra { - -// TODO: this needs optimizations real bad -template -class DynamicPool : public Pool, T, allow_zero_handle> { - public: - u32 AllocateIndex_() { - // TODO: look for a free index first - - const auto index = static_cast(objects.size()); - objects.push_back({}); - - return index; - } - - void FreeByIndex_(u32 index) { - if (index == objects.size() - 1) - objects.pop_back(); - else - free_slots.push_back(index); - } - - bool IsValidByIndex_(u32 index) const { - if (index >= objects.size()) - return false; - - return std::find(free_slots.begin(), free_slots.end(), index) == - free_slots.end(); - } - - T& GetByIndex_(u32 index) { return objects[index]; } - - const T& GetByIndex_(u32 index) const { return objects[index]; } - - usize GetCapacity() const { return objects.size(); } - - private: - std::vector objects; - std::vector free_slots; -}; - -} // namespace hydra diff --git a/src/common/filesystem.hpp b/src/common/filesystem.hpp index e8582219..1aa4ebd8 100644 --- a/src/common/filesystem.hpp +++ b/src/common/filesystem.hpp @@ -4,12 +4,12 @@ #include +#include "common/fmt_helper.hpp" #include "common/log.hpp" -#include "common/platform.hpp" namespace hydra { -#ifdef PLATFORM_APPLE +#ifdef ZTD_PLATFORM_APPLE inline std::string GetBundleResourcePath(const std::string& filename) { CFBundleRef main_bundle = CFBundleGetMainBundle(); if (main_bundle == nullptr) { diff --git a/src/common/fmt_helper.hpp b/src/common/fmt_helper.hpp new file mode 100644 index 00000000..ec10c804 --- /dev/null +++ b/src/common/fmt_helper.hpp @@ -0,0 +1,108 @@ +#pragma once + +#include "ztd/ztd.hpp" + +#include +#include + +#define ENUM_FORMAT_CASE(type, c, name) \ + case type::c: \ + res = name; \ + break; + +#define ENABLE_ENUM_FORMATTING(type, ...) \ + template <> \ + struct fmt::formatter : formatter { \ + template \ + auto format(type value, FormatContext& ctx) const { \ + std::string_view res; \ + switch (value) { \ + ZTD_FOR_EACH_1_2(ENUM_FORMAT_CASE, type, __VA_ARGS__) \ + default: \ + return formatter::format( \ + fmt::format("unknown ({})", \ + static_cast(value)), \ + ctx); \ + break; \ + } \ + return formatter::format(res, ctx); \ + } \ + }; + +#define STRUCT_FORMAT_CASE(member, f, name) \ + fmt::format(name ": {" f "}", value.member), + +#define ENABLE_STRUCT_FORMATTING(type, ...) \ + template <> \ + struct fmt::formatter : formatter { \ + template \ + auto format(const type& value, FormatContext& ctx) const { \ + /* TODO: make this more efficient */ \ + std::string res = fmt::format( \ + "{}", fmt::join(std::array{ZTD_FOR_EACH_0_3( \ + STRUCT_FORMAT_CASE, __VA_ARGS__)}, \ + ", ")); \ + return formatter::format(std::move(res), ctx); \ + } \ + }; + +#define ENUM_CAST_CASE(type, value, n) \ + if (value_str == n) \ + return type::value; + +#define ENABLE_ENUM_CASTING(namespc, type, ...) \ + namespace namespc { \ + inline std::optional To##type(std::string_view value_str) { \ + ZTD_FOR_EACH_1_2(ENUM_CAST_CASE, type, __VA_ARGS__) \ + return std::nullopt; \ + } \ + } + +#define ENABLE_ENUM_FORMATTING_AND_CASTING(namespc, type, ...) \ + ENABLE_ENUM_FORMATTING(namespc::type, __VA_ARGS__) \ + ENABLE_ENUM_CASTING(namespc, type, __VA_ARGS__) + +#define ENUM_BIT_TEST(type, c, n) \ + if (any(value & type::c)) { \ + if (added) \ + name += " | "; \ + else \ + added = true; \ + name += n; \ + } + +#define ENABLE_ENUM_FLAGS_FORMATTING(type, ...) \ + template <> \ + struct fmt::formatter : formatter { \ + template \ + auto format(type value, FormatContext& ctx) const { \ + std::string name; \ + bool added = false; \ + ZTD_FOR_EACH_1_2(ENUM_BIT_TEST, type, __VA_ARGS__) \ + if (!added) \ + name = "none"; \ + return formatter::format(name, ctx); \ + } \ + }; + +template +struct fmt::formatter> : formatter { + fmt::formatter value_formatter; + + constexpr auto parse(fmt::format_parse_context& ctx) { + return value_formatter.parse(ctx); + } + + template + auto format(const ztd::Range& range, FormatContext& ctx) const { + auto out = ctx.out(); + + *out++ = '<'; + out = value_formatter.format(range.getBegin(), ctx); + out = fmt::format_to(out, ", "); + out = value_formatter.format(range.getEnd(), ctx); + *out++ = ')'; + + return out; + } +}; diff --git a/src/common/functions.hpp b/src/common/functions.hpp index f131640e..031e2460 100644 --- a/src/common/functions.hpp +++ b/src/common/functions.hpp @@ -84,8 +84,8 @@ T ceil_divide(T dividend, T divisor) { return (dividend + divisor - 1) / divisor; } -inline constexpr u32 make_magic4(const char c0, const char c1, const char c2, - const char c3) { +constexpr u32 make_magic4(const char c0, const char c1, const char c2, + const char c3) { return static_cast(c0) | static_cast(c1) << 8 | static_cast(c2) << 16 | static_cast(c3) << 24; } diff --git a/src/common/io/continuous_stream.hpp b/src/common/io/continuous_stream.hpp index 134a00a3..d0923ef9 100644 --- a/src/common/io/continuous_stream.hpp +++ b/src/common/io/continuous_stream.hpp @@ -9,8 +9,8 @@ class IContinuousStream : public IStream { IContinuousStream() noexcept = default; ~IContinuousStream() noexcept = default; - MAKE_DEFAULT_COPYABLE(IContinuousStream); - MAKE_NON_MOVABLE(IContinuousStream); + ZTD_MAKE_DEFAULT_COPYABLE(IContinuousStream); + ZTD_MAKE_DEFAULT_MOVABLE(IContinuousStream); u64 GetSeek() const override { return seek; } void SeekTo(u64 seek_) override { seek = seek_; } diff --git a/src/common/io/memory_stream.hpp b/src/common/io/memory_stream.hpp index 1a3f9212..1263fe40 100644 --- a/src/common/io/memory_stream.hpp +++ b/src/common/io/memory_stream.hpp @@ -8,8 +8,8 @@ class MemoryStream : public IContinuousStream { public: MemoryStream(std::span data_) : data{data_} {} - MAKE_DEFAULT_COPYABLE(MemoryStream); - MAKE_DEFAULT_MOVABLE(MemoryStream); + ZTD_MAKE_DEFAULT_COPYABLE(MemoryStream); + ZTD_MAKE_DEFAULT_MOVABLE(MemoryStream); u64 GetSize() const override { return data.size(); } diff --git a/src/common/io/sparse_stream.hpp b/src/common/io/sparse_stream.hpp index 499a043b..2ab73888 100644 --- a/src/common/io/sparse_stream.hpp +++ b/src/common/io/sparse_stream.hpp @@ -1,14 +1,13 @@ #pragma once #include "common/io/stream.hpp" -#include "common/range.hpp" namespace hydra::io { class SparseStream : public IStream { public: struct Entry { - Range range; + ztd::Range range; IStream* stream; }; @@ -36,9 +35,9 @@ class SparseStream : public IStream { const auto entry = GetEntry(seek); const auto max_read_size = std::min( - entry.range.GetEnd() - seek, static_cast(buffer.size())); + entry.range.getEnd() - seek, static_cast(buffer.size())); if (entry.stream != nullptr) { - entry.stream->SeekTo(seek - entry.range.GetBegin()); + entry.stream->SeekTo(seek - entry.range.getBegin()); entry.stream->ReadRaw(buffer.subspan(0, max_read_size)); } else { std::fill(buffer.begin(), @@ -58,9 +57,9 @@ class SparseStream : public IStream { const auto entry = GetEntry(seek); const auto max_write_size = std::min( - entry.range.GetEnd() - seek, static_cast(buffer.size())); + entry.range.getEnd() - seek, static_cast(buffer.size())); if (entry.stream != nullptr) { - entry.stream->SeekTo(seek - entry.range.GetBegin()); + entry.stream->SeekTo(seek - entry.range.getBegin()); entry.stream->WriteRaw(buffer.subspan(0, max_write_size)); } @@ -83,7 +82,7 @@ class SparseStream : public IStream { // First, check if the entry has been cached if (cached_entry.has_value()) { const auto entry = cached_entry.value(); - if (entry.range.Contains(offset)) + if (entry.range.contains(offset)) return entry; } @@ -91,22 +90,22 @@ class SparseStream : public IStream { auto next_it = std::upper_bound(entries.begin(), entries.end(), offset, [](u64 offset, const Entry& entry) { - return offset < entry.range.GetBegin(); + return offset < entry.range.getBegin(); }); // If the offset is before the first entry, return an empty entry if (next_it == entries.begin()) - return {.range = {0, next_it->range.GetBegin()}, .stream = nullptr}; + return {.range = {0, next_it->range.getBegin()}, .stream = nullptr}; auto it = std::prev(next_it); // Check if entry is past the range - if (!it->range.Contains(offset)) { + if (!it->range.contains(offset)) { if (next_it == entries.end()) - return {.range = {it->range.GetEnd(), size - offset}, + return {.range = {it->range.getEnd(), size - offset}, .stream = nullptr}; - return {.range = {it->range.GetEnd(), next_it->range.GetBegin()}, + return {.range = {it->range.getEnd(), next_it->range.getBegin()}, .stream = nullptr}; } @@ -126,7 +125,7 @@ class OwnedSparseStream : public SparseStream { delete entry.stream; } - MAKE_NON_COPYABLE(OwnedSparseStream); + ZTD_MAKE_NON_COPYABLE(OwnedSparseStream); }; } // namespace hydra::io diff --git a/src/common/io/stream.hpp b/src/common/io/stream.hpp index f5a1384f..a7274306 100644 --- a/src/common/io/stream.hpp +++ b/src/common/io/stream.hpp @@ -13,8 +13,8 @@ class IStream { IStream() = default; virtual ~IStream() noexcept = default; - MAKE_DEFAULT_COPYABLE(IStream); - MAKE_DEFAULT_MOVABLE(IStream); + ZTD_MAKE_DEFAULT_COPYABLE(IStream); + ZTD_MAKE_DEFAULT_MOVABLE(IStream); virtual u64 GetSeek() const = 0; virtual void SeekTo(u64 seek) { diff --git a/src/common/io/stream_view.hpp b/src/common/io/stream_view.hpp index 1c95ab65..a79ab431 100644 --- a/src/common/io/stream_view.hpp +++ b/src/common/io/stream_view.hpp @@ -44,7 +44,7 @@ class OwnedStreamView : public StreamView { ~OwnedStreamView() override { delete base; } - MAKE_NON_COPYABLE(OwnedStreamView); + ZTD_MAKE_NON_COPYABLE(OwnedStreamView); }; } // namespace hydra::io diff --git a/src/common/linked_list.hpp b/src/common/linked_list.hpp deleted file mode 100644 index 7b3d6269..00000000 --- a/src/common/linked_list.hpp +++ /dev/null @@ -1,204 +0,0 @@ -#pragma once - -#include "common/log.hpp" -#include "common/type_aliases.hpp" - -namespace hydra { - -template -class LinkedListNode { - template - friend class LinkedList; - - public: - LinkedListNode(const T& value_) : value{value_} {} - - operator const T&() const { return value; } - const T* operator->() const { return &value; } - T* operator->() { return &value; } - - private: - T value; - LinkedListNode* next{nullptr}; - - public: - CONST_REF_GETTER(value, Get); - GETTER(next, GetNext); -}; - -template -class LinkedListNode { - template - friend class LinkedList; - - public: - LinkedListNode(const T& value_) : value{value_} {} - - operator const T&() const { return value; } - const T* operator->() const { return &value; } - T* operator->() { return &value; } - - private: - T value; - LinkedListNode* next{nullptr}; - LinkedListNode* prev{nullptr}; - - public: - CONST_REF_GETTER(value, Get); - GETTER(next, GetNext); - GETTER(prev, GetPrev); -}; - -template -class LinkedList { - using Node = LinkedListNode; - - public: - enum class Error { - Empty, - InvalidNode, - }; - - void AddFirst(const T& value) { - auto node = new Node(value); - if (!head) { - head = tail = node; - } else { - node->next = head; - if constexpr (is_doubly_linked) - head->prev = node; - head = node; - } - size++; - } - - void AddLast(const T& value) { - auto node = new Node(value); - if (!head) { - head = tail = node; - } else { - tail->next = node; - if constexpr (is_doubly_linked) - node->prev = tail; - tail = node; - } - size++; - } - - void RemoveFirst() { - ASSERT_DEBUG(head, Common, "List is empty"); - - auto node = head; - head = head->next; - delete node; - if (!head) - tail = nullptr; - size--; - } - - bool RemoveLast() { - ASSERT_DEBUG(head, Common, "List is empty"); - - if (!head->next) { - delete head; - head = tail = nullptr; - } else { - auto node = head; - while (node->next != tail) - node = node->next; - delete tail; - tail = node; - tail->next = nullptr; - } - size--; - } - - Node* Remove(Node* target) { - ASSERT_DEBUG(target, Common, "Invalid node"); - ASSERT_DEBUG(head, Common, "List is empty"); - - if constexpr (is_doubly_linked) { - // A more efficient way to remove a node from a doubly linked list - - // Head - if (target == head) { - head = target->next; - } else { - ASSERT_DEBUG(target->prev, Common, "Invalid node"); - target->prev->next = target->next; - } - - // Tail - if (target == tail) { - tail = target->prev; - } else { - ASSERT_DEBUG(target->next, Common, "Invalid node"); - target->next->prev = target->prev; - } - - auto next = target->next; - delete target; - size--; - return next; - } else { - if (head == target) { - RemoveFirst(); - return head; - } - - if (tail == target) { - RemoveLast(); - return nullptr; - } - - auto node = head; - while (node->next && node->next != target) - node = node->next; - ASSERT_DEBUG(node->next, Common, "Invalid node"); - - node->next = target->next; - delete target; - if (!node->next) - tail = node; - size--; - return node->next; - } - } - - void Remove(const T& target) - requires is_doubly_linked - { - ASSERT_DEBUG(target, Common, "Invalid node"); - - // Remove all occurrences of the target - for (auto node = head; node;) { - if (node->value == target) - node = Remove(node); - else - node = node->next; - } - } - - void Clear() { - // TODO: do more efficiently - while (head) - RemoveFirst(); - } - - private: - Node* head{nullptr}; - Node* tail{nullptr}; - usize size{0}; - - public: - GETTER(head, GetHead); - GETTER(tail, GetTail); - GETTER(size, GetSize); -}; - -template -using SingleLinkedList = LinkedList; -template -using DoubleLinkedList = LinkedList; - -} // namespace hydra diff --git a/src/common/literals.hpp b/src/common/literals.hpp deleted file mode 100644 index 4f775508..00000000 --- a/src/common/literals.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "common/type_aliases.hpp" - -namespace hydra { - -inline unsigned long long operator"" _KiB(unsigned long long x) { - return x * 1024; -} - -inline unsigned long long operator"" _MiB(unsigned long long x) { - return x * 1024_KiB; -} - -inline unsigned long long operator"" _GiB(unsigned long long x) { - return x * 1024_MiB; -} - -inline unsigned long long operator"" _TiB(unsigned long long x) { - return x * 1024_GiB; -} - -/* -inline constexpr const char* operator"" _str(u64 value) { - return reinterpret_cast(&value); -} -*/ - -} // namespace hydra diff --git a/src/common/log.hpp b/src/common/log.hpp index 656d230e..7adb3353 100644 --- a/src/common/log.hpp +++ b/src/common/log.hpp @@ -30,7 +30,7 @@ #define LOG_INFO(c, ...) LOG(Info, c, __VA_ARGS__) #define LOG_STUBBED(c, f, ...) \ - LOG(Stub, c, f " stubbed" PASS_VA_ARGS(__VA_ARGS__)) + LOG(Stub, c, f " stubbed" ZTD_PASS_VA_ARGS(__VA_ARGS__)) #define LOG_WARN(c, ...) LOG(Warning, c, __VA_ARGS__) #define LOG_ERROR(c, ...) LOG(Error, c, __VA_ARGS__) #ifdef HYDRA_DEBUG @@ -50,7 +50,7 @@ #define LOG_FUNC_WITH_ARGS_STUBBED(c, f, ...) \ LOG_STUBBED(c, "{} (" f ")", __func__, __VA_ARGS__) #define LOG_NOT_IMPLEMENTED(c, f, ...) \ - LOG_WARN(c, f " not implemented" PASS_VA_ARGS(__VA_ARGS__)) + LOG_WARN(c, f " not implemented" ZTD_PASS_VA_ARGS(__VA_ARGS__)) #define LOG_FUNC_WITH_ARGS_NOT_IMPLEMENTED(c, f, ...) \ LOG_NOT_IMPLEMENTED(c, "{} (" f ")", __func__, __VA_ARGS__) #define LOG_FUNC_NOT_IMPLEMENTED(c) LOG_NOT_IMPLEMENTED(c, "{}", __func__) @@ -71,14 +71,12 @@ ASSERT_ALIGNMENT(value, alignment, c, name) #else // TODO: should the condition be evaluated? -#define ASSERT_DEBUG(condition, c, ...) \ - if (condition) { \ - } +#define ASSERT_DEBUG(condition, c, ...) (void)(condition) #define ASSERT_ALIGNMENT_DEBUG(value, alignment, c, name) #endif #define INDENT_FMT "{:{}}" -#define PASS_INDENT(indent) "", ((indent)*4) +#define PASS_INDENT(indent) "", ((indent) * 4) namespace hydra { @@ -172,8 +170,8 @@ class Logger { Logger() noexcept = default; ~Logger() noexcept = default; - MAKE_NON_COPYABLE(Logger); - MAKE_NON_MOVABLE(Logger); + ZTD_MAKE_NON_COPYABLE(Logger); + ZTD_MAKE_NON_MOVABLE(Logger); void InstallCallback(const log_callback_fn_t& callback_) { std::lock_guard lock(mutex); diff --git a/src/common/lz4.hpp b/src/common/lz4.hpp deleted file mode 100644 index a75b7a4a..00000000 --- a/src/common/lz4.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -#include "common/type_aliases.hpp" - -namespace hydra { - -void DecompressLZ4(std::span src, std::span dst); - -} // namespace hydra diff --git a/src/common/macros.hpp b/src/common/macros.hpp index 0facb327..48ec9064 100644 --- a/src/common/macros.hpp +++ b/src/common/macros.hpp @@ -4,28 +4,6 @@ #define sizeof_array(array) (sizeof(array) / sizeof(array[0])) -#define CONCAT_IMPL(a, b) a##b -#define CONCAT(a, b) CONCAT_IMPL(a, b) - -#define UNIQUE_SUFFIX(var) CONCAT(var, __LINE__) - -#define ASSIGN_OR(var, expected, fail_statement) \ - const auto UNIQUE_SUFFIX(_) = expected; \ - if (!UNIQUE_SUFFIX(_).has_value()) \ - fail_statement; \ - var = UNIQUE_SUFFIX(_).value(); - -#define ASSIGN_OR_RETURN_VALUE(var, expected, ret) \ - ASSIGN_OR(var, expected, return ret) -#define ASSIGN_OR_RETURN(var, expected) ASSIGN_OR_RETURN_VALUE(var, expected, ) -#define ASSIGN_OR_RETURN_ERROR(var, expected) \ - ASSIGN_OR_RETURN_VALUE(var, expected, std::unexpected(expected.error())) - -#define ASSIGN_OR_CONTINUE(var, expected, ret) \ - ASSIGN_OR(var, expected, continue) - -#define ASSIGN_OR_BREAK(var, expected, ret) ASSIGN_OR(var, expected, break) - #define ONCE(code) \ { \ static bool executed = false; \ @@ -38,79 +16,6 @@ #define THIS reinterpret_cast(this) #define CONST_THIS reinterpret_cast(this) -#define PASS(...) __VA_ARGS__ -#define PASS_VA_ARGS(...) , ##__VA_ARGS__ - -#define BIT(n) (1u << (n)) -#define BITL(n) (1ul << (n)) - -#define ENABLE_ENUM_ARITHMETIC_OPERATORS(type) \ - [[maybe_unused]] inline type operator+(type a, type b) { \ - return static_cast( \ - static_cast>(a) + \ - static_cast>(b)); \ - } \ - [[maybe_unused]] inline type operator-(type a, type b) { \ - return static_cast( \ - static_cast>(a) - \ - static_cast>(b)); \ - } \ - [[maybe_unused]] inline type operator*(type a, type b) { \ - return static_cast( \ - static_cast>(a) * \ - static_cast>(b)); \ - } \ - [[maybe_unused]] inline type operator/(type a, type b) { \ - return static_cast( \ - static_cast>(a) / \ - static_cast>(b)); \ - } \ - [[maybe_unused]] inline type operator++(type& x, i32) { \ - const auto tmp = x; \ - x = static_cast(static_cast>(x) + \ - 1); \ - return tmp; \ - } \ - [[maybe_unused]] inline type operator--(type& x, i32) { \ - const auto tmp = x; \ - x = static_cast(static_cast>(x) - \ - 1); \ - return tmp; \ - } \ - [[maybe_unused]] inline type& operator++(type& x) { \ - x = static_cast(static_cast>(x) + \ - 1); \ - return x; \ - } \ - [[maybe_unused]] inline type& operator--(type& x) { \ - x = static_cast(static_cast>(x) - \ - 1); \ - return x; \ - } - -#define ENABLE_ENUM_BITWISE_OPERATORS(type) \ - [[maybe_unused]] inline type operator|(type a, type b) { \ - return static_cast( \ - static_cast>(a) | \ - static_cast>(b)); \ - } \ - [[maybe_unused]] inline type& operator|=(type& a, type b) { \ - return a = a | b; \ - } \ - [[maybe_unused]] inline type operator&(type a, type b) { \ - return static_cast( \ - static_cast>(a) & \ - static_cast>(b)); \ - } \ - [[maybe_unused]] inline type& operator&=(type& a, type b) { \ - return a = a & b; \ - } \ - [[maybe_unused]] inline type operator~(type a) { \ - return static_cast( \ - ~static_cast>(a)); \ - } \ - [[maybe_unused]] inline bool any(type a) { return a != type::None; } - #define GETTER(member, name) \ decltype(member) name() const { return member; } #define REF_GETTER(member, name) \ @@ -149,185 +54,3 @@ #define CONSTEXPR_GETTER_AND_SETTER(member, getter_name, setter_name) \ CONSTEXPR_GETTER(member, getter_name) \ SETTER(member, setter_name) - -#define PARENS () - -#define EXPAND(...) EXPAND4(EXPAND4(EXPAND4(EXPAND4(__VA_ARGS__)))) -#define EXPAND4(...) EXPAND3(EXPAND3(EXPAND3(EXPAND3(__VA_ARGS__)))) -#define EXPAND3(...) EXPAND2(EXPAND2(EXPAND2(EXPAND2(__VA_ARGS__)))) -#define EXPAND2(...) EXPAND1(EXPAND1(EXPAND1(EXPAND1(__VA_ARGS__)))) -#define EXPAND1(...) __VA_ARGS__ - -#define FOR_EACH_0_1(macro, ...) \ - __VA_OPT__(EXPAND(FOR_EACH_HELPER_0_1(macro, __VA_ARGS__))) -#define FOR_EACH_HELPER_0_1(macro, a, ...) \ - macro(a) __VA_OPT__(FOR_EACH_AGAIN_0_1 PARENS(macro, __VA_ARGS__)) -#define FOR_EACH_AGAIN_0_1() FOR_EACH_HELPER_0_1 - -#define FOR_EACH_0_2(macro, ...) \ - __VA_OPT__(EXPAND(FOR_EACH_HELPER_0_2(macro, __VA_ARGS__))) -#define FOR_EACH_HELPER_0_2(macro, a1, a2, ...) \ - macro(a1, a2) __VA_OPT__(FOR_EACH_AGAIN_0_2 PARENS(macro, __VA_ARGS__)) -#define FOR_EACH_AGAIN_0_2() FOR_EACH_HELPER_0_2 - -#define FOR_EACH_0_3(macro, ...) \ - __VA_OPT__(EXPAND(FOR_EACH_HELPER_0_3(macro, __VA_ARGS__))) -#define FOR_EACH_HELPER_0_3(macro, a1, a2, a3, ...) \ - macro(a1, a2, a3) __VA_OPT__(FOR_EACH_AGAIN_0_3 PARENS(macro, __VA_ARGS__)) -#define FOR_EACH_AGAIN_0_3() FOR_EACH_HELPER_0_3 - -#define FOR_EACH_0_4(macro, ...) \ - __VA_OPT__(EXPAND(FOR_EACH_HELPER_0_4(macro, __VA_ARGS__))) -#define FOR_EACH_HELPER_0_4(macro, a1, a2, a3, a4, ...) \ - macro(a1, a2, a3, a4) \ - __VA_OPT__(FOR_EACH_AGAIN_0_4 PARENS(macro, __VA_ARGS__)) -#define FOR_EACH_AGAIN_0_4() FOR_EACH_HELPER_0_4 - -#define FOR_EACH_1_2(macro, e, ...) \ - __VA_OPT__(EXPAND(FOR_EACH_HELPER_1_2(macro, e, __VA_ARGS__))) -#define FOR_EACH_HELPER_1_2(macro, e, a1, a2, ...) \ - macro(e, a1, a2) \ - __VA_OPT__(FOR_EACH_AGAIN_1_2 PARENS(macro, e, __VA_ARGS__)) -#define FOR_EACH_AGAIN_1_2() FOR_EACH_HELPER_1_2 - -#define FOR_EACH_1_3(macro, e, ...) \ - __VA_OPT__(EXPAND(FOR_EACH_HELPER_1_3(macro, e, __VA_ARGS__))) -#define FOR_EACH_HELPER_1_3(macro, e, a1, a2, a3, ...) \ - macro(e, a1, a2, a3) \ - __VA_OPT__(FOR_EACH_AGAIN_1_3 PARENS(macro, e, __VA_ARGS__)) -#define FOR_EACH_AGAIN_1_3() FOR_EACH_HELPER_1_3 - -#define FOR_EACH_2_1(macro, e1, e2, ...) \ - __VA_OPT__(EXPAND(FOR_EACH_HELPER_2_1(macro, e1, e2, __VA_ARGS__))) -#define FOR_EACH_HELPER_2_1(macro, e1, e2, a, ...) \ - macro(e1, e2, a) \ - __VA_OPT__(FOR_EACH_AGAIN_2_1 PARENS(macro, e1, e2, __VA_ARGS__)) -#define FOR_EACH_AGAIN_2_1() FOR_EACH_HELPER_2_1 - -#define FOR_EACH_2_2(macro, e1, e2, ...) \ - __VA_OPT__(EXPAND(FOR_EACH_HELPER_2_2(macro, e1, e2, __VA_ARGS__))) -#define FOR_EACH_HELPER_2_2(macro, e1, e2, a1, a2, ...) \ - macro(e1, e2, a1, a2) \ - __VA_OPT__(FOR_EACH_AGAIN_2_2 PARENS(macro, e1, e2, __VA_ARGS__)) -#define FOR_EACH_AGAIN_2_2() FOR_EACH_HELPER_2_2 - -#define ENUM_FORMAT_CASE(type, c, name) \ - case type::c: \ - res = name; \ - break; - -#define ENABLE_ENUM_FORMATTING(type, ...) \ - template <> \ - struct fmt::formatter : formatter { \ - template \ - auto format(type value, FormatContext& ctx) const { \ - std::string_view res; \ - switch (value) { \ - FOR_EACH_1_2(ENUM_FORMAT_CASE, type, __VA_ARGS__) \ - default: \ - return formatter::format( \ - fmt::format("unknown ({})", \ - static_cast(value)), \ - ctx); \ - break; \ - } \ - return formatter::format(res, ctx); \ - } \ - }; - -#define STRUCT_FORMAT_CASE(member, f, name) \ - fmt::format(name ": {" f "}", value.member), - -#define ENABLE_STRUCT_FORMATTING(type, ...) \ - template <> \ - struct fmt::formatter : formatter { \ - template \ - auto format(const type& value, FormatContext& ctx) const { \ - /* TODO: make this more efficient */ \ - std::string res = fmt::format( \ - "{}", fmt::join(std::array{FOR_EACH_0_3(STRUCT_FORMAT_CASE, \ - __VA_ARGS__)}, \ - ", ")); \ - return formatter::format(std::move(res), ctx); \ - } \ - }; - -#define ENUM_CAST_CASE(type, value, n) \ - if (value_str == n) \ - return type::value; - -#define ENABLE_ENUM_CASTING(namespc, type, ...) \ - namespace namespc { \ - inline std::optional To##type(std::string_view value_str) { \ - FOR_EACH_1_2(ENUM_CAST_CASE, type, __VA_ARGS__) \ - return std::nullopt; \ - } \ - } - -#define ENABLE_ENUM_FORMATTING_AND_CASTING(namespc, type, ...) \ - ENABLE_ENUM_FORMATTING(namespc::type, __VA_ARGS__) \ - ENABLE_ENUM_CASTING(namespc, type, __VA_ARGS__) - -#define ENUM_BIT_TEST(type, c, n) \ - if (any(value & type::c)) { \ - if (added) \ - name += " | "; \ - else \ - added = true; \ - name += n; \ - } - -#define ENABLE_ENUM_FLAGS_FORMATTING(type, ...) \ - template <> \ - struct fmt::formatter : formatter { \ - template \ - auto format(type value, FormatContext& ctx) const { \ - std::string name; \ - bool added = false; \ - FOR_EACH_1_2(ENUM_BIT_TEST, type, __VA_ARGS__) \ - if (!added) \ - name = "none"; \ - return formatter::format(name, ctx); \ - } \ - }; - -#define MAKE_DEFAULT_COPYABLE(type) \ - type(const type&) noexcept = default; \ - type& operator=(const type&) noexcept = default; - -#define MAKE_NON_COPYABLE(type) \ - type(const type&) = delete; \ - type& operator=(const type&) = delete; - -#define MAKE_DEFAULT_MOVABLE(type) \ - type(type&&) noexcept = default; \ - type& operator=(type&&) noexcept = default; - -#define MAKE_NON_MOVABLE(type) \ - type(type&&) = delete; \ - type& operator=(type&&) = delete; - -#define SWAP_CASE(member) std::swap(a.member, b.member); - -#define MAKE_MOVE_ASSIGNABLE(type, ...) \ - type& operator=(type&& other) noexcept { \ - if (this != &other) { \ - type temp(std::move(other)); \ - swap(*this, temp); \ - } \ - return *this; \ - } \ - friend void swap(type& a, type& b) { FOR_EACH_0_1(SWAP_CASE, __VA_ARGS__) } - -#define MOVE_CASE(member, value) \ - , member { value } -#define MOVE_MEMBERS(member1, value1, ...) \ - member1{value1} FOR_EACH_0_2(MOVE_CASE, __VA_ARGS__) - -#define PASS_TO_MAKE_MOVE_ASSIGNABLE_CASE(member, value) , member -#define PASS_TO_MAKE_MOVE_ASSIGNABLE(member1, value1, ...) \ - member1 FOR_EACH_0_2(PASS_TO_MAKE_MOVE_ASSIGNABLE_CASE, __VA_ARGS__) - -#define MAKE_MOVABLE(type, ...) \ - type(type&& other) noexcept : MOVE_MEMBERS(__VA_ARGS__) {} \ - MAKE_MOVE_ASSIGNABLE(type, PASS_TO_MAKE_MOVE_ASSIGNABLE(__VA_ARGS__)) diff --git a/src/common/platform.hpp b/src/common/platform.hpp deleted file mode 100644 index b75e1592..00000000 --- a/src/common/platform.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -// Windows -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || \ - defined(__WINDOWS__) -#define PLATFORM_WINDOWS 1 -#ifdef _WIN64 -#define PLATFORM_WINDOWS_64 1 -#else -#define PLATFORM_WINDOWS_32 1 -#endif - -// Apple platforms -#elif defined(__APPLE__) || defined(__MACH__) -#include -#define PLATFORM_APPLE -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR -#define PLATFORM_IOS 1 -#elif TARGET_OS_MAC -#define PLATFORM_MACOS 1 -#endif - -// Android -#elif defined(__ANDROID__) -#define PLATFORM_ANDROID 1 - -// Linux -#elif defined(__linux__) || defined(__linux) -#define PLATFORM_LINUX 1 - -// FreeBSD -#elif defined(__FreeBSD__) -#define PLATFORM_FREEBSD 1 - -// Generic Unix -#elif defined(__unix__) || defined(__unix) -#define PLATFORM_UNIX 1 - -#else -#error "Unknown platform" -#endif diff --git a/src/common/pool.hpp b/src/common/pool.hpp deleted file mode 100644 index 9b05e455..00000000 --- a/src/common/pool.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include "common/log.hpp" -#include "common/type_aliases.hpp" - -namespace hydra { - -template -class Pool { - public: - handle_id_t AllocateHandle() { - return IndexToHandle(THIS->AllocateIndex_()); - } - - T& Allocate() { return THIS->GetByIndex_(THIS->AllocateIndex_()); } - - handle_id_t Insert(const T& object) { - const auto index = THIS->AllocateIndex_(); - THIS->GetByIndex_(index) = object; - return IndexToHandle(index); - } - - void Free(handle_id_t handle_id) { - THIS->FreeByIndex_(HandleToIndex(handle_id)); - } - - bool IsValid(handle_id_t handle_id) const { - return CONST_THIS->IsValidByIndex_(HandleToIndex(handle_id)); - } - - T& Get(handle_id_t handle_id) { - AssertHandle(handle_id); - return THIS->GetByIndex_(HandleToIndex(handle_id)); - } - - const T& Get(handle_id_t handle_id) const { - AssertHandle(handle_id); - return CONST_THIS->GetByIndex_(HandleToIndex(handle_id)); - } - - private: - // Helpers - void AssertHandle(handle_id_t handle_id) const { - ASSERT_DEBUG(IsValid(handle_id), Common, "Invalid handle {}", - handle_id); - } - - static handle_id_t IndexToHandle(u32 index) { - if constexpr (allow_zero_handle) - return index; - else - return index + 1; - } - - static u32 HandleToIndex(handle_id_t handle_id) { - if constexpr (allow_zero_handle) { - return handle_id; - } else { - ASSERT_DEBUG(handle_id != INVALID_HANDLE_ID, Common, - "Invalid handle"); - return handle_id - 1; - } - } -}; - -} // namespace hydra diff --git a/src/common/range.hpp b/src/common/range.hpp deleted file mode 100644 index 5f423b8d..00000000 --- a/src/common/range.hpp +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once - -#include "common/functions.hpp" -#include "common/log.hpp" -#include "common/macros.hpp" -#include "common/type_aliases.hpp" - -namespace hydra { - -template -class Range { - public: - static constexpr Range FromSize(T begin_, T size) { - return Range(begin_, begin_ + size); - } - - constexpr Range() : begin{0}, end{0} {} - constexpr Range(T begin_, T end_) : begin{begin_}, end{end_} {} - - bool operator==(const Range& other) const { - return begin == other.begin && end == other.end; - } - - void operator+=(T offset) { - begin += offset; - end += offset; - } - - void operator-=(T offset) { - begin -= offset; - end -= offset; - } - - // Size - constexpr T GetSize() const { return end - begin; } - constexpr void SetSize(T size) { end = begin + size; } - - // Intersection - bool Contains(T value) const { return value >= begin && value < end; } - bool Contains(const Range& other) const { - return other.begin >= begin && other.end <= end; - } - - bool Intersects(const Range& other) const { - return begin < other.end && end > other.begin; - } - - // Combining - Range ClampedTo(const Range& bounds) const { - return Range(std::max(begin, bounds.begin), - std::min(end, bounds.end)); - } - - Range Union(const Range& other) const { - return Range(std::min(begin, other.begin), std::max(end, other.end)); - } - - private: - T begin; - T end; - - public: - CONSTEXPR_GETTER_AND_SETTER(begin, GetBegin, SetBegin); - CONSTEXPR_GETTER_AND_SETTER(end, GetEnd, SetEnd); -}; - -} // namespace hydra - -template -struct fmt::formatter> : formatter { - fmt::formatter value_formatter; - - constexpr auto parse(fmt::format_parse_context& ctx) { - return value_formatter.parse(ctx); - } - - template - auto format(const hydra::Range& range, FormatContext& ctx) const { - auto out = ctx.out(); - - *out++ = '<'; - out = value_formatter.format(range.GetBegin(), ctx); - out = fmt::format_to(out, "..."); - out = value_formatter.format(range.GetEnd(), ctx); - *out++ = ')'; - - return out; - } -}; diff --git a/src/common/small_cache.hpp b/src/common/small_cache.hpp index c1a97597..430b2b73 100644 --- a/src/common/small_cache.hpp +++ b/src/common/small_cache.hpp @@ -90,8 +90,8 @@ class SmallCache { SmallCache() noexcept = default; ~SmallCache() noexcept = default; - MAKE_NON_COPYABLE(SmallCache); - MAKE_DEFAULT_MOVABLE(SmallCache); + ZTD_MAKE_NON_COPYABLE(SmallCache); + ZTD_MAKE_DEFAULT_MOVABLE(SmallCache); // TODO: const versions as well iterator begin() { return iterator(this, 0); } diff --git a/src/common/static_pool.hpp b/src/common/static_pool.hpp deleted file mode 100644 index 183824a6..00000000 --- a/src/common/static_pool.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "common/pool.hpp" - -namespace hydra { - -#define FREE_SIZE (size + 7) / 8 - -#define FREE_SLOT(index) free_slots[index / 8] -#define MASK(index) (1 << index % 8) - -template -class StaticPool : public Pool, T, allow_zero_handle> { - public: - StaticPool() { - for (u32 i = 0; i < FREE_SIZE; i++) - free_slots[i] = std::numeric_limits::max(); - } - - u32 AllocateIndex_() { - if (crnt < size) { - Take(crnt); - return crnt++; - } - - for (u32 i = 0; i < size; i++) { - if (!IsValidByIndex_(i)) { - Take(i); - return i; - } - } - -#ifdef HYDRA_DEBUG - LOG_FATAL(Common, "Free index not found"); -#endif - - return invalid(); - } - - void FreeByIndex_(u32 index) { FREE_SLOT(index) |= MASK(index); } - - bool IsValidByIndex_(u32 index) const { - if (index >= crnt) - return false; - - bool is_free = FREE_SLOT(index) & MASK(index); - return !is_free; - } - - T& GetByIndex_(u32 index) { return objects[index]; } - - const T& GetByIndex_(u32 index) const { return objects[index]; } - - usize GetCapacity() const { return size; } - - private: - std::array objects; - std::array free_slots; - u32 crnt{0}; - - void Take(u32 index) { FREE_SLOT(index) &= ~MASK(index); } -}; - -} // namespace hydra diff --git a/src/common/string.hpp b/src/common/string.hpp index b0d78f14..599e740b 100644 --- a/src/common/string.hpp +++ b/src/common/string.hpp @@ -19,7 +19,7 @@ inline std::string U64AsString(u64 value) { return {str, std::min(strlen(str), 8)}; } -inline constexpr u64 operator"" _u64(const char* str, unsigned long len) { +inline constexpr u64 operator""_u64(const char* str, unsigned long len) { return StringAsU64(std::string_view(str, len)); } diff --git a/src/common/toml_helper.hpp b/src/common/toml_helper.hpp index 50f10c79..3d7ad583 100644 --- a/src/common/toml_helper.hpp +++ b/src/common/toml_helper.hpp @@ -17,7 +17,8 @@ template \ static std::optional from_toml(const basic_value& v) { \ const auto& str = v.as_string(); \ - FOR_EACH_1_2(TOML11_CONVERSION_TOML_TO_ENUM_CASE, e, __VA_ARGS__) \ + ZTD_FOR_EACH_1_2(TOML11_CONVERSION_TOML_TO_ENUM_CASE, e, \ + __VA_ARGS__) \ return std::nullopt; \ } \ }; \ @@ -26,8 +27,8 @@ template \ static basic_value into_toml(const e& obj) { \ switch (obj) { \ - FOR_EACH_1_2(TOML11_CONVERSION_ENUM_TO_TOML_CASE, e, \ - __VA_ARGS__) \ + ZTD_FOR_EACH_1_2(TOML11_CONVERSION_ENUM_TO_TOML_CASE, e, \ + __VA_ARGS__) \ } \ } \ }; \ @@ -41,5 +42,5 @@ #define ENABLE_STRUCT_FORMATTING_AND_TOML11(s, ...) \ ENABLE_STRUCT_FORMATTING( \ - s, FOR_EACH_0_1(STRUCT_DEFAULT_FMT_CASE, __VA_ARGS__)) \ + s, ZTD_FOR_EACH_0_1(STRUCT_DEFAULT_FMT_CASE, __VA_ARGS__)) \ TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(s, __VA_ARGS__) diff --git a/src/common/type_aliases.hpp b/src/common/type_aliases.hpp index 6afa97f5..51430211 100644 --- a/src/common/type_aliases.hpp +++ b/src/common/type_aliases.hpp @@ -1,24 +1,23 @@ #pragma once -#include -#include +#include namespace hydra { -using i8 = std::int8_t; -using i16 = std::int16_t; -using i32 = std::int32_t; -using i64 = std::int64_t; -using i128 = __int128_t; -using u8 = std::uint8_t; -using u16 = std::uint16_t; -using u32 = std::uint32_t; -using u64 = std::uint64_t; -using u128 = __uint128_t; -using usize = std::size_t; -using uptr = std::uintptr_t; -using f32 = float; -using f64 = double; +using i8 = ztd::i8; +using i16 = ztd::i16; +using i32 = ztd::i32; +using i64 = ztd::i64; +using i128 = ztd::i128; +using u8 = ztd::u8; +using u16 = ztd::u16; +using u32 = ztd::u32; +using u64 = ztd::u64; +using u128 = ztd::u128; +using usize = ztd::usize; +using uptr = ztd::uptr; +using f32 = ztd::f32; +using f64 = ztd::f64; using bool32 = u32; @@ -31,4 +30,6 @@ using handle_id_t = u32; constexpr handle_id_t INVALID_HANDLE_ID = 0; +using namespace ztd::mem::literals; + } // namespace hydra diff --git a/src/common/types.hpp b/src/common/types.hpp index 71c8c176..96a68a81 100644 --- a/src/common/types.hpp +++ b/src/common/types.hpp @@ -334,7 +334,7 @@ class CacheBase { THIS->Destroy(); } - MAKE_NON_COPYABLE(CacheBase); + ZTD_MAKE_NON_COPYABLE(CacheBase); T& Find(const DescriptorT& descriptor) { u32 hash = THIS->Hash(descriptor); diff --git a/src/core/debugger/debugger.hpp b/src/core/debugger/debugger.hpp index 5cdd6af0..283d97ba 100644 --- a/src/core/debugger/debugger.hpp +++ b/src/core/debugger/debugger.hpp @@ -19,7 +19,7 @@ class IFile; if (!(condition)) { \ /* TODO: log class? */ \ GET_CURRENT_PROCESS_DEBUGGER().BreakOnThisThread( \ - f PASS_VA_ARGS(__VA_ARGS__)); \ + f ZTD_PASS_VA_ARGS(__VA_ARGS__)); \ } #ifdef HYDRA_DEBUG @@ -107,7 +107,7 @@ class Thread { struct Symbol { std::string name; - Range guest_mem_range; + ztd::Range guest_mem_range; }; class SymbolTable { @@ -116,7 +116,7 @@ class SymbolTable { std::string FindSymbol(vaddr_t addr) { for (const auto& symbol : symbols) { - if (symbol.guest_mem_range.Contains(addr)) + if (symbol.guest_mem_range.contains(addr)) return symbol.name; } diff --git a/src/core/debugger/gdb_server.cpp b/src/core/debugger/gdb_server.cpp index 126f4c3f..960c4549 100644 --- a/src/core/debugger/gdb_server.cpp +++ b/src/core/debugger/gdb_server.cpp @@ -515,7 +515,7 @@ void GdbServer::HandleQuery(std::string_view command) { // TODO: number_to_hex? output += fmt::format( R"()", - symbol.name, symbol.guest_mem_range.GetBegin()); + symbol.name, symbol.guest_mem_range.getBegin()); } output += ""; SendPacket(PageFromBuffer(output, command.substr(21))); @@ -608,7 +608,7 @@ void GdbServer::HandleInsertBreakpoint(std::string_view command) { const auto mmu = debugger.process->GetMmu(); replaced_instructions.insert({addr, mmu->Read(addr)}); mmu->Write(addr, BRK); - NotifyMemoryChanged(Range(addr, 4)); + NotifyMemoryChanged(ztd::Range(addr, 4)); } SendPacket(GDB_OK); @@ -646,7 +646,7 @@ void GdbServer::HandleRemoveBreakpoint(std::string_view command) { ASSERT(it != replaced_instructions.end(), Debugger, "Breakpoint not found at address {:#x}", addr); mmu->Write(addr, it->second); - NotifyMemoryChanged(Range(addr, 4)); + NotifyMemoryChanged(ztd::Range(addr, 4)); replaced_instructions.erase(it); } @@ -691,7 +691,7 @@ void GdbServer::HandleGetExecutables() { // Output output += fmt::format("\"{}\":{:#x}", path, - module_.guest_mem_range.GetBegin()); + module_.guest_mem_range.getBegin()); if (i < debugger.GetModuleTable().GetSymbols().size() - 1) output += ";"; @@ -800,7 +800,7 @@ void GdbServer::NotifySupervisorPausedImpl(horizon::kernel::GuestThread* thread, SendPacket(GetThreadStatus(thread, signal)); } -void GdbServer::NotifyMemoryChanged(Range mem_range) { +void GdbServer::NotifyMemoryChanged(ztd::Range mem_range) { for (const auto& [_, thread] : debugger.threads) thread.guest_thread->GetThread()->NotifyMemoryChanged(mem_range); } diff --git a/src/core/debugger/gdb_server.hpp b/src/core/debugger/gdb_server.hpp index 3eb0b0ad..3fb2b61a 100644 --- a/src/core/debugger/gdb_server.hpp +++ b/src/core/debugger/gdb_server.hpp @@ -78,7 +78,7 @@ class GdbServer { void NotifySupervisorPausedImpl(horizon::kernel::GuestThread* thread, Signal signal); - void NotifyMemoryChanged(Range mem_range); + void NotifyMemoryChanged(ztd::Range mem_range); }; } // namespace hydra::debugger diff --git a/src/core/horizon/applets/software_keyboard/const.hpp b/src/core/horizon/applets/software_keyboard/const.hpp index 0d022f2e..8734784d 100644 --- a/src/core/horizon/applets/software_keyboard/const.hpp +++ b/src/core/horizon/applets/software_keyboard/const.hpp @@ -19,16 +19,16 @@ enum class KeyboardMode : u32 { enum class InvalidCharFlags : u32 { None = 0, - Space = BIT(1), - AtMark = BIT(2), - Percent = BIT(3), - Slash = BIT(4), - BackSlash = BIT(5), - Numeric = BIT(6), - OutsideOfDownloadCode = BIT(7), - OutsideOfMiiNickName = BIT(8), + Space = ZTD_BIT(1), + AtMark = ZTD_BIT(2), + Percent = ZTD_BIT(3), + Slash = ZTD_BIT(4), + BackSlash = ZTD_BIT(5), + Numeric = ZTD_BIT(6), + OutsideOfDownloadCode = ZTD_BIT(7), + OutsideOfMiiNickName = ZTD_BIT(8), }; -ENABLE_ENUM_BITWISE_OPERATORS(InvalidCharFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(InvalidCharFlags) enum class InitialCursorPosition : u32 { First = 0, diff --git a/src/core/horizon/display/binder.hpp b/src/core/horizon/display/binder.hpp index 28073628..ed5c508e 100644 --- a/src/core/horizon/display/binder.hpp +++ b/src/core/horizon/display/binder.hpp @@ -44,14 +44,14 @@ struct NvMultiFence { enum class TransformFlags : u32 { None = 0, - FlipH = BIT(0), - FlipV = BIT(1), - Rot90 = BIT(2), - InverseDisplay = BIT(3), - NoVSyncCapability = BIT(4), - ReturnFrameNumber = BIT(5), + FlipH = ZTD_BIT(0), + FlipV = ZTD_BIT(1), + Rot90 = ZTD_BIT(2), + InverseDisplay = ZTD_BIT(3), + NoVSyncCapability = ZTD_BIT(4), + ReturnFrameNumber = ZTD_BIT(5), }; -ENABLE_ENUM_BITWISE_OPERATORS(TransformFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(TransformFlags) struct BqBufferInput { i64 timestamp; @@ -87,7 +87,8 @@ struct AccumulatedTime { explicit operator bool() const { return sample_count != 0; } explicit operator f32() const { - return static_cast(std::chrono::duration_cast>(value) + return static_cast( + std::chrono::duration_cast>(value) .count()) / static_cast(sample_count); } diff --git a/src/core/horizon/display/driver.cpp b/src/core/horizon/display/driver.cpp index 67b13c4f..8c9e0394 100644 --- a/src/core/horizon/display/driver.cpp +++ b/src/core/horizon/display/driver.cpp @@ -5,7 +5,8 @@ namespace hydra::horizon::display { Driver::Driver(System& system_) : system{system_} { - display_pool.Insert(new Display()); + ASSERT_DEBUG(display_pool.insert().has_value(), Horizon, + "Fail to create display"); } bool Driver::AcquirePresentTextures( @@ -13,12 +14,8 @@ bool Driver::AcquirePresentTextures( bool acquired = false; { std::scoped_lock lock(layer_mutex); - for (u32 layer_id = 1; layer_id < layer_pool.GetCapacity() + 1; - layer_id++) { - if (!layer_pool.IsValid(layer_id)) - continue; - acquired |= - layer_pool.Get(layer_id)->AcquirePresentTexture(command_buffer); + for (const auto& layer : layer_pool) { + acquired |= layer->AcquirePresentTexture(command_buffer); } } @@ -31,13 +28,7 @@ void Driver::Present( u32 height) { std::scoped_lock lock(layer_mutex); std::vector sorted_layers; - for (u32 layer_id = 1; layer_id < layer_pool.GetCapacity() + 1; - layer_id++) { - if (!layer_pool.IsValid(layer_id)) - continue; - - auto layer = layer_pool.Get(layer_id); - + for (const auto& layer : layer_pool) { // Find the correct position bool inserted = false; for (u32 i = 0; i < sorted_layers.size(); i++) { @@ -79,22 +70,14 @@ void Driver::Present( void Driver::SignalVSync() { // NOTE: we signal all displays at once for simplicity std::scoped_lock lock(display_mutex); - for (u32 display_id = 1; display_id < layer_pool.GetCapacity() + 1; - display_id++) { - if (!display_pool.IsValid(display_id)) - continue; - display_pool.Get(display_id)->GetVSyncEvent()->Signal(); + for (const auto& display : display_pool) { + display->GetVSyncEvent()->Signal(); } } Layer* Driver::GetFirstLayerForProcess(kernel::Process* process) { std::scoped_lock lock(layer_mutex); - for (u32 layer_id = 1; layer_id < layer_pool.GetCapacity() + 1; - layer_id++) { - if (!layer_pool.IsValid(layer_id)) - continue; - - auto layer = layer_pool.Get(layer_id); + for (const auto& layer : layer_pool) { if (layer->GetProcess() == process) return layer; } diff --git a/src/core/horizon/display/driver.hpp b/src/core/horizon/display/driver.hpp index 26ad5dde..8ef0cd10 100644 --- a/src/core/horizon/display/driver.hpp +++ b/src/core/horizon/display/driver.hpp @@ -12,7 +12,9 @@ class Driver { // Displays Display& GetDisplay(handle_id_t id) { std::scoped_lock lock(display_mutex); - return *display_pool.Get(id); + ZTD_ASSIGN_OR(auto display, display_pool.get(id), + LOG_FATAL(Horizon, "Failed to get display {}", id)); + return *display; } handle_id_t GetDisplayIDFromName(const std::string& name) { @@ -30,35 +32,38 @@ class Driver { // Layers u32 CreateLayer(kernel::Process* process, u32 binder_id) { std::scoped_lock lock(layer_mutex); - return layer_pool.Insert(new Layer(system, process, binder_id)); + return layer_pool.insert(std::ref(system), process, binder_id) + .value_or(INVALID_HANDLE_ID); } void DestroyLayer(u32 id) { std::scoped_lock lock(layer_mutex); - delete layer_pool.Get(id); - layer_pool.Free(id); + ASSERT_DEBUG(layer_pool.free(id), Horizon, "Invalid layer {}", id); } Layer& GetLayer(u32 id) { std::scoped_lock lock(layer_mutex); - return *layer_pool.Get(id); + ZTD_ASSIGN_OR(auto layer, layer_pool.get(id), + LOG_FATAL(Horizon, "Failed to get layer {}", id)); + return *layer; } // Binders u32 CreateBinder() { std::scoped_lock lock(binder_mutex); - return binder_pool.Insert(new Binder()); + return binder_pool.insert().value_or(INVALID_HANDLE_ID); } void DestroyBinder(u32 id) { std::scoped_lock lock(binder_mutex); - delete binder_pool.Get(id); - binder_pool.Free(id); + ASSERT_DEBUG(binder_pool.free(id), Horizon, "Invalid binder {}", id); } Binder& GetBinder(u32 id) { std::scoped_lock lock(binder_mutex); - return *binder_pool.Get(id); + ZTD_ASSIGN_OR(auto binder, binder_pool.get(id), + LOG_FATAL(Horizon, "Failed to get binder {}", id)); + return *binder; } // Presenting @@ -75,11 +80,11 @@ class Driver { System& system; std::mutex display_mutex; - StaticPool display_pool; + ztd::mem::StaticPool display_pool; std::mutex layer_mutex; - StaticPool layer_pool; + ztd::mem::StaticPool layer_pool; std::mutex binder_mutex; - StaticPool binder_pool; + ztd::mem::StaticPool binder_pool; }; } // namespace hydra::horizon::display diff --git a/src/core/horizon/display/layer.cpp b/src/core/horizon/display/layer.cpp index ba22cfaf..932e59f6 100644 --- a/src/core/horizon/display/layer.cpp +++ b/src/core/horizon/display/layer.cpp @@ -64,7 +64,7 @@ bool Layer::AcquirePresentTexture( void Layer::Present(hw::tegra_x1::gpu::renderer::ICommandBuffer* command_buffer, hw::tegra_x1::gpu::renderer::ISurfaceCompositor* compositor, FloatRect2D dst_rect, f32 dst_scale, bool transparent) { - ASSIGN_OR_RETURN(auto present_tex, present_texture); + ZTD_ASSIGN_OR_RETURN(auto present_tex, present_texture); // Size if (size != LAYER_SIZE_AUTO) diff --git a/src/core/horizon/filesystem/const.hpp b/src/core/horizon/filesystem/const.hpp index 255e1b63..2032a3e3 100644 --- a/src/core/horizon/filesystem/const.hpp +++ b/src/core/horizon/filesystem/const.hpp @@ -29,11 +29,11 @@ enum class FsResult { enum class FileOpenFlags { None = 0, - Read = BIT(0), - Write = BIT(1), - Append = BIT(2), + Read = ZTD_BIT(0), + Write = ZTD_BIT(1), + Append = ZTD_BIT(2), }; -ENABLE_ENUM_BITWISE_OPERATORS(FileOpenFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(FileOpenFlags) } // namespace hydra::horizon::filesystem diff --git a/src/core/horizon/filesystem/disk_file.hpp b/src/core/horizon/filesystem/disk_file.hpp index 43414c6d..1eb10d1b 100644 --- a/src/core/horizon/filesystem/disk_file.hpp +++ b/src/core/horizon/filesystem/disk_file.hpp @@ -5,7 +5,7 @@ #define LOG_FS_ACCESS(host_path, f, ...) \ if (CONFIG_INSTANCE.GetLogFsAccess()) { \ LOG_INFO(Filesystem, "\"{}\": " f, \ - host_path PASS_VA_ARGS(__VA_ARGS__)); \ + host_path ZTD_PASS_VA_ARGS(__VA_ARGS__)); \ } namespace hydra::horizon::filesystem { diff --git a/src/core/horizon/filesystem/sparse_file.hpp b/src/core/horizon/filesystem/sparse_file.hpp index d2fe1c04..7cc4383f 100644 --- a/src/core/horizon/filesystem/sparse_file.hpp +++ b/src/core/horizon/filesystem/sparse_file.hpp @@ -86,7 +86,7 @@ class SparseFile : public IFile { for (const auto& entry : entries) { streams.push_back( {.range = - Range(entry.offset, entry.offset + entry.file->GetSize()), + ztd::Range(entry.offset, entry.offset + entry.file->GetSize()), .stream = entry.file->Open(flags)}); } diff --git a/src/core/horizon/kernel/auto_object.hpp b/src/core/horizon/kernel/auto_object.hpp index 9bfc42f8..26cd10ba 100644 --- a/src/core/horizon/kernel/auto_object.hpp +++ b/src/core/horizon/kernel/auto_object.hpp @@ -28,8 +28,8 @@ class AutoObject { reinterpret_cast(this))} {} virtual ~AutoObject() noexcept = default; - MAKE_NON_COPYABLE(AutoObject); - MAKE_NON_MOVABLE(AutoObject); + ZTD_MAKE_NON_COPYABLE(AutoObject); + ZTD_MAKE_NON_MOVABLE(AutoObject); void Retain() { ref_count.fetch_add(1, std::memory_order_relaxed); } diff --git a/src/core/horizon/kernel/const.hpp b/src/core/horizon/kernel/const.hpp index d5a556d1..0069126f 100644 --- a/src/core/horizon/kernel/const.hpp +++ b/src/core/horizon/kernel/const.hpp @@ -5,14 +5,18 @@ namespace hydra::horizon::kernel { constexpr handle_id_t CURRENT_PROCESS_PSEUDO_HANDLE = 0xffff8001; constexpr handle_id_t CURRENT_THREAD_PSEUDO_HANDLE = 0xffff8000; -constexpr Range ADDRESS_SPACE = - Range(0x10000000, 0x200000000); -constexpr Range STACK_REGION = Range(0x10000000, 0x20000000); -constexpr Range TLS_REGION = Range(0x20000000, 0x30000000); -constexpr Range ALIAS_REGION = Range(0x30000000, 0x40000000); -constexpr Range EXECUTABLE_REGION = - Range(0x40000000, 0x80000000); -constexpr Range HEAP_REGION = Range(0x100000000, 0x200000000); +constexpr ztd::Range ADDRESS_SPACE = + ztd::Range(0x10000000, 0x200000000); +constexpr ztd::Range STACK_REGION = + ztd::Range(0x10000000, 0x20000000); +constexpr ztd::Range TLS_REGION = + ztd::Range(0x20000000, 0x30000000); +constexpr ztd::Range ALIAS_REGION = + ztd::Range(0x30000000, 0x40000000); +constexpr ztd::Range EXECUTABLE_REGION = + ztd::Range(0x40000000, 0x80000000); +constexpr ztd::Range HEAP_REGION = + ztd::Range(0x100000000, 0x200000000); constexpr u64 HEAP_MEM_ALIGNMENT = 0x200000; @@ -288,7 +292,7 @@ using result_t = u32; (static_cast(description) & 0x1fff) << 9) #define GET_RESULT_MODULE(result) \ - static_cast<::hydra::horizon::kernel::Module>((result)&0x1ff) + static_cast<::hydra::horizon::kernel::Module>((result) & 0x1ff) #define GET_RESULT_DESCRIPTION(result) ((result) >> 9) @@ -326,24 +330,24 @@ enum class MemoryType : u32 { enum class MemoryAttribute : u32 { None = 0, - Locked = BIT(0), - IpcLocked = BIT(1), - DeviceShared = BIT(2), - Uncached = BIT(3), + Locked = ZTD_BIT(0), + IpcLocked = ZTD_BIT(1), + DeviceShared = ZTD_BIT(2), + Uncached = ZTD_BIT(3), }; -ENABLE_ENUM_BITWISE_OPERATORS(MemoryAttribute) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(MemoryAttribute) enum class MemoryPermission : u32 { None = 0x0, - Read = BIT(0), - Write = BIT(1), - Execute = BIT(2), + Read = ZTD_BIT(0), + Write = ZTD_BIT(1), + Execute = ZTD_BIT(2), ReadWrite = Read | Write, ReadExecute = Read | Execute, ReadWriteExecute = Read | Write | Execute, - DontCare = BIT(28), + DontCare = ZTD_BIT(28), }; -ENABLE_ENUM_BITWISE_OPERATORS(MemoryPermission) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(MemoryPermission) struct MemoryState { MemoryType type; diff --git a/src/core/horizon/kernel/kernel.cpp b/src/core/horizon/kernel/kernel.cpp index be49782f..93186832 100644 --- a/src/core/horizon/kernel/kernel.cpp +++ b/src/core/horizon/kernel/kernel.cpp @@ -363,7 +363,7 @@ result_t Kernel::SetHeapSize(Process* crnt_process, u64 size, uptr& out_base) { crnt_process->ResizeHeap(size); - out_base = HEAP_REGION.GetBegin(); + out_base = HEAP_REGION.getBegin(); return RESULT_SUCCESS; } @@ -392,7 +392,7 @@ result_t Kernel::SetMemoryAttribute(Process* crnt_process, vaddr_t addr, addr, size, mask, value); crnt_process->GetMmu()->SetMemoryAttribute( - Range::FromSize(addr, size), mask, value); + ztd::Range::fromSize(addr, size), mask, value); return RESULT_SUCCESS; } @@ -405,7 +405,7 @@ result_t Kernel::MapMemory(Process* crnt_process, uptr dst_addr, uptr src_addr, dst_addr, src_addr, size); crnt_process->GetMmu()->Map(dst_addr, - Range::FromSize(src_addr, size)); + ztd::Range::fromSize(src_addr, size)); return RESULT_SUCCESS; } @@ -421,7 +421,8 @@ result_t Kernel::UnmapMemory(Process* crnt_process, uptr dst_addr, // TODO: verify that src_addr is the same as the one used in MapMemory? (void)src_addr; - crnt_process->GetMmu()->Unmap(Range::FromSize(dst_addr, size)); + crnt_process->GetMmu()->Unmap( + ztd::Range::fromSize(dst_addr, size)); return RESULT_SUCCESS; } @@ -577,7 +578,7 @@ result_t Kernel::MapSharedMemory(Process* crnt_process, SharedMemory* shmem, shmem->GetDebugName(), addr, size, perm); shmem->MapToRange(crnt_process->GetMmu(), - Range(addr, static_cast(addr + size)), perm); + ztd::Range(addr, static_cast(addr + size)), perm); return RESULT_SUCCESS; } @@ -591,7 +592,7 @@ result_t Kernel::UnmapSharedMemory(Process* crnt_process, SharedMemory* shmem, "0x{:08x})", shmem->GetDebugName(), addr, size); - crnt_process->GetMmu()->Unmap(Range::FromSize(addr, size)); + crnt_process->GetMmu()->Unmap(ztd::Range::fromSize(addr, size)); return RESULT_SUCCESS; } @@ -609,16 +610,13 @@ result_t Kernel::CreateTransferMemory(uptr addr, u64 size, } result_t Kernel::CloseHandle(Process* crnt_process, handle_id_t handle_id) { - auto obj = crnt_process->GetHandle(handle_id); - if (obj == nullptr) { - LOG_WARN(Kernel, "CloseHandle called (INVALID_HANDLE)"); + LOG_DEBUG(Kernel, "CloseHandle called (handle: {:#x})", handle_id); + + if (crnt_process->FreeHandle(handle_id)) { + return RESULT_SUCCESS; + } else { return MAKE_RESULT(Svc, Error::InvalidHandle); } - - LOG_DEBUG(Kernel, "CloseHandle called (handle: {})", obj->GetDebugName()); - - crnt_process->FreeHandle(handle_id); - return RESULT_SUCCESS; } // TODO: can only be ReadableEvent or Process? @@ -779,7 +777,8 @@ result_t Kernel::WaitProcessWideKeyAtomic(Process* crnt_process, { CriticalSectionLock cs_lock(*this); - cond_var_waiters.AddLast(crnt_thread); + ASSERT_DEBUG(cond_var_waiters.addLast(crnt_thread).has_value(), Kernel, + "Failed to add cond var waiter"); UnlockMutex(crnt_thread, mutex_addr); } @@ -801,13 +800,13 @@ result_t Kernel::WaitProcessWideKeyAtomic(Process* crnt_process, CriticalSectionLock cs_lock(*this); // Cond var - cond_var_waiters.Remove(crnt_thread); + cond_var_waiters.remove(crnt_thread); // Mutex auto owner = GetMutexOwner( - crnt_process, static_cast(crnt_thread->mutex_wait_addr)); - if (owner != nullptr) - owner->RemoveMutexWaiter(crnt_thread); + crnt_process, reinterpret_cast(crnt_thread->mutex_wait_addr)); + if (owner.has_value()) + owner.value()->RemoveMutexWaiter(crnt_thread); } return res; @@ -821,19 +820,20 @@ result_t Kernel::SignalProcessWideKey(Process* crnt_process, uptr addr, CriticalSectionLock cs_lock(*this); if (count == -1) - count = static_cast(cond_var_waiters.GetSize()); + count = static_cast(cond_var_waiters.getSize()); // TODO: sort by priority - for (auto thread_node = cond_var_waiters.GetHead(); - (thread_node != nullptr) && count > 0;) { - const auto thread = thread_node->Get(); + for (auto thread_node = cond_var_waiters.getHead(); + thread_node.has_value() && count > 0;) { + const auto thread_node_ = thread_node.value(); + const auto thread = thread_node_->get(); if (thread->cond_var_wait_addr == addr) { thread->cond_var_wait_addr = 0x0; TryAcquireMutex(crnt_process, thread); - thread_node = cond_var_waiters.Remove(thread_node); + thread_node = cond_var_waiters.remove(thread_node_); count--; } else { - thread_node = thread_node->GetNext(); + thread_node = thread_node_->getNext(); } } @@ -967,16 +967,16 @@ result_t Kernel::GetInfo(Process* crnt_process, InfoType info_type, out_info = 0xf; return RESULT_SUCCESS; case InfoType::AliasRegionAddress: - out_info = ALIAS_REGION.GetBegin(); + out_info = ALIAS_REGION.getBegin(); return RESULT_SUCCESS; case InfoType::AliasRegionSize: - out_info = ALIAS_REGION.GetSize(); + out_info = ALIAS_REGION.getSize(); return RESULT_SUCCESS; case InfoType::HeapRegionAddress: - out_info = HEAP_REGION.GetBegin(); + out_info = HEAP_REGION.getBegin(); return RESULT_SUCCESS; case InfoType::HeapRegionSize: - out_info = HEAP_REGION.GetSize(); + out_info = HEAP_REGION.getSize(); return RESULT_SUCCESS; case InfoType::TotalMemorySize: // TODO: what should this be? @@ -1004,16 +1004,16 @@ result_t Kernel::GetInfo(Process* crnt_process, InfoType info_type, out_info = crnt_process->GetRandomEntropy()[info_sub_type]; return RESULT_SUCCESS; case InfoType::AslrRegionAddress: - out_info = ADDRESS_SPACE.GetBegin(); + out_info = ADDRESS_SPACE.getBegin(); return RESULT_SUCCESS; case InfoType::AslrRegionSize: - out_info = ADDRESS_SPACE.GetSize(); + out_info = ADDRESS_SPACE.getSize(); return RESULT_SUCCESS; case InfoType::StackRegionAddress: - out_info = STACK_REGION.GetBegin(); + out_info = STACK_REGION.getBegin(); return RESULT_SUCCESS; case InfoType::StackRegionSize: - out_info = STACK_REGION.GetSize(); + out_info = STACK_REGION.getSize(); return RESULT_SUCCESS; case InfoType::TotalSystemResourceSize: { out_info = crnt_process->GetSystemResourceSize(); @@ -1069,7 +1069,7 @@ result_t Kernel::MapPhysicalMemory(Process* crnt_process, vaddr_t addr, if (!is_aligned(size, hw::tegra_x1::cpu::GUEST_PAGE_SIZE)) return MAKE_RESULT(Svc, 101); // Invalid size - if (!ALIAS_REGION.Contains(Range::FromSize(addr, size))) + if (!ALIAS_REGION.contains(ztd::Range::fromSize(addr, size))) return MAKE_RESULT(Svc, 110); // Invalid memory region auto mem = system.GetCpu().AllocateMemory(size); @@ -1139,7 +1139,8 @@ result_t Kernel::WaitForAddress(IThread* crnt_thread, uptr addr, crnt_thread->Pause(); crnt_thread->mutex_wait_addr = addr; - arbiters.AddLast(crnt_thread); + ASSERT_DEBUG(arbiters.addLast(crnt_thread).has_value(), Kernel, + "Failed to add arbiter"); } } @@ -1163,7 +1164,7 @@ result_t Kernel::WaitForAddress(IThread* crnt_thread, uptr addr, /* { CriticalSectionLock cs_lock(*this); - arbiters.Remove(crnt_thread); + arbiters.remove(crnt_thread); } */ @@ -1187,15 +1188,16 @@ result_t Kernel::SignalToAddress(uptr addr, SignalType signal_type, u32 value, (void)count; CriticalSectionLock cs_lock(*this); - for (auto waiter_node = arbiters.GetHead(); waiter_node != nullptr;) { - auto waiter = waiter_node->Get(); + for (auto waiter_node = arbiters.getHead(); waiter_node.has_value();) { + const auto waiter_node_ = waiter_node.value(); + auto waiter = waiter_node_->get(); if (waiter->mutex_wait_addr != addr) { - waiter_node = waiter_node->GetNext(); + waiter_node = waiter_node_->getNext(); continue; } waiter->Resume(); - waiter_node = arbiters.Remove(waiter_node); + waiter_node = arbiters.remove(waiter_node_); } return RESULT_SUCCESS; @@ -1344,7 +1346,7 @@ result_t Kernel::MapProcessMemory(Process* crnt_process, vaddr_t dst_addr, // TODO: correct? const auto ptr = process->GetMmu()->UnmapAddr(src_addr); - crnt_process->GetMmu()->Map(dst_addr, Range::FromSize(ptr, size), + crnt_process->GetMmu()->Map(dst_addr, ztd::Range::fromSize(ptr, size), {}); // TODO: state return RESULT_SUCCESS; @@ -1357,7 +1359,8 @@ result_t Kernel::MapProcessCodeMemory(Process* process, vaddr_t dst_addr, "src_addr: 0x{:08x}, size: {})", process->GetDebugName(), dst_addr, src_addr, size); - process->GetMmu()->Map(dst_addr, Range::FromSize(src_addr, size)); + process->GetMmu()->Map(dst_addr, + ztd::Range::fromSize(src_addr, size)); return RESULT_SUCCESS; } @@ -1372,7 +1375,7 @@ result_t Kernel::UnmapProcessCodeMemory(Process* process, vaddr_t dst_addr, // TODO: verify that src_addr is the same as the one used in MapMemory? (void)src_addr; - process->GetMmu()->Unmap(Range::FromSize(dst_addr, size)); + process->GetMmu()->Unmap(ztd::Range::fromSize(dst_addr, size)); return RESULT_SUCCESS; } @@ -1400,7 +1403,7 @@ void Kernel::TryAcquireMutex(Process* crnt_process, IThread* thread) { } // Register this thread as a waiter by the owner - auto owner = GetMutexOwner(crnt_process, value); + auto owner = GetMutexOwner(crnt_process, value).value(); owner->AddMutexWaiter(thread); } diff --git a/src/core/horizon/kernel/kernel.hpp b/src/core/horizon/kernel/kernel.hpp index 948ac1e2..586c0ae8 100644 --- a/src/core/horizon/kernel/kernel.hpp +++ b/src/core/horizon/kernel/kernel.hpp @@ -158,8 +158,8 @@ class Kernel { std::mutex critical_section_mutex; // Sync - DoubleLinkedList cond_var_waiters; - DoubleLinkedList arbiters; + ztd::DoublyLinkedList cond_var_waiters; + ztd::DoublyLinkedList arbiters; // Applet resource std::array free_applet_resource_user_ids = { diff --git a/src/core/horizon/kernel/process.cpp b/src/core/horizon/kernel/process.cpp index dd71705f..c0c32875 100644 --- a/src/core/horizon/kernel/process.cpp +++ b/src/core/horizon/kernel/process.cpp @@ -31,8 +31,9 @@ Process::~Process() { DEBUGGER_MANAGER_INSTANCE.DetachDebugger(this); } -uptr Process::CreateMemory(Range region, u64 size, MemoryType type, - MemoryPermission perm, vaddr_t& out_base) { +uptr Process::CreateMemory(ztd::Range region, u64 size, + MemoryType type, MemoryPermission perm, + vaddr_t& out_base) { out_base = mmu->FindFreeMemory(region, size); ASSERT(out_base != 0x0, Kernel, "Failed to find free memory"); @@ -53,26 +54,26 @@ uptr Process::CreateExecutableMemory(const std::string_view module_name, // Protect mmu->Protect( - Range::FromSize( - out_base + code_set.code.GetBegin(), - align(code_set.code.GetSize(), hw::tegra_x1::cpu::GUEST_PAGE_SIZE)), + ztd::Range::fromSize( + out_base + code_set.code.getBegin(), + align(code_set.code.getSize(), hw::tegra_x1::cpu::GUEST_PAGE_SIZE)), MemoryPermission::ReadExecute); // mmu->Protect( - // Range::FromSize(out_base + code_set.ro_data.GetBegin(), + // ztd::Range::fromSize(out_base + code_set.ro_data.getBegin(), // align(code_set.ro_data.GetSize(), // hw::tegra_x1::cpu::GUEST_PAGE_SIZE)), // MemoryPermission::Read); mmu->Protect( - Range::FromSize( - out_base + code_set.data.GetBegin(), - align(code_set.data.GetSize(), hw::tegra_x1::cpu::GUEST_PAGE_SIZE)), + ztd::Range::fromSize( + out_base + code_set.data.getBegin(), + align(code_set.data.getSize(), hw::tegra_x1::cpu::GUEST_PAGE_SIZE)), MemoryPermission::ReadWrite); // Debug DEBUGGER_MANAGER_INSTANCE.GetDebugger(this).GetModuleTable().RegisterSymbol( {.name = std::string(module_name), .guest_mem_range = - Range(out_base, out_base + code_set.size)}); + ztd::Range(out_base, out_base + code_set.size)}); return ptr; } @@ -94,7 +95,7 @@ void Process::CreateStackMemory(u64 stack_size) { // 0x10, priority); auto handle_id = AddHandle(main_thread); main_thread_stack_mem.reset(system.GetCpu().AllocateMemory(stack_size)); - mmu->Map(STACK_REGION.GetBegin(), main_thread_stack_mem.get(), + mmu->Map(STACK_REGION.getBegin(), main_thread_stack_mem.get(), {.type = MemoryType::Stack, .attr = MemoryAttribute::None, .perm = MemoryPermission::ReadWrite}); @@ -104,12 +105,12 @@ void Process::ResizeHeap(u64 size) { if (heap_mem == nullptr) { heap_mem.reset(system.GetCpu().AllocateMemory(size)); } else { - mmu->Unmap(Range::FromSize(HEAP_REGION.GetBegin(), - heap_mem->GetSize())); + mmu->Unmap(ztd::Range::fromSize(HEAP_REGION.getBegin(), + heap_mem->GetSize())); heap_mem->Resize(size); } - mmu->Map(HEAP_REGION.GetBegin(), heap_mem.get(), + mmu->Map(HEAP_REGION.getBegin(), heap_mem.get(), {.type = MemoryType::Normal_1_0_0, .attr = MemoryAttribute::None, .perm = MemoryPermission::ReadWrite}); @@ -161,10 +162,8 @@ void Process::CleanUp() { main_thread = nullptr; } - for (handle_id_t handle_id = 1; handle_id < handle_pool.GetCapacity() + 1; - handle_id++) { - if (handle_pool.IsValid(handle_id)) - handle_pool.Get(handle_id)->Release(); + for (const auto& obj : handle_pool) { + obj->Release(); } // Signal diff --git a/src/core/horizon/kernel/process.hpp b/src/core/horizon/kernel/process.hpp index 11f8d2c3..3939de67 100644 --- a/src/core/horizon/kernel/process.hpp +++ b/src/core/horizon/kernel/process.hpp @@ -28,9 +28,9 @@ enum class ProcessState { struct CodeSet { u64 size; - Range code; - Range ro_data; - Range data; + ztd::Range code; + ztd::Range ro_data; + ztd::Range data; }; class Process : public SynchronizationObject { @@ -41,7 +41,7 @@ class Process : public SynchronizationObject { ~Process() override; // Memory - uptr CreateMemory(Range region, u64 size, MemoryType type, + uptr CreateMemory(ztd::Range region, u64 size, MemoryType type, MemoryPermission perm, vaddr_t& out_base); uptr CreateExecutableMemory(const std::string_view module_name, CodeSet code_set, vaddr_t& out_base); @@ -85,50 +85,65 @@ class Process : public SynchronizationObject { // Handles template - T* GetHandle(handle_id_t handle_id) { + // TODO: uncomment + /*std::optional*/ T* GetHandle(handle_id_t handle_id) { static_assert(std::is_base_of_v, "T must be derived from AutoObject"); if (handle_id == INVALID_HANDLE_ID) - return nullptr; - - AutoObject* obj; - if (handle_id == CURRENT_PROCESS_PSEUDO_HANDLE) [[unlikely]] { - obj = this; - } else if (handle_id == CURRENT_THREAD_PSEUDO_HANDLE) [[unlikely]] { - obj = tls_current_thread; - } else { - if (!handle_pool.IsValid(handle_id)) - return nullptr; - - obj = handle_pool.Get(handle_id); + return nullptr; // std::nullopt; + + if constexpr (std::is_base_of_v) { + if (handle_id == CURRENT_PROCESS_PSEUDO_HANDLE) [[unlikely]] { + return this; + } + } + + if constexpr (std::is_base_of_v) { + if (handle_id == CURRENT_THREAD_PSEUDO_HANDLE) [[unlikely]] { + return tls_current_thread; + } } - return static_cast(obj); + // HACK + return handle_pool.get(handle_id) + .transform( + [](AutoObject* obj) -> auto { return static_cast(obj); }) + .value_or(nullptr); } handle_id_t AddHandleNoRetain(AutoObject* obj) { + // TODO: remove if (obj == nullptr) [[unlikely]] return INVALID_HANDLE_ID; - return handle_pool.Insert(obj); + return handle_pool.insert(obj).value_or(INVALID_HANDLE_ID); } handle_id_t AddHandle(AutoObject* obj) { + // TODO: remove if (obj == nullptr) [[unlikely]] return INVALID_HANDLE_ID; obj->Retain(); - return handle_pool.Insert(obj); + return handle_pool.insert(obj).value_or(INVALID_HANDLE_ID); } - void FreeHandle(handle_id_t handle_id) { + bool FreeHandle(handle_id_t handle_id) { ASSERT_DEBUG(handle_id != CURRENT_PROCESS_PSEUDO_HANDLE, Kernel, "Cannot free current process handle"); ASSERT_DEBUG(handle_id != CURRENT_THREAD_PSEUDO_HANDLE, Kernel, "Cannot free current thread handle"); - handle_pool.Get(handle_id)->Release(); - handle_pool.Free(handle_id); + const auto object = handle_pool.get(handle_id); + if (!object.has_value()) { + LOG_WARN(Kernel, "Invalid handle {:#x}", handle_id); + return false; + } + + object.value()->Release(); + ASSERT_DEBUG(handle_pool.free(handle_id), Kernel, + "Failed to free handle {:#x}", handle_id); + return true; } hw::tegra_x1::cpu::IMmu* GetMmu() const { return mmu.get(); } @@ -153,7 +168,7 @@ class Process : public SynchronizationObject { std::unique_ptr main_thread_stack_mem; std::unique_ptr heap_mem; - vaddr_t tls_mem_base{TLS_REGION.GetBegin()}; + vaddr_t tls_mem_base{TLS_REGION.getBegin()}; // Thread GuestThread* main_thread{nullptr}; @@ -161,7 +176,8 @@ class Process : public SynchronizationObject { std::vector threads; // Handles - StaticPool + // TODO: store as strong refs + ztd::mem::StaticPool handle_pool; // TODO: get the size from capabilities std::atomic state{ProcessState::Created}; diff --git a/src/core/horizon/kernel/shared_memory.cpp b/src/core/horizon/kernel/shared_memory.cpp index 40eadb7f..a712921b 100644 --- a/src/core/horizon/kernel/shared_memory.cpp +++ b/src/core/horizon/kernel/shared_memory.cpp @@ -14,8 +14,8 @@ SharedMemory::SharedMemory(hw::tegra_x1::cpu::ICpu& cpu, u64 size, SharedMemory::~SharedMemory() { delete memory; } void SharedMemory::MapToRange(hw::tegra_x1::cpu::IMmu* mmu, - const Range range, MemoryPermission perm) { - mmu->Map(range.GetBegin(), memory, + const ztd::Range range, MemoryPermission perm) { + mmu->Map(range.getBegin(), memory, {.type = MemoryType::Shared, .attr = MemoryAttribute::None, .perm = perm}); diff --git a/src/core/horizon/kernel/shared_memory.hpp b/src/core/horizon/kernel/shared_memory.hpp index 69a27b91..f1b191e8 100644 --- a/src/core/horizon/kernel/shared_memory.hpp +++ b/src/core/horizon/kernel/shared_memory.hpp @@ -19,7 +19,7 @@ class SharedMemory : public AutoObject { std::string_view debug_name = "SharedMemory"); ~SharedMemory() override; - void MapToRange(hw::tegra_x1::cpu::IMmu* mmu, const Range range_, + void MapToRange(hw::tegra_x1::cpu::IMmu* mmu, const ztd::Range range_, MemoryPermission perm); // Getters diff --git a/src/core/horizon/kernel/strong_ref.hpp b/src/core/horizon/kernel/strong_ref.hpp index 283682dc..833cd04e 100644 --- a/src/core/horizon/kernel/strong_ref.hpp +++ b/src/core/horizon/kernel/strong_ref.hpp @@ -8,26 +8,20 @@ class StrongRef { "T must derive from AutoObject"); public: - StrongRef(T* obj_) : obj{obj_} { obj->Retain(); } + StrongRef(T* obj_) noexcept : obj{obj_} { obj->Retain(); } template - StrongRef(Args&&... args) : obj{new T(std::forward(args)...)} {} - - StrongRef(const StrongRef& other) : obj{other.obj} { obj->Retain(); } + StrongRef(Args&&... args) noexcept + : obj{new T(std::forward(args)...)} {} ~StrongRef() { obj->Release(); } - StrongRef& operator=(const StrongRef& other) = delete; - - T* operator T*() const { return obj; } + ZTD_MAKE_NON_COPYABLE(StrongRef); + ZTD_MAKE_DEFAULT_MOVABLE(StrongRef); + T* operator*() const { return obj; } T* operator->() const { return obj; } - T* GetRetained() const { - obj->Retain(); - return obj; - } - private: T* obj; diff --git a/src/core/horizon/kernel/synchronization_object.cpp b/src/core/horizon/kernel/synchronization_object.cpp index 2e1c35a4..6c54c41c 100644 --- a/src/core/horizon/kernel/synchronization_object.cpp +++ b/src/core/horizon/kernel/synchronization_object.cpp @@ -6,18 +6,21 @@ namespace hydra::horizon::kernel { void SynchronizationObject::AddWaitingThread(IThread* thread) { std::scoped_lock lock(mutex); - if (signalled) + if (signalled) { thread->Resume(this); - else - waiting_threads.AddFirst(thread); + } else { + ASSERT_DEBUG(waiting_threads.addFirst(thread).has_value(), Kernel, + "Fail to add waiting thread"); + } } void SynchronizationObject::RemoveWaitingThread(IThread* thread) { std::scoped_lock lock(mutex); - waiting_threads.Remove(thread); + waiting_threads.remove(thread); } -void SynchronizationObject::AddSignalCallback(const signal_callback_fn_t& callback) { +void SynchronizationObject::AddSignalCallback( + const signal_callback_fn_t& callback) { std::scoped_lock lock(mutex); if (signalled) callback(); @@ -32,10 +35,12 @@ void SynchronizationObject::Signal() { signalled = true; - for (auto waiting_thread = waiting_threads.GetHead(); - waiting_thread != nullptr; waiting_thread = waiting_thread->GetNext()) - waiting_thread->Get()->Resume(this); - waiting_threads.Clear(); + for (auto waiting_thread = waiting_threads.getHead(); + waiting_thread.has_value(); + waiting_thread = waiting_thread.value()->getNext()) { + waiting_thread.value()->get()->Resume(this); + } + waiting_threads.clear(); for (auto& callback : signal_callbacks) callback(); diff --git a/src/core/horizon/kernel/synchronization_object.hpp b/src/core/horizon/kernel/synchronization_object.hpp index 00a5907f..db17018c 100644 --- a/src/core/horizon/kernel/synchronization_object.hpp +++ b/src/core/horizon/kernel/synchronization_object.hpp @@ -23,7 +23,7 @@ class SynchronizationObject : public AutoObject { private: std::mutex mutex; - DoubleLinkedList waiting_threads; + ztd::DoublyLinkedList waiting_threads; std::vector signal_callbacks; bool signalled{false}; }; diff --git a/src/core/horizon/kernel/thread.cpp b/src/core/horizon/kernel/thread.cpp index 5d192c98..50c50c22 100644 --- a/src/core/horizon/kernel/thread.cpp +++ b/src/core/horizon/kernel/thread.cpp @@ -108,12 +108,13 @@ bool IThread::ProcessMessagesImpl() { void IThread::AddMutexWaiter(IThread* waiter) { std::scoped_lock lock(mutex_wait_mutex); - mutex_wait_list.AddLast(waiter); + ASSERT_DEBUG(mutex_wait_list.addLast(waiter).has_value(), Kernel, + "Failed to add mutex waiter"); } void IThread::RemoveMutexWaiter(IThread* waiter) { std::scoped_lock lock(mutex_wait_mutex); - mutex_wait_list.Remove(waiter); + mutex_wait_list.remove(waiter); } IThread* IThread::RelinquishMutex(uptr mutex_addr, u32& out_waiter_count) { @@ -122,15 +123,16 @@ IThread* IThread::RelinquishMutex(uptr mutex_addr, u32& out_waiter_count) { // Find a new owner IThread* new_owner = nullptr; out_waiter_count = 0; - for (auto waiter_node = mutex_wait_list.GetHead(); - waiter_node != nullptr;) { - auto waiter = waiter_node->Get(); + for (auto waiter_node = mutex_wait_list.getHead(); + waiter_node.has_value();) { + const auto waiter_node_ = waiter_node.value(); + auto waiter = waiter_node_->get(); if (waiter->mutex_wait_addr != mutex_addr) { - waiter_node = waiter_node->GetNext(); + waiter_node = waiter_node_->getNext(); continue; } - waiter_node = mutex_wait_list.Remove(waiter_node); + waiter_node = mutex_wait_list.remove(waiter_node_); if (new_owner != nullptr) { new_owner->AddMutexWaiter(waiter); out_waiter_count++; @@ -143,8 +145,16 @@ IThread* IThread::RelinquishMutex(uptr mutex_addr, u32& out_waiter_count) { return new_owner; } -IThread* GetMutexOwner(Process* process, u32 mutex) { - return process->GetHandle(mutex & ~MUTEX_WAIT_MASK); +std::optional GetMutexOwner(Process* process, u32 mutex) { + // HACK + const auto thread = process->GetHandle(mutex & ~MUTEX_WAIT_MASK); + return (thread != nullptr ? std::make_optional(thread) : std::nullopt); +} + +std::optional GetMutexOwner(Process* process, u32* mutex_ptr) { + if (mutex_ptr == nullptr) + return std::nullopt; + return GetMutexOwner(process, atomic_load(mutex_ptr)); } } // namespace hydra::horizon::kernel diff --git a/src/core/horizon/kernel/thread.hpp b/src/core/horizon/kernel/thread.hpp index 706355cc..8c24eff7 100644 --- a/src/core/horizon/kernel/thread.hpp +++ b/src/core/horizon/kernel/thread.hpp @@ -117,7 +117,7 @@ class IThread : public SynchronizationObject { mutex_wait_addr = 0x0; cond_var_wait_addr = 0x0; cond_var_wait_addr = 0x0; - mutex_wait_list.Clear(); + mutex_wait_list.clear(); supervisor_pause = false; guest_pause = false; } @@ -136,7 +136,7 @@ class IThread : public SynchronizationObject { u32 self_handle_for_mutex{0x0}; uptr cond_var_wait_addr{0x0}; std::mutex mutex_wait_mutex; - DoubleLinkedList mutex_wait_list; + ztd::DoublyLinkedList mutex_wait_list; // Synchronization bool supervisor_pause{false}; @@ -163,9 +163,7 @@ class IThread : public SynchronizationObject { inline thread_local IThread* tls_current_thread = nullptr; -IThread* GetMutexOwner(Process* process, u32 mutex); -inline IThread* GetMutexOwner(Process* process, u32* mutex_ptr) { - return GetMutexOwner(process, atomic_load(mutex_ptr)); -} +std::optional GetMutexOwner(Process* process, u32 mutex); +std::optional GetMutexOwner(Process* process, u32* mutex_ptr); } // namespace hydra::horizon::kernel diff --git a/src/core/horizon/loader/homebrew_loader.cpp b/src/core/horizon/loader/homebrew_loader.cpp index fe6d66fd..9c03930a 100644 --- a/src/core/horizon/loader/homebrew_loader.cpp +++ b/src/core/horizon/loader/homebrew_loader.cpp @@ -35,7 +35,7 @@ enum class ConfigEntryType : u32 { enum class ConfigEntryFlag : u32 { None = 0, - IsMandatory = BIT(0), + IsMandatory = ZTD_BIT(0), }; struct ConfigEntry { @@ -50,7 +50,7 @@ class HomebrewThread : public kernel::GuestThread { HomebrewThread(System& system_, kernel::Process* process, std::string_view path_) : kernel::GuestThread(system_, process, - kernel::STACK_REGION.GetBegin() + + kernel::STACK_REGION.getBegin() + STACK_MEMORY_SIZE - 0x10, 0x2c, "Homebrew thread"), system{system_}, path{path_} {} @@ -176,11 +176,11 @@ class HomebrewThread : public kernel::GuestThread { ADD_ENTRY_OPTIONAL(RandomSeed, gen(), gen()); ADD_ENTRY_OPTIONAL(UserIdStorage, state_base + USER_ID_STORAGE_OFFSET, 0); - ADD_ENTRY_OPTIONAL(HosVersion, - BIT(31) | (FIRMWARE_VERSION.major << 16) | - (FIRMWARE_VERSION.minor << 8) | - FIRMWARE_VERSION.micro, - 0x41544d4f53504852ul); // "ATMOSPHR" + ADD_ENTRY_OPTIONAL( + HosVersion, + ZTD_BIT(31) | (FIRMWARE_VERSION.major << 16) | + (FIRMWARE_VERSION.minor << 8) | FIRMWARE_VERSION.micro, + 0x41544d4f53504852ul); // "ATMOSPHR" ADD_ENTRY_OPTIONAL(EndOfList, state_base + NOTICE_TEXT_OFFSET, sizeof(NOTICE_TEXT)); diff --git a/src/core/horizon/loader/loader.hpp b/src/core/horizon/loader/loader.hpp index 3f15b3e3..421986a9 100644 --- a/src/core/horizon/loader/loader.hpp +++ b/src/core/horizon/loader/loader.hpp @@ -27,8 +27,8 @@ class ILoader { ILoader() noexcept = default; virtual ~ILoader() noexcept = default; - MAKE_NON_COPYABLE(ILoader); - MAKE_DEFAULT_MOVABLE(ILoader); + ZTD_MAKE_NON_COPYABLE(ILoader); + ZTD_MAKE_DEFAULT_MOVABLE(ILoader); virtual u64 GetTitleID() const { return invalid(); } diff --git a/src/core/horizon/loader/npdm.hpp b/src/core/horizon/loader/npdm.hpp index c5fb4e15..7b746a0a 100644 --- a/src/core/horizon/loader/npdm.hpp +++ b/src/core/horizon/loader/npdm.hpp @@ -4,17 +4,17 @@ namespace hydra::horizon::loader { enum class NpdmFlags : u8 { None = 0, - Is64BitInstruction = BIT(0), + Is64BitInstruction = ZTD_BIT(0), AddressSpace32Bit = 0x0 << 1, AddressSpace64BitOld = 0x1 << 1, AddressSpace32BitNoReserved = 0x2 << 1, AddressSpace64Bit = 0x3 << 1, - OptimizeMemoryAllocation = BIT(4), // 7.0.0+ - DisableDeviceAddressSpaceMerge = BIT(5), // 11.0.0+ - EnableAliasRegionExtraSize = BIT(6), // 18.0.0+ - PreventCodeReads = BIT(7), // 19.0.0+ + OptimizeMemoryAllocation = ZTD_BIT(4), // 7.0.0+ + DisableDeviceAddressSpaceMerge = ZTD_BIT(5), // 11.0.0+ + EnableAliasRegionExtraSize = ZTD_BIT(6), // 18.0.0+ + PreventCodeReads = ZTD_BIT(7), // 19.0.0+ }; -ENABLE_ENUM_BITWISE_OPERATORS(NpdmFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(NpdmFlags) struct NpdmMeta { u32 magic; diff --git a/src/core/horizon/loader/nro_loader.cpp b/src/core/horizon/loader/nro_loader.cpp index ec1c16ce..2b8ed970 100644 --- a/src/core/horizon/loader/nro_loader.cpp +++ b/src/core/horizon/loader/nro_loader.cpp @@ -70,9 +70,9 @@ void NroLoader::LoadProcess(System& system, kernel::Process* process) { // TODO: is the size correct? const auto set = kernel::CodeSet{ .size=GetExecutableSize() + 0x1000, // HACK: one extra page - .code=Range::FromSize(sections[0].offset, sections[0].size), - .ro_data=Range::FromSize(sections[1].offset, sections[1].size), - .data=Range::FromSize(sections[2].offset, sections[2].size)}; + .code=ztd::Range::fromSize(sections[0].offset, sections[0].size), + .ro_data=ztd::Range::fromSize(sections[1].offset, sections[1].size), + .data=ztd::Range::fromSize(sections[2].offset, sections[2].size)}; // TODO: module name executable_ptr = process->CreateExecutableMemory("main.nro", set, executable_base); diff --git a/src/core/horizon/loader/nso_loader.cpp b/src/core/horizon/loader/nso_loader.cpp index 7e73c000..3d2a4299 100644 --- a/src/core/horizon/loader/nso_loader.cpp +++ b/src/core/horizon/loader/nso_loader.cpp @@ -1,6 +1,5 @@ #include "core/horizon/loader/nso_loader.hpp" -#include "common/lz4.hpp" #include "core/debugger/debugger_manager.hpp" #include "core/horizon/kernel/kernel.hpp" #include "core/horizon/kernel/process.hpp" @@ -13,14 +12,14 @@ namespace { enum class NsoFlags : u32 { None = 0, - TextCompressed = BIT(0), - RoCompressed = BIT(1), - DataCompressed = BIT(2), - TextHash = BIT(3), - RoHash = BIT(4), - DataHash = BIT(5), + TextCompressed = ZTD_BIT(0), + RoCompressed = ZTD_BIT(1), + DataCompressed = ZTD_BIT(2), + TextHash = ZTD_BIT(3), + RoHash = ZTD_BIT(4), + DataHash = ZTD_BIT(5), }; -ENABLE_ENUM_BITWISE_OPERATORS(NsoFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(NsoFlags) struct NsoHeader { u32 magic; @@ -61,10 +60,10 @@ void read_segment(io::IStream* stream, uptr executable_mem_ptr, // Decompress std::vector file(file_size); stream->ReadToSpan(std::span(file)); - DecompressLZ4(file, - std::span(reinterpret_cast(executable_mem_ptr + - segment.memory_offset), - segment.size)); + ztd::compress::decompressLz4( + file, std::span(reinterpret_cast(executable_mem_ptr + + segment.memory_offset), + segment.size)); } else { stream->ReadToSpan(std::span( reinterpret_cast(executable_mem_ptr + segment.memory_offset), @@ -140,12 +139,12 @@ void NsoLoader::LoadProcess(System& system, kernel::Process* process) { // Create executable memory const auto set = kernel::CodeSet{ .size = executable_size, - .code = Range::FromSize(segments[0].seg.memory_offset, - segments[0].seg.size), - .ro_data = Range::FromSize(segments[1].seg.memory_offset, - segments[1].seg.size), - .data = Range::FromSize(segments[2].seg.memory_offset, - segments[2].seg.size)}; + .code = ztd::Range::fromSize(segments[0].seg.memory_offset, + segments[0].seg.size), + .ro_data = ztd::Range::fromSize(segments[1].seg.memory_offset, + segments[1].seg.size), + .data = ztd::Range::fromSize(segments[2].seg.memory_offset, + segments[2].seg.size)}; vaddr_t base; auto ptr = process->CreateExecutableMemory(name, set, base); LOG_DEBUG(Loader, "Base: 0x{:08x}, size: 0x{:08x}", base, executable_size); @@ -210,7 +209,7 @@ void NsoLoader::LoadProcess(System& system, kernel::Process* process) { DEBUGGER_MANAGER_INSTANCE.GetDebugger(process) .GetFunctionTable() .RegisterSymbol({.name = demangle(std::string(symbol_name)), - .guest_mem_range = Range( + .guest_mem_range = ztd::Range( base + symbol.st_value, base + symbol.st_value + symbol.st_size)}); } @@ -225,7 +224,7 @@ void NsoLoader::LoadProcess(System& system, kernel::Process* process) { // Main thread auto main_thread = new kernel::GuestThread( system, process, - kernel::STACK_REGION.GetBegin() + main_thread_stack_size - 0x10, + kernel::STACK_REGION.getBegin() + main_thread_stack_size - 0x10, main_thread_priority); const auto main_thread_handle_id = process->SetMainThread(main_thread); diff --git a/src/core/horizon/loader/plugins/plugin.cpp b/src/core/horizon/loader/plugins/plugin.cpp index b6917d19..27048d61 100644 --- a/src/core/horizon/loader/plugins/plugin.cpp +++ b/src/core/horizon/loader/plugins/plugin.cpp @@ -176,8 +176,8 @@ Plugin::Create(const std::string& path, } // Create context - ASSIGN_OR_RETURN_ERROR(plugin.context, - plugin.CreateContext(options)); + ZTD_ASSIGN_OR_RETURN_ERROR(plugin.context, + plugin.CreateContext(options)); return plugin; }); diff --git a/src/core/horizon/loader/plugins/plugin.hpp b/src/core/horizon/loader/plugins/plugin.hpp index b2502bbd..53846106 100644 --- a/src/core/horizon/loader/plugins/plugin.hpp +++ b/src/core/horizon/loader/plugins/plugin.hpp @@ -50,7 +50,7 @@ class Plugin { Plugin() = default; ~Plugin(); - MAKE_NON_COPYABLE(Plugin); + ZTD_MAKE_NON_COPYABLE(Plugin); MAKE_MOVABLE(Plugin, library, std::exchange(other.library, nullptr), get_api_version, other.get_api_version, query, other.query, create_context, other.create_context, destroy_context, diff --git a/src/core/horizon/os.cpp b/src/core/horizon/os.cpp index 04c58a44..9b3be18a 100644 --- a/src/core/horizon/os.cpp +++ b/src/core/horizon/os.cpp @@ -164,8 +164,8 @@ OS::OS(System& system_) return s; \ }); #define REGISTER_SERVICE(server_name, service, ...) \ - FOR_EACH_2_1(REGISTER_SERVICE_CASE, &server_name##_server, service, \ - __VA_ARGS__) + ZTD_FOR_EACH_2_1(REGISTER_SERVICE_CASE, &server_name##_server, service, \ + __VA_ARGS__) // HID REGISTER_SERVICE(others, hid::IHidServer, "hid"); diff --git a/src/core/horizon/services/am/internal/library_applet_controller.hpp b/src/core/horizon/services/am/internal/library_applet_controller.hpp index 9e7d8ec9..76f2a01e 100644 --- a/src/core/horizon/services/am/internal/library_applet_controller.hpp +++ b/src/core/horizon/services/am/internal/library_applet_controller.hpp @@ -14,8 +14,8 @@ class StorageQueue { data->Release(); } - MAKE_NON_COPYABLE(StorageQueue); - MAKE_DEFAULT_MOVABLE(StorageQueue); + ZTD_MAKE_NON_COPYABLE(StorageQueue); + ZTD_MAKE_DEFAULT_MOVABLE(StorageQueue); void PushData(IStorage* data) { data->Retain(); @@ -44,8 +44,8 @@ class LibraryAppletController { interactive_out_data_event(std::make_unique( false, "Library applet interactive out data event")) {} - MAKE_NON_COPYABLE(LibraryAppletController); - MAKE_DEFAULT_MOVABLE(LibraryAppletController); + ZTD_MAKE_NON_COPYABLE(LibraryAppletController); + ZTD_MAKE_DEFAULT_MOVABLE(LibraryAppletController); // Data diff --git a/src/core/horizon/services/const.hpp b/src/core/horizon/services/const.hpp index aa955655..52a84cf1 100644 --- a/src/core/horizon/services/const.hpp +++ b/src/core/horizon/services/const.hpp @@ -12,7 +12,7 @@ result_t service::RequestImpl([[maybe_unused]] RequestContext& context, \ u32 id) { \ switch (id) { \ - FOR_EACH_1_2(SERVICE_COMMAND_CASE, service, __VA_ARGS__) \ + ZTD_FOR_EACH_1_2(SERVICE_COMMAND_CASE, service, __VA_ARGS__) \ default: \ LOG_WARN(Services, "Unknown request {}", id); \ return MAKE_RESULT(Svc, 0); /* TODO */ \ diff --git a/src/core/horizon/services/fssrv/const.hpp b/src/core/horizon/services/fssrv/const.hpp index 485eb235..933d06c3 100644 --- a/src/core/horizon/services/fssrv/const.hpp +++ b/src/core/horizon/services/fssrv/const.hpp @@ -11,10 +11,10 @@ enum class EntryType : u32 { enum class DirectoryFilterFlags { None = 0, - Directories = BIT(0), - Files = BIT(1), + Directories = ZTD_BIT(0), + Files = ZTD_BIT(1), }; -ENABLE_ENUM_BITWISE_OPERATORS(DirectoryFilterFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(DirectoryFilterFlags) enum class SaveDataType : u8 { System = 0, diff --git a/src/core/horizon/services/fssrv/filesystem.hpp b/src/core/horizon/services/fssrv/filesystem.hpp index 8ab9410a..d59c886f 100644 --- a/src/core/horizon/services/fssrv/filesystem.hpp +++ b/src/core/horizon/services/fssrv/filesystem.hpp @@ -8,9 +8,9 @@ namespace hydra::horizon::services::fssrv { enum class CreateOption : u32 { None = 0, - BigFile = BIT(0), + BigFile = ZTD_BIT(0), }; -ENABLE_ENUM_BITWISE_OPERATORS(CreateOption) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(CreateOption) struct TimeStampRaw { u64 creation_time; diff --git a/src/core/horizon/services/fssrv/filesystem_proxy.hpp b/src/core/horizon/services/fssrv/filesystem_proxy.hpp index 648a4f4e..c4e77419 100644 --- a/src/core/horizon/services/fssrv/filesystem_proxy.hpp +++ b/src/core/horizon/services/fssrv/filesystem_proxy.hpp @@ -43,10 +43,10 @@ enum class BisPartitionId : u32 { }; enum class SaveDataFlags : u32 { - KeepAfterResettingSystemSaveData = BIT(0), - KeepAfterRefurbishment = BIT(1), - KeepAfterResettingSystemSaveDataWithoutUserSaveData = BIT(2), - NeedsSecureDelete = BIT(3), + KeepAfterResettingSystemSaveData = ZTD_BIT(0), + KeepAfterRefurbishment = ZTD_BIT(1), + KeepAfterResettingSystemSaveDataWithoutUserSaveData = ZTD_BIT(2), + NeedsSecureDelete = ZTD_BIT(3), }; enum class SaveDataMetaType : u8 { diff --git a/src/core/horizon/services/hid/const.hpp b/src/core/horizon/services/hid/const.hpp index f85f397e..7b2383f6 100644 --- a/src/core/horizon/services/hid/const.hpp +++ b/src/core/horizon/services/hid/const.hpp @@ -12,20 +12,20 @@ enum class NpadRevision : u32 { }; enum class DebugPadButton : u32 { - A = BIT(0), - B = BIT(1), - X = BIT(2), - Y = BIT(3), - L = BIT(4), - R = BIT(5), - ZL = BIT(6), - ZR = BIT(7), - Start = BIT(8), - Select = BIT(9), - Left = BIT(10), - Up = BIT(11), - Right = BIT(12), - Down = BIT(13), + A = ZTD_BIT(0), + B = ZTD_BIT(1), + X = ZTD_BIT(2), + Y = ZTD_BIT(3), + L = ZTD_BIT(4), + R = ZTD_BIT(5), + ZL = ZTD_BIT(6), + ZR = ZTD_BIT(7), + Start = ZTD_BIT(8), + Select = ZTD_BIT(9), + Left = ZTD_BIT(10), + Up = ZTD_BIT(11), + Right = ZTD_BIT(12), + Down = ZTD_BIT(13), }; enum class TouchScreenModeForNx : u32 { @@ -35,11 +35,11 @@ enum class TouchScreenModeForNx : u32 { }; enum class MouseButton : u32 { - Left = BIT(0), - Right = BIT(1), - Middle = BIT(2), - Forward = BIT(3), - Back = BIT(4), + Left = ZTD_BIT(0), + Right = ZTD_BIT(1), + Middle = ZTD_BIT(2), + Forward = ZTD_BIT(3), + Back = ZTD_BIT(4), }; enum class KeyboardKey : u32 { @@ -178,28 +178,28 @@ enum class KeyboardKey : u32 { }; enum class KeyboardModifier : u32 { - Control = BIT(0), - Shift = BIT(1), - LeftAlt = BIT(2), - RightAlt = BIT(3), - Gui = BIT(4), - CapsLock = BIT(8), - ScrollLock = BIT(9), - NumLock = BIT(10), - Katakana = BIT(11), - Hiragana = BIT(12), + Control = ZTD_BIT(0), + Shift = ZTD_BIT(1), + LeftAlt = ZTD_BIT(2), + RightAlt = ZTD_BIT(3), + Gui = ZTD_BIT(4), + CapsLock = ZTD_BIT(8), + ScrollLock = ZTD_BIT(9), + NumLock = ZTD_BIT(10), + Katakana = ZTD_BIT(11), + Hiragana = ZTD_BIT(12), }; enum class KeyboardLockKeyEvent : u32 { - NumLockOn = BIT(0), - NumLockOff = BIT(1), - NumLockToggle = BIT(2), - CapsLockOn = BIT(3), - CapsLockOff = BIT(4), - CapsLockToggle = BIT(5), - ScrollLockOn = BIT(6), - ScrollLockOff = BIT(7), - ScrollLockToggle = BIT(8), + NumLockOn = ZTD_BIT(0), + NumLockOff = ZTD_BIT(1), + NumLockToggle = ZTD_BIT(2), + CapsLockOn = ZTD_BIT(3), + CapsLockOff = ZTD_BIT(4), + CapsLockToggle = ZTD_BIT(5), + ScrollLockOn = ZTD_BIT(6), + ScrollLockOff = ZTD_BIT(7), + ScrollLockToggle = ZTD_BIT(8), }; enum class NpadIdType : u32 { @@ -217,25 +217,25 @@ enum class NpadIdType : u32 { enum class NpadStyleSet : u32 { None = 0, - FullKey = BIT(0), - Handheld = BIT(1), - JoyDual = BIT(2), - JoyLeft = BIT(3), - JoyRight = BIT(4), - Gc = BIT(5), - Palma = BIT(6), - Lark = BIT(7), - HandheldLark = BIT(8), - Lucia = BIT(9), - Lagon = BIT(10), - Lager = BIT(11), - SystemExt = BIT(29), - System = BIT(30), + FullKey = ZTD_BIT(0), + Handheld = ZTD_BIT(1), + JoyDual = ZTD_BIT(2), + JoyLeft = ZTD_BIT(3), + JoyRight = ZTD_BIT(4), + Gc = ZTD_BIT(5), + Palma = ZTD_BIT(6), + Lark = ZTD_BIT(7), + HandheldLark = ZTD_BIT(8), + Lucia = ZTD_BIT(9), + Lagon = ZTD_BIT(10), + Lager = ZTD_BIT(11), + SystemExt = ZTD_BIT(29), + System = ZTD_BIT(30), FullCtrl = FullKey | Handheld | JoyDual, Standard = FullCtrl | JoyLeft | JoyRight, }; -ENABLE_ENUM_BITWISE_OPERATORS(NpadStyleSet) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(NpadStyleSet) enum class ColorAttribute : u32 { Ok = 0, @@ -246,46 +246,46 @@ enum class ColorAttribute : u32 { enum class NpadButtons : u64 { None = 0, - A = BITL(0), - B = BITL(1), - X = BITL(2), - Y = BITL(3), - StickL = BITL(4), - StickR = BITL(5), - L = BITL(6), - R = BITL(7), - ZL = BITL(8), - ZR = BITL(9), - Plus = BITL(10), - Minus = BITL(11), - Left = BITL(12), - Up = BITL(13), - Right = BITL(14), - Down = BITL(15), - StickLLeft = BITL(16), - StickLUp = BITL(17), - StickLRight = BITL(18), - StickLDown = BITL(19), - StickRLeft = BITL(20), - StickRUp = BITL(21), - StickRRight = BITL(22), - StickRDown = BITL(23), - LeftSL = BITL(24), - LeftSR = BITL(25), - RightSL = BITL(26), - RightSR = BITL(27), - Palma = BITL(28), - Verification = BITL(29), - HandheldLeftB = BITL(30), - LagonCLeft = BITL(31), - LagonCUp = BITL(32), - LagonCRight = BITL(33), - LagonCDown = BITL(34), + A = ZTD_BITL(0), + B = ZTD_BITL(1), + X = ZTD_BITL(2), + Y = ZTD_BITL(3), + StickL = ZTD_BITL(4), + StickR = ZTD_BITL(5), + L = ZTD_BITL(6), + R = ZTD_BITL(7), + ZL = ZTD_BITL(8), + ZR = ZTD_BITL(9), + Plus = ZTD_BITL(10), + Minus = ZTD_BITL(11), + Left = ZTD_BITL(12), + Up = ZTD_BITL(13), + Right = ZTD_BITL(14), + Down = ZTD_BITL(15), + StickLLeft = ZTD_BITL(16), + StickLUp = ZTD_BITL(17), + StickLRight = ZTD_BITL(18), + StickLDown = ZTD_BITL(19), + StickRLeft = ZTD_BITL(20), + StickRUp = ZTD_BITL(21), + StickRRight = ZTD_BITL(22), + StickRDown = ZTD_BITL(23), + LeftSL = ZTD_BITL(24), + LeftSR = ZTD_BITL(25), + RightSL = ZTD_BITL(26), + RightSR = ZTD_BITL(27), + Palma = ZTD_BITL(28), + Verification = ZTD_BITL(29), + HandheldLeftB = ZTD_BITL(30), + LagonCLeft = ZTD_BITL(31), + LagonCUp = ZTD_BITL(32), + LagonCRight = ZTD_BITL(33), + LagonCDown = ZTD_BITL(34), // HACK: alias Invalid = None, }; -ENABLE_ENUM_BITWISE_OPERATORS(NpadButtons) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(NpadButtons) enum class NpadColor : u32 { BodyGray = 0x828282, @@ -323,61 +323,61 @@ enum class NpadColor : u32 { enum class NpadSystemProperties : u64 { None = 0, - IsChargingJoyDual = BIT(0), - IsChargingJoyLeft = BIT(1), - IsChargingJoyRight = BIT(2), - IsPoweredJoyDual = BIT(3), - IsPoweredJoyLeft = BIT(4), - IsPoweredJoyRight = BIT(5), - IsUnsuportedButtonPressedOnNpadSystem = BIT(9), - IsUnsuportedButtonPressedOnNpadSystemExt = BIT(10), - IsAbxyButtonOriented = BIT(11), - IsSlSrButtonOriented = BIT(12), - IsPlusAvailable = BIT(13), - IsMinusAvailable = BIT(14), - IsDirectionalButtonsAvailable = BIT(15), -}; -ENABLE_ENUM_BITWISE_OPERATORS(NpadSystemProperties) + IsChargingJoyDual = ZTD_BIT(0), + IsChargingJoyLeft = ZTD_BIT(1), + IsChargingJoyRight = ZTD_BIT(2), + IsPoweredJoyDual = ZTD_BIT(3), + IsPoweredJoyLeft = ZTD_BIT(4), + IsPoweredJoyRight = ZTD_BIT(5), + IsUnsuportedButtonPressedOnNpadSystem = ZTD_BIT(9), + IsUnsuportedButtonPressedOnNpadSystemExt = ZTD_BIT(10), + IsAbxyButtonOriented = ZTD_BIT(11), + IsSlSrButtonOriented = ZTD_BIT(12), + IsPlusAvailable = ZTD_BIT(13), + IsMinusAvailable = ZTD_BIT(14), + IsDirectionalButtonsAvailable = ZTD_BIT(15), +}; +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(NpadSystemProperties) enum class NpadSystemButtonProperties : u32 { None = 0, - IsUnintendedHomeButtonInputProtectionEnabled = BIT(0), + IsUnintendedHomeButtonInputProtectionEnabled = ZTD_BIT(0), }; -ENABLE_ENUM_BITWISE_OPERATORS(NpadSystemButtonProperties) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(NpadSystemButtonProperties) enum class DebugPadAttribute : u32 { - IsConnected = BIT(0), + IsConnected = ZTD_BIT(0), }; enum class HidTouchAttribute : u32 { - Start = BIT(0), - End = BIT(1), + Start = ZTD_BIT(0), + End = ZTD_BIT(1), }; enum class MouseAttribute : u32 { - Transferable = BIT(0), - IsConnected = BIT(1), + Transferable = ZTD_BIT(0), + IsConnected = ZTD_BIT(1), }; enum class NpadAttributes : u32 { None = 0, - IsConnected = BIT(0), - IsWired = BIT(1), - IsLeftConnected = BIT(2), - IsLeftWired = BIT(3), - IsRightConnected = BIT(4), - IsRightWired = BIT(5), + IsConnected = ZTD_BIT(0), + IsWired = ZTD_BIT(1), + IsLeftConnected = ZTD_BIT(2), + IsLeftWired = ZTD_BIT(3), + IsRightConnected = ZTD_BIT(4), + IsRightWired = ZTD_BIT(5), }; -ENABLE_ENUM_BITWISE_OPERATORS(NpadAttributes) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(NpadAttributes) enum class SixAxisSensorAttribute : u32 { - IsConnected = BIT(0), - IsInterpolated = BIT(1), + IsConnected = ZTD_BIT(0), + IsInterpolated = ZTD_BIT(1), }; enum class GestureAttribute : u32 { - IsNewTouch = BIT(4), - IsDoubleTap = BIT(8), + IsNewTouch = ZTD_BIT(4), + IsDoubleTap = ZTD_BIT(8), }; enum class GestureDirection : u32 { @@ -445,27 +445,27 @@ enum class NpadBatteryLevel : u32 { enum class DeviceTypeBits : u32 { None = 0, - FullKey = BIT(0), - DebugPad = BIT(1), - HandheldLeft = BIT(2), - HandheldRight = BIT(3), - JoyLeft = BIT(4), - JoyRight = BIT(5), - Palma = BIT(6), - LarkHvcLeft = BIT(7), - LarkHvcRight = BIT(8), - LarkNesLeft = BIT(9), - LarkNesRight = BIT(10), - HandheldLarkHvcLeft = BIT(11), - HandheldLarkHvcRight = BIT(12), - HandheldLarkNesLeft = BIT(13), - HandheldLarkNesRight = BIT(14), - Lucia = BIT(15), - Lagon = BIT(16), - Lager = BIT(17), - System = BIT(31), -}; -ENABLE_ENUM_BITWISE_OPERATORS(DeviceTypeBits) + FullKey = ZTD_BIT(0), + DebugPad = ZTD_BIT(1), + HandheldLeft = ZTD_BIT(2), + HandheldRight = ZTD_BIT(3), + JoyLeft = ZTD_BIT(4), + JoyRight = ZTD_BIT(5), + Palma = ZTD_BIT(6), + LarkHvcLeft = ZTD_BIT(7), + LarkHvcRight = ZTD_BIT(8), + LarkNesLeft = ZTD_BIT(9), + LarkNesRight = ZTD_BIT(10), + HandheldLarkHvcLeft = ZTD_BIT(11), + HandheldLarkHvcRight = ZTD_BIT(12), + HandheldLarkNesLeft = ZTD_BIT(13), + HandheldLarkNesRight = ZTD_BIT(14), + Lucia = ZTD_BIT(15), + Lagon = ZTD_BIT(16), + Lager = ZTD_BIT(17), + System = ZTD_BIT(31), +}; +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(DeviceTypeBits) enum class DeviceType : u32 { JoyRight1 = 1, @@ -523,10 +523,10 @@ enum class NpadInterfaceType : u32 { }; enum class XcdInterfaceType : u32 { - Bluetooth = BIT(0), - Uart = BIT(1), - Usb = BIT(2), - FieldSet = BIT(7), + Bluetooth = ZTD_BIT(0), + Uart = ZTD_BIT(1), + Usb = ZTD_BIT(2), + FieldSet = ZTD_BIT(7), }; enum class NpadLarkType : u32 { @@ -605,10 +605,10 @@ enum class PalmaWaveSet : u32 { }; enum class PalmaFeature : u32 { - FrMode = BIT(0), - RumbleFeedback = BIT(1), - Step = BIT(2), - MuteSwitch = BIT(3), + FrMode = ZTD_BIT(0), + RumbleFeedback = ZTD_BIT(1), + Step = ZTD_BIT(2), + MuteSwitch = ZTD_BIT(3), }; } // namespace hydra::horizon::services::hid diff --git a/src/core/horizon/services/lm/logger.cpp b/src/core/horizon/services/lm/logger.cpp index ac96c37f..10cdcab0 100644 --- a/src/core/horizon/services/lm/logger.cpp +++ b/src/core/horizon/services/lm/logger.cpp @@ -7,12 +7,12 @@ namespace { enum class PacketFlags : u8 { None = 0, - Head = BIT(0), - Tail = BIT(1), - LittleEndian = BIT(2), + Head = ZTD_BIT(0), + Tail = ZTD_BIT(1), + LittleEndian = ZTD_BIT(2), }; -ENABLE_ENUM_BITWISE_OPERATORS(hydra::horizon::services::lm::PacketFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(hydra::horizon::services::lm::PacketFlags) enum class Severity : u8 { Trace, @@ -81,8 +81,9 @@ namespace hydra::horizon::services::lm { DEFINE_SERVICE_COMMAND_TABLE(ILogger, 0, Log) result_t ILogger::Log(InBuffer buffer) { - ASSIGN_OR_RETURN_VALUE(auto stream, buffer.stream, - RESULT_SUCCESS); // TODO: return error on failure? + ZTD_ASSIGN_OR_RETURN_VALUE( + auto stream, buffer.stream, + RESULT_SUCCESS); // TODO: return error on failure? const auto header = stream.Read(); // From Ryujinx diff --git a/src/core/horizon/services/nvdrv/ioctl/const.hpp b/src/core/horizon/services/nvdrv/ioctl/const.hpp index b8be2da8..9bbe5046 100644 --- a/src/core/horizon/services/nvdrv/ioctl/const.hpp +++ b/src/core/horizon/services/nvdrv/ioctl/const.hpp @@ -11,7 +11,7 @@ #define DEFINE_IOCTL_TABLE_ENTRY_IMPL(fd, ioctl_suffix, type, ...) \ case type: \ switch (nr) { \ - FOR_EACH_2_2(IOCTL_CASE, fd, ioctl_suffix, __VA_ARGS__) \ + ZTD_FOR_EACH_2_2(IOCTL_CASE, fd, ioctl_suffix, __VA_ARGS__) \ default: \ LOG_WARN(Services, "Unknown ioctl nr 0x{:02x} for type 0x{:02x}", \ nr, type); \ diff --git a/src/core/horizon/services/nvdrv/ioctl/nvhost_as_gpu.cpp b/src/core/horizon/services/nvdrv/ioctl/nvhost_as_gpu.cpp index 617b37ee..8dd4ef15 100644 --- a/src/core/horizon/services/nvdrv/ioctl/nvhost_as_gpu.cpp +++ b/src/core/horizon/services/nvdrv/ioctl/nvhost_as_gpu.cpp @@ -63,18 +63,20 @@ NvResult NvHostAsGpu::MapBufferEX(System* system, kernel::Process* process, return NvResult::Success; } - const auto& map = system->GetGpu().GetMap(nvmap_handle_id); + ZTD_ASSIGN_OR_RETURN_VALUE(const auto map, + system->GetGpu().GetMap(nvmap_handle_id), + NvResult::BadParameter); u64 size = mapping_size; if (size == 0x0) - size = map.size; // TODO: correct? + size = map->size; // TODO: correct? gpu_vaddr_t addr = invalid(); if (any(flags & MapBufferFlags::FixedOffset)) addr = inout_addr; inout_addr = process->GetGMmu().MapBufferToAddressSpace( - Range::FromSize(map.addr + buffer_offset, size), addr); + ztd::Range::fromSize(map->addr + buffer_offset, size), addr); return NvResult::Success; } diff --git a/src/core/horizon/services/nvdrv/ioctl/nvhost_as_gpu.hpp b/src/core/horizon/services/nvdrv/ioctl/nvhost_as_gpu.hpp index b2e7d65a..908bfd04 100644 --- a/src/core/horizon/services/nvdrv/ioctl/nvhost_as_gpu.hpp +++ b/src/core/horizon/services/nvdrv/ioctl/nvhost_as_gpu.hpp @@ -7,20 +7,20 @@ namespace hydra::horizon::services::nvdrv::ioctl { enum class AllocSpaceFlags : u32 { None = 0, - FixedOffset = BIT(0), - Sparse = BIT(1), + FixedOffset = ZTD_BIT(0), + Sparse = ZTD_BIT(1), }; -ENABLE_ENUM_BITWISE_OPERATORS(AllocSpaceFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(AllocSpaceFlags) enum class MapBufferFlags : u32 { None = 0, - FixedOffset = BIT(0), - IsCacheable = BIT(2), - Modify = BIT(8), + FixedOffset = ZTD_BIT(0), + IsCacheable = ZTD_BIT(2), + Modify = ZTD_BIT(8), }; -ENABLE_ENUM_BITWISE_OPERATORS(MapBufferFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(MapBufferFlags) struct VaRegion { gpu_vaddr_t addr; diff --git a/src/core/horizon/services/nvdrv/ioctl/nvmap.cpp b/src/core/horizon/services/nvdrv/ioctl/nvmap.cpp index a43aa3c0..ae7c1fb7 100644 --- a/src/core/horizon/services/nvdrv/ioctl/nvmap.cpp +++ b/src/core/horizon/services/nvdrv/ioctl/nvmap.cpp @@ -35,21 +35,21 @@ NvResult NvMap::Alloc(System* system, handle_id_t handle_id, u32 heap_mask, NvResult NvMap::Free(System* system, Aligned handle_id, gpu_vaddr_t* out_addr, u64* out_size, u32* out_flags) { - auto map = system->GetGpu().GetMap(handle_id); + auto map = system->GetGpu().GetMap(handle_id).value(); system->GetGpu().FreeMap(handle_id); - *out_addr = map.addr; - *out_size = map.size; - *out_flags = map.write ? 1 : 0; // TODO: correct? + *out_addr = map->addr; + *out_size = map->size; + *out_flags = map->write ? 1 : 0; // TODO: correct? return NvResult::Success; } NvResult NvMap::Param(System* system, handle_id_t handle_id, NvMapParamType type, u32* out_value) { - auto map = system->GetGpu().GetMap(handle_id); + auto map = system->GetGpu().GetMap(handle_id).value(); switch (type) { case NvMapParamType::Size: - *out_value = static_cast(map.size); + *out_value = static_cast(map->size); break; case NvMapParamType::Alignment: *out_value = hw::tegra_x1::gpu::GPU_PAGE_SIZE; // TODO: correct? diff --git a/src/core/horizon/services/nvdrv/nvdrv_services.cpp b/src/core/horizon/services/nvdrv/nvdrv_services.cpp index e02cdaea..258acb1a 100644 --- a/src/core/horizon/services/nvdrv/nvdrv_services.cpp +++ b/src/core/horizon/services/nvdrv/nvdrv_services.cpp @@ -17,8 +17,6 @@ namespace hydra::horizon::services::nvdrv { -StaticPool INvDrvServices::fd_pool; - DEFINE_SERVICE_COMMAND_TABLE(INvDrvServices, 0, Open, 1, Ioctl, 2, Close, 3, Initialize, 4, QueryEvent, 8, SetAruid, 11, Ioctl2, 12, Ioctl3, 13, @@ -27,31 +25,32 @@ DEFINE_SERVICE_COMMAND_TABLE(INvDrvServices, 0, Open, 1, Ioctl, 2, Close, 3, result_t INvDrvServices::Open(InBuffer path_buffer, u32* out_fd_id, u32* out_error) { auto path = path_buffer.stream->ReadNullTerminatedString(); - handle_id_t fd_id = fd_pool.AllocateHandle(); + handle_id_t fd_id; if (path == "/dev/nvhost-ctrl") { - fd_pool.Get(fd_id) = new ioctl::NvHostCtrl(); + fd_id = fd_pool.insert(std::make_unique()).value(); } else if (path == "/dev/nvmap") { - fd_pool.Get(fd_id) = new ioctl::NvMap(); + fd_id = fd_pool.insert(std::make_unique()).value(); } else if (path == "/dev/nvhost-as-gpu") { - fd_pool.Get(fd_id) = new ioctl::NvHostAsGpu(); + fd_id = fd_pool.insert(std::make_unique()).value(); } else if (path == "/dev/nvhost-ctrl-gpu") { - fd_pool.Get(fd_id) = new ioctl::NvHostCtrlGpu(); + fd_id = + fd_pool.insert(std::make_unique()).value(); } else if (path == "/dev/nvhost-gpu") { - fd_pool.Get(fd_id) = new ioctl::NvHostGpu(); + fd_id = fd_pool.insert(std::make_unique()).value(); } else if (path == "/dev/nvhost-nvdec") { - fd_pool.Get(fd_id) = new ioctl::NvHostNvDec(); + fd_id = fd_pool.insert(std::make_unique()).value(); } else if (path == "/dev/nvsched-ctrl") { - fd_pool.Get(fd_id) = new ioctl::NvSchedCtrl(); + fd_id = fd_pool.insert(std::make_unique()).value(); } else if (path == "/dev/nvdisp-ctrl") { - fd_pool.Get(fd_id) = new ioctl::NvDispCtrl(); + fd_id = fd_pool.insert(std::make_unique()).value(); } else if (path == "/dev/nvdisp-disp0") { - fd_pool.Get(fd_id) = new ioctl::NvDispDisp(0); + fd_id = fd_pool.insert(std::make_unique(0)).value(); } else if (path == "/dev/nvdisp-disp1") { - fd_pool.Get(fd_id) = new ioctl::NvDispDisp(1); + fd_id = fd_pool.insert(std::make_unique(1)).value(); } else if (path == "/dev/nvhost-vic") { - fd_pool.Get(fd_id) = new ioctl::NvHostVic(); + fd_id = fd_pool.insert(std::make_unique()).value(); } else if (path == "/dev/nvhost-nvjpg") { - fd_pool.Get(fd_id) = new ioctl::NvHostNvJpg(); + fd_id = fd_pool.insert(std::make_unique()).value(); } else { LOG_WARN(Services, "Unknown path \"{}\"", path); *out_error = MAKE_RESULT(Svc, 0); // TODO @@ -74,10 +73,10 @@ result_t INvDrvServices::Ioctl(System* system, kernel::Process* process, } result_t INvDrvServices::Close(u32 fd_id, u32* out_err) { - // TODO: check if exists - auto fd = fd_pool.Get(fd_id); - delete fd; - fd_pool.Free(fd_id); + if (!fd_pool.free(fd_id)) { + // TODO: what to do? + return MAKE_RESULT(Svc, 4); + } *out_err = 0; return RESULT_SUCCESS; @@ -97,11 +96,12 @@ result_t INvDrvServices::Initialize(u32 transfer_mem_size, result_t INvDrvServices::QueryEvent(kernel::Process* process, handle_id_t fd_id, u32 event_id, NvResult* out_result, OutHandle out_handle) { - auto fd = fd_pool.Get(fd_id); + ZTD_ASSIGN_OR_RETURN_VALUE(auto fd, fd_pool.get(fd_id), + MAKE_RESULT(Svc, 4)); // TODO: result // Dispatch kernel::Event* event = nullptr; - NvResult result = fd->QueryEvent(event_id, event); + NvResult result = fd->get()->QueryEvent(event_id, event); // Write result *out_result = result; @@ -145,7 +145,8 @@ result_t INvDrvServices::IoctlImpl( std::optional in_buffer_stream, std::optional out_stream, std::optional out_buffer_stream, NvResult* out_result) { - auto fd = fd_pool.Get(fd_id); + ZTD_ASSIGN_OR_RETURN_VALUE(auto fd, fd_pool.get(fd_id), + MAKE_RESULT(Svc, 4)); // TODO: result // Dispatch u32 type = (code >> 8) & 0xff; @@ -159,7 +160,7 @@ result_t INvDrvServices::IoctlImpl( .out_stream = std::move(out_stream), .out_buffer_stream = std::move(out_buffer_stream), }; - NvResult result = (fd->*func)(context, type, nr); + NvResult result = (fd->get()->*func)(context, type, nr); // Write result *out_result = result; diff --git a/src/core/horizon/services/nvdrv/nvdrv_services.hpp b/src/core/horizon/services/nvdrv/nvdrv_services.hpp index 51bfd885..2f865a10 100644 --- a/src/core/horizon/services/nvdrv/nvdrv_services.hpp +++ b/src/core/horizon/services/nvdrv/nvdrv_services.hpp @@ -2,14 +2,10 @@ #include "core/horizon/services/const.hpp" #include "core/horizon/services/nvdrv/const.hpp" -#include "core/horizon/services/nvdrv/ioctl/const.hpp" +#include "core/horizon/services/nvdrv/ioctl/fd_base.hpp" namespace hydra::horizon::services::nvdrv { -namespace ioctl { -class FdBase; -} - constexpr usize MAX_FD_COUNT = 256; class INvDrvServices : public IService { @@ -19,7 +15,7 @@ class INvDrvServices : public IService { private: // TODO: what should be the max number of fds? - static StaticPool fd_pool; + ztd::mem::StaticPool, MAX_FD_COUNT> fd_pool; // Commands result_t Open(InBuffer path_buffer, u32* out_fd_id, diff --git a/src/core/horizon/services/pl/const.hpp b/src/core/horizon/services/pl/const.hpp index 3df2ccc3..7e00437b 100644 --- a/src/core/horizon/services/pl/const.hpp +++ b/src/core/horizon/services/pl/const.hpp @@ -10,7 +10,7 @@ enum class SharedFontType : u32 { Korean = 4, NintendoExtended = 5, }; -ENABLE_ENUM_ARITHMETIC_OPERATORS(SharedFontType) +ZTD_ENABLE_ENUM_ARITHMETIC_OPERATORS(SharedFontType) enum class LoadState : u32 { Loading = 0, diff --git a/src/core/horizon/services/ro/detail/ro_interface.cpp b/src/core/horizon/services/ro/detail/ro_interface.cpp index 7f25e899..fbc50a5f 100644 --- a/src/core/horizon/services/ro/detail/ro_interface.cpp +++ b/src/core/horizon/services/ro/detail/ro_interface.cpp @@ -17,8 +17,8 @@ result_t IRoInterface::MapManualLoadModuleMemory(kernel::Process* process, auto mmu = process->GetMmu(); const auto base = mmu->FindFreeMemory(kernel::EXECUTABLE_REGION, nro_size + bss_size); - mmu->Map(base, Range::FromSize(nro_addr, nro_size)); - mmu->Map(base + nro_size, Range::FromSize(bss_addr, bss_size)); + mmu->Map(base, ztd::Range::fromSize(nro_addr, nro_size)); + mmu->Map(base + nro_size, ztd::Range::fromSize(bss_addr, bss_size)); *out_addr = base; return RESULT_SUCCESS; diff --git a/src/core/horizon/services/server.hpp b/src/core/horizon/services/server.hpp index 320c2b1a..2c7ce574 100644 --- a/src/core/horizon/services/server.hpp +++ b/src/core/horizon/services/server.hpp @@ -23,8 +23,8 @@ class Server { Server(System& system_) : system{system_} {} ~Server() { Stop(); } - MAKE_NON_COPYABLE(Server); - MAKE_NON_MOVABLE(Server); + ZTD_MAKE_NON_COPYABLE(Server); + ZTD_MAKE_NON_MOVABLE(Server); void Start(); void Stop(); diff --git a/src/core/horizon/services/service.hpp b/src/core/horizon/services/service.hpp index fb6c4469..b214f410 100644 --- a/src/core/horizon/services/service.hpp +++ b/src/core/horizon/services/service.hpp @@ -28,7 +28,7 @@ class IService { IService() noexcept = default; virtual ~IService() noexcept = default; - MAKE_NON_COPYABLE(IService); + ZTD_MAKE_NON_COPYABLE(IService); void HandleRequest(System& system, kernel::Process* caller_process, uptr ptr); @@ -53,16 +53,18 @@ class IService { if (service == nullptr) return INVALID_HANDLE_ID; - return parent->subservice_pool->Insert(service); + return parent->subservice_pool->insert(service).value_or( + INVALID_HANDLE_ID); } void FreeSubservice(handle_id_t handle_id) { - parent->subservice_pool->Get(handle_id)->Release(); - parent->subservice_pool->Free(handle_id); + parent->subservice_pool->get(handle_id).value()->Release(); + ASSERT_DEBUG(parent->subservice_pool->free(handle_id), Services, + "Failed to free subservice"); } IService* GetSubservice(handle_id_t handle_id) const { - return parent->subservice_pool->Get(handle_id); + return parent->subservice_pool->get(handle_id).value(); } private: @@ -73,7 +75,8 @@ class IService { // Domain bool is_domain{false}; IService* parent{this}; - std::optional> subservice_pool; + // TODO: dynamic pool? + std::optional> subservice_pool; void Close(); void Request(RequestContext& context); diff --git a/src/core/horizon/services/settings/system_settings_server.hpp b/src/core/horizon/services/settings/system_settings_server.hpp index 80f9a8db..8dc6bd15 100644 --- a/src/core/horizon/services/settings/system_settings_server.hpp +++ b/src/core/horizon/services/settings/system_settings_server.hpp @@ -11,12 +11,12 @@ enum class ColorSetId : i32 { enum class TvFlags : u32 { None = 0, - Allows4k = BIT(0), - Allows3d = BIT(1), - AllowsCec = BIT(2), - PreventsScreenBurnIn = BIT(3), + Allows4k = ZTD_BIT(0), + Allows3d = ZTD_BIT(1), + AllowsCec = ZTD_BIT(2), + PreventsScreenBurnIn = ZTD_BIT(3), }; -ENABLE_ENUM_BITWISE_OPERATORS(TvFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(TvFlags) enum class TvResolution : u32 { Auto = 0, diff --git a/src/core/hw/tegra_x1/cpu/dynarmic/mmu.cpp b/src/core/hw/tegra_x1/cpu/dynarmic/mmu.cpp index 1801218b..d86637da 100644 --- a/src/core/hw/tegra_x1/cpu/dynarmic/mmu.cpp +++ b/src/core/hw/tegra_x1/cpu/dynarmic/mmu.cpp @@ -6,51 +6,51 @@ namespace hydra::hw::tegra_x1::cpu::dynarmic { -void Mmu::Map(vaddr_t dst_va, Range range, +void Mmu::Map(vaddr_t dst_va, ztd::Range range, const horizon::kernel::MemoryState state) { - ASSERT_ALIGNMENT(range.GetSize(), GUEST_PAGE_SIZE, Dynarmic, "size"); + ASSERT_ALIGNMENT(range.getSize(), GUEST_PAGE_SIZE, Dynarmic, "size"); u64 va_page = dst_va / GUEST_PAGE_SIZE; - u64 size_page = range.GetSize() / GUEST_PAGE_SIZE; + u64 size_page = range.getSize() / GUEST_PAGE_SIZE; u64 va_page_end = va_page + size_page; for (u64 page = va_page; page < va_page_end; ++page) { - auto page_ptr = range.GetBegin() + ((page - va_page) * GUEST_PAGE_SIZE); + auto page_ptr = range.getBegin() + ((page - va_page) * GUEST_PAGE_SIZE); pages[page] = page_ptr; states[page] = state; } } -void Mmu::Map(vaddr_t dst_va, Range range) { - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Dynarmic, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Dynarmic, "end"); +void Mmu::Map(vaddr_t dst_va, ztd::Range range) { + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Dynarmic, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Dynarmic, "end"); - auto src_page = range.GetBegin() / GUEST_PAGE_SIZE; + auto src_page = range.getBegin() / GUEST_PAGE_SIZE; auto dst_page = dst_va / GUEST_PAGE_SIZE; - for (u64 i = 0; i < range.GetSize() / GUEST_PAGE_SIZE; i++) { + for (u64 i = 0; i < range.getSize() / GUEST_PAGE_SIZE; i++) { pages[dst_page + i] = pages[src_page + i]; states[dst_page + i] = states[src_page + i]; } } -void Mmu::Unmap(Range range) { - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Dynarmic, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Dynarmic, "end"); +void Mmu::Unmap(ztd::Range range) { + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Dynarmic, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Dynarmic, "end"); - for (u64 page = range.GetBegin() / GUEST_PAGE_SIZE; - page < range.GetEnd() / GUEST_PAGE_SIZE; ++page) { + for (u64 page = range.getBegin() / GUEST_PAGE_SIZE; + page < range.getEnd() / GUEST_PAGE_SIZE; ++page) { pages[page] = 0x0; states[page] = {.type = horizon::kernel::MemoryType::Free}; } } // TODO: actually protect the memory -void Mmu::Protect(Range range, +void Mmu::Protect(ztd::Range range, horizon::kernel::MemoryPermission perm) { - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Dynarmic, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Dynarmic, "end"); + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Dynarmic, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Dynarmic, "end"); - for (u64 page = range.GetBegin() / GUEST_PAGE_SIZE; - page < range.GetEnd() / GUEST_PAGE_SIZE; ++page) { + for (u64 page = range.getBegin() / GUEST_PAGE_SIZE; + page < range.getEnd() / GUEST_PAGE_SIZE; ++page) { states[page].perm = perm; } } @@ -81,14 +81,14 @@ MemoryRegion Mmu::QueryRegion(vaddr_t va) const { }; } -void Mmu::SetMemoryAttribute(Range range, +void Mmu::SetMemoryAttribute(ztd::Range range, horizon::kernel::MemoryAttribute mask, horizon::kernel::MemoryAttribute value) { - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Dynarmic, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Dynarmic, "end"); + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Dynarmic, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Dynarmic, "end"); - for (u64 page = range.GetBegin() / GUEST_PAGE_SIZE; - page < range.GetEnd() / GUEST_PAGE_SIZE; ++page) { + for (u64 page = range.getBegin() / GUEST_PAGE_SIZE; + page < range.getEnd() / GUEST_PAGE_SIZE; ++page) { auto& state = states[page]; state.attr = (state.attr & ~mask) | (value & mask); } diff --git a/src/core/hw/tegra_x1/cpu/dynarmic/mmu.hpp b/src/core/hw/tegra_x1/cpu/dynarmic/mmu.hpp index 37d00461..d9fe653a 100644 --- a/src/core/hw/tegra_x1/cpu/dynarmic/mmu.hpp +++ b/src/core/hw/tegra_x1/cpu/dynarmic/mmu.hpp @@ -6,22 +6,22 @@ namespace hydra::hw::tegra_x1::cpu::dynarmic { constexpr u64 PAGE_COUNT = - horizon::kernel::ADDRESS_SPACE.GetEnd() / GUEST_PAGE_SIZE; + horizon::kernel::ADDRESS_SPACE.getEnd() / GUEST_PAGE_SIZE; class Mmu : public IMmu { public: using IMmu::IMmu; - void Map(vaddr_t dst_va, Range range, + void Map(vaddr_t dst_va, ztd::Range range, const horizon::kernel::MemoryState state) override; - void Map(vaddr_t dst_va, Range range) override; - void Unmap(Range range) override; - void Protect(Range range, + void Map(vaddr_t dst_va, ztd::Range range) override; + void Unmap(ztd::Range range) override; + void Protect(ztd::Range range, horizon::kernel::MemoryPermission perm) override; uptr UnmapAddr(vaddr_t va) const override; MemoryRegion QueryRegion(vaddr_t va) const override; - void SetMemoryAttribute(Range range, + void SetMemoryAttribute(ztd::Range range, horizon::kernel::MemoryAttribute mask, horizon::kernel::MemoryAttribute value) override; @@ -29,19 +29,19 @@ class Mmu : public IMmu { protected: // Write tracking - void SetWriteTrackingEnabled(Range range, bool enable) override { + void SetWriteTrackingEnabled(ztd::Range range, bool enable) override { // TODO: implement (void)range; (void)enable; ONCE(LOG_FUNC_NOT_IMPLEMENTED(Dynarmic)); } - bool TrySuspendWriteTracking(Range range) override { + bool TrySuspendWriteTracking(ztd::Range range) override { // TODO: implement (void)range; ONCE(LOG_FUNC_NOT_IMPLEMENTED(Dynarmic)); return false; } - void ResumeWriteTracking(Range range) override { + void ResumeWriteTracking(ztd::Range range) override { // TODO: implement (void)range; ONCE(LOG_FUNC_NOT_IMPLEMENTED(Dynarmic)); diff --git a/src/core/hw/tegra_x1/cpu/dynarmic/thread.cpp b/src/core/hw/tegra_x1/cpu/dynarmic/thread.cpp index 8d30e297..94ac1617 100644 --- a/src/core/hw/tegra_x1/cpu/dynarmic/thread.cpp +++ b/src/core/hw/tegra_x1/cpu/dynarmic/thread.cpp @@ -55,7 +55,7 @@ Thread::Thread(WallClock& wall_clock, IMmu* mmu, config.enable_cycle_counting = false; // Code cache size - config.code_cache_size = static_cast(128 * 1024 * 1024); // 128_MiB; + config.code_cache_size = 128_MiB; // TODO: make this configurable // config.optimizations = Dyn::no_optimizations; diff --git a/src/core/hw/tegra_x1/cpu/dynarmic/thread.hpp b/src/core/hw/tegra_x1/cpu/dynarmic/thread.hpp index d3fabd81..ea913a6d 100644 --- a/src/core/hw/tegra_x1/cpu/dynarmic/thread.hpp +++ b/src/core/hw/tegra_x1/cpu/dynarmic/thread.hpp @@ -24,8 +24,8 @@ class Thread final : public IThread, private Dynarmic::A64::UserCallbacks { void Run() override; - void NotifyMemoryChanged(Range mem_range) override { - jit->InvalidateCacheRange(mem_range.GetBegin(), mem_range.GetSize()); + void NotifyMemoryChanged(ztd::Range mem_range) override { + jit->InvalidateCacheRange(mem_range.getBegin(), mem_range.getSize()); } // Debug diff --git a/src/core/hw/tegra_x1/cpu/hypervisor/cpu.cpp b/src/core/hw/tegra_x1/cpu/hypervisor/cpu.cpp index 85e047b9..4a97f32b 100644 --- a/src/core/hw/tegra_x1/cpu/hypervisor/cpu.cpp +++ b/src/core/hw/tegra_x1/cpu/hypervisor/cpu.cpp @@ -53,7 +53,7 @@ Cpu::Cpu() // Kernel memory kernel_page_table.Map( - 0x0, Range::FromSize(kernel_mem.GetPtr(), KERNEL_MEM_SIZE), + 0x0, ztd::Range::fromSize(kernel_mem.GetPtr(), KERNEL_MEM_SIZE), {.type = horizon::kernel::MemoryType::Kernel, .attr = horizon::kernel::MemoryAttribute::None, .perm = horizon::kernel::MemoryPermission::Execute}, @@ -72,11 +72,11 @@ Cpu::Cpu() /* GET_CURRENT_PROCESS_DEBUGGER().GetModuleTable().RegisterSymbol( {"Hypervisor::handler", - Range(KERNEL_REGION_BASE, + ztd::Range(KERNEL_REGION_BASE, KERNEL_REGION_BASE + EXCEPTION_TRAMPOLINE_OFFSET)}); GET_CURRENT_PROCESS_DEBUGGER().GetModuleTable().RegisterSymbol( {"Hypervisor::trampoline", - Range(KERNEL_REGION_BASE + EXCEPTION_TRAMPOLINE_OFFSET, + ztd::Range(KERNEL_REGION_BASE + EXCEPTION_TRAMPOLINE_OFFSET, KERNEL_REGION_BASE + EXCEPTION_TRAMPOLINE_OFFSET + sizeof(exception_trampoline))}); */ diff --git a/src/core/hw/tegra_x1/cpu/hypervisor/mmu.cpp b/src/core/hw/tegra_x1/cpu/hypervisor/mmu.cpp index 712d88d6..f5e4e526 100644 --- a/src/core/hw/tegra_x1/cpu/hypervisor/mmu.cpp +++ b/src/core/hw/tegra_x1/cpu/hypervisor/mmu.cpp @@ -95,35 +95,35 @@ Mmu::Mmu(System& system) Mmu::~Mmu() { ReleasePageTableRegion(user_page_table.GetBase()); } -void Mmu::Map(vaddr_t dst_va, Range range, +void Mmu::Map(vaddr_t dst_va, ztd::Range range, const horizon::kernel::MemoryState state) { ASSERT_ALIGNMENT(dst_va, GUEST_PAGE_SIZE, Hypervisor, "destination VA"); - ASSERT_ALIGNMENT(range.GetSize(), GUEST_PAGE_SIZE, Hypervisor, "size"); + ASSERT_ALIGNMENT(range.getSize(), GUEST_PAGE_SIZE, Hypervisor, "size"); user_page_table.Map(dst_va, range, state, ToApFlags(state.perm)); } // HACK: this assumes that the whole src range is stored contiguously in // physical memory -void Mmu::Map(vaddr_t dst_va, Range range) { - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); - const auto region = user_page_table.QueryRegion(range.GetBegin()); - paddr_t pa = region.UnmapAddr(range.GetBegin()); +void Mmu::Map(vaddr_t dst_va, ztd::Range range) { + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); + const auto region = user_page_table.QueryRegion(range.getBegin()); + paddr_t pa = region.UnmapAddr(range.getBegin()); // TODO: also inherit flags - user_page_table.Map(dst_va, Range::FromSize(pa, range.GetSize()), + user_page_table.Map(dst_va, ztd::Range::fromSize(pa, range.getSize()), region.state, ToApFlags(region.state.perm)); } -void Mmu::Unmap(Range range) { - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); +void Mmu::Unmap(ztd::Range range) { + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); user_page_table.Unmap(range); } -void Mmu::Protect(Range range, +void Mmu::Protect(ztd::Range range, horizon::kernel::MemoryPermission perm) { - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); user_page_table.SetMemoryPermission(range, perm, ToApFlags(perm)); } @@ -139,27 +139,27 @@ MemoryRegion Mmu::QueryRegion(vaddr_t va) const { }; } -void Mmu::SetMemoryAttribute(Range range, +void Mmu::SetMemoryAttribute(ztd::Range range, horizon::kernel::MemoryAttribute mask, horizon::kernel::MemoryAttribute value) { user_page_table.SetMemoryAttribute(range, mask, value); } -void Mmu::SetWriteTrackingEnabled(Range range, bool enable) { - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); +void Mmu::SetWriteTrackingEnabled(ztd::Range range, bool enable) { + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); user_page_table.SetWriteTrackingEnabled(range, enable); } -bool Mmu::TrySuspendWriteTracking(Range range) { - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); +bool Mmu::TrySuspendWriteTracking(ztd::Range range) { + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); return user_page_table.TrySuspendWriteTracking(range); } -void Mmu::ResumeWriteTracking(Range range) { - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); +void Mmu::ResumeWriteTracking(ztd::Range range) { + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); user_page_table.ResumeWriteTracking(range); } diff --git a/src/core/hw/tegra_x1/cpu/hypervisor/mmu.hpp b/src/core/hw/tegra_x1/cpu/hypervisor/mmu.hpp index 82da90f7..7c07c3b9 100644 --- a/src/core/hw/tegra_x1/cpu/hypervisor/mmu.hpp +++ b/src/core/hw/tegra_x1/cpu/hypervisor/mmu.hpp @@ -14,24 +14,24 @@ class Mmu : public IMmu { Mmu(System& system); ~Mmu() override; - void Map(vaddr_t dst_va, Range range, + void Map(vaddr_t dst_va, ztd::Range range, const horizon::kernel::MemoryState state) override; - void Map(vaddr_t dst_va, Range range) override; - void Unmap(Range range) override; - void Protect(Range range, + void Map(vaddr_t dst_va, ztd::Range range) override; + void Unmap(ztd::Range range) override; + void Protect(ztd::Range range, horizon::kernel::MemoryPermission perm) override; uptr UnmapAddr(vaddr_t va) const override; MemoryRegion QueryRegion(vaddr_t va) const override; - void SetMemoryAttribute(Range range, + void SetMemoryAttribute(ztd::Range range, horizon::kernel::MemoryAttribute mask, horizon::kernel::MemoryAttribute value) override; protected: // Write tracking - void SetWriteTrackingEnabled(Range range, bool enable) override; - bool TrySuspendWriteTracking(Range range) override; - void ResumeWriteTracking(Range range) override; + void SetWriteTrackingEnabled(ztd::Range range, bool enable) override; + bool TrySuspendWriteTracking(ztd::Range range) override; + void ResumeWriteTracking(ztd::Range range) override; private: PageTable user_page_table; diff --git a/src/core/hw/tegra_x1/cpu/hypervisor/page_table.cpp b/src/core/hw/tegra_x1/cpu/hypervisor/page_table.cpp index b4be522e..cc6208c9 100644 --- a/src/core/hw/tegra_x1/cpu/hypervisor/page_table.cpp +++ b/src/core/hw/tegra_x1/cpu/hypervisor/page_table.cpp @@ -45,19 +45,19 @@ PageTable::PageTable(paddr_t base_pa) PageTable::~PageTable() = default; -void PageTable::Map(vaddr_t va, Range range, +void PageTable::Map(vaddr_t va, ztd::Range range, const horizon::kernel::MemoryState state, ApFlags ap_flags) { LOG_DEBUG(Hypervisor, "va: {:#x}, range: {:#x}", va, range); ASSERT_ALIGNMENT(va, GUEST_PAGE_SIZE, Hypervisor, "va"); - ASSERT_ALIGNMENT(range.GetBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); - ASSERT_ALIGNMENT(range.GetEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); + ASSERT_ALIGNMENT(range.getBegin(), GUEST_PAGE_SIZE, Hypervisor, "begin"); + ASSERT_ALIGNMENT(range.getEnd(), GUEST_PAGE_SIZE, Hypervisor, "end"); - MapLevel(top_level, va, range.GetBegin(), range.GetSize(), state, ap_flags); + MapLevel(top_level, va, range.getBegin(), range.getSize(), state, ap_flags); } -void PageTable::Unmap(Range range) { +void PageTable::Unmap(ztd::Range range) { (void)this; LOG_FUNC_WITH_ARGS_NOT_IMPLEMENTED(Hypervisor, "range: {:#x}", range); } @@ -99,10 +99,10 @@ PageRegion PageTable::QueryRegion(vaddr_t va) const { return region; } -void PageTable::SetMemoryPermission(Range range, +void PageTable::SetMemoryPermission(ztd::Range range, horizon::kernel::MemoryPermission perm, ApFlags ap_flags) { - ModifyRange(range, [perm, ap_flags]([[maybe_unused]] Range range, + ModifyRange(range, [perm, ap_flags]([[maybe_unused]] ztd::Range range, u64& entry, horizon::kernel::MemoryState& state, [[maybe_unused]] PageFlags flags) { @@ -114,10 +114,10 @@ void PageTable::SetMemoryPermission(Range range, }); } -void PageTable::SetMemoryAttribute(Range range, +void PageTable::SetMemoryAttribute(ztd::Range range, horizon::kernel::MemoryAttribute mask, horizon::kernel::MemoryAttribute value) { - ModifyRange(range, [mask, value]([[maybe_unused]] Range range, + ModifyRange(range, [mask, value]([[maybe_unused]] ztd::Range range, [[maybe_unused]] u64& entry, horizon::kernel::MemoryState& state, [[maybe_unused]] PageFlags flags) { @@ -125,9 +125,9 @@ void PageTable::SetMemoryAttribute(Range range, }); } -void PageTable::SetWriteTrackingEnabled(Range range, bool enable) { +void PageTable::SetWriteTrackingEnabled(ztd::Range range, bool enable) { ModifyRange(range, - [enable]([[maybe_unused]] Range range, u64& entry, + [enable]([[maybe_unused]] ztd::Range range, u64& entry, [[maybe_unused]] horizon::kernel::MemoryState& state, PageFlags& flags) { // AP flags @@ -144,10 +144,10 @@ void PageTable::SetWriteTrackingEnabled(Range range, bool enable) { }); } -bool PageTable::TrySuspendWriteTracking(Range range) { +bool PageTable::TrySuspendWriteTracking(ztd::Range range) { bool res = false; ModifyRange(range, [&res]( - [[maybe_unused]] Range range, u64& entry, + [[maybe_unused]] ztd::Range range, u64& entry, [[maybe_unused]] horizon::kernel::MemoryState& state, [[maybe_unused]] PageFlags& flags) { bool enabled = any(flags & PageFlags::WriteTrackingEnabled); @@ -161,8 +161,8 @@ bool PageTable::TrySuspendWriteTracking(Range range) { return res; } -void PageTable::ResumeWriteTracking(Range range) { - ModifyRange(range, []([[maybe_unused]] Range range, u64& entry, +void PageTable::ResumeWriteTracking(ztd::Range range) { + ModifyRange(range, []([[maybe_unused]] ztd::Range range, u64& entry, [[maybe_unused]] horizon::kernel::MemoryState& state, PageFlags& flags) { if (any(flags & PageFlags::WriteTrackingEnabled)) { @@ -219,12 +219,12 @@ void PageTable::MapLevelNext(PageTableLevel& level, vaddr_t va, paddr_t pa, } void PageTable::IterateRange( - Range range, - const std::function, u64, + ztd::Range range, + const std::function, u64, const horizon::kernel::MemoryState&, PageFlags)>& callback) const { - for (u64 page = range.GetBegin() / GUEST_PAGE_SIZE; - page < range.GetEnd() / GUEST_PAGE_SIZE; ++page) { + for (u64 page = range.getBegin() / GUEST_PAGE_SIZE; + page < range.getEnd() / GUEST_PAGE_SIZE; ++page) { u32 index = top_level.VaToIndex(page * GUEST_PAGE_SIZE); auto* level = &top_level; u64 entry = top_level.GetEntry(index); @@ -241,7 +241,7 @@ void PageTable::IterateRange( continue; callback( - Range::FromSize(page * GUEST_PAGE_SIZE, GUEST_PAGE_SIZE), + ztd::Range::fromSize(page * GUEST_PAGE_SIZE, GUEST_PAGE_SIZE), level->GetEntry(index), level->GetLevelState(index), level->GetLevelFlags(index)); } @@ -249,12 +249,12 @@ void PageTable::IterateRange( // TODO: this should subdivide the table if necessary void PageTable::ModifyRange( - Range range, - const std::function, u64&, + ztd::Range range, + const std::function, u64&, horizon::kernel::MemoryState&, PageFlags&)>& callback) { - for (u64 page = range.GetBegin() / GUEST_PAGE_SIZE; - page < range.GetEnd() / GUEST_PAGE_SIZE; ++page) { + for (u64 page = range.getBegin() / GUEST_PAGE_SIZE; + page < range.getEnd() / GUEST_PAGE_SIZE; ++page) { u32 index = top_level.VaToIndex(page * GUEST_PAGE_SIZE); auto* level = &top_level; u64 entry = top_level.GetEntry(index); @@ -271,7 +271,7 @@ void PageTable::ModifyRange( continue; callback( - Range::FromSize(page * GUEST_PAGE_SIZE, GUEST_PAGE_SIZE), + ztd::Range::fromSize(page * GUEST_PAGE_SIZE, GUEST_PAGE_SIZE), level->GetEntry(index), level->GetLevelState(index), level->GetLevelFlags(index)); } diff --git a/src/core/hw/tegra_x1/cpu/hypervisor/page_table.hpp b/src/core/hw/tegra_x1/cpu/hypervisor/page_table.hpp index 37d8b7c3..cbe31833 100644 --- a/src/core/hw/tegra_x1/cpu/hypervisor/page_table.hpp +++ b/src/core/hw/tegra_x1/cpu/hypervisor/page_table.hpp @@ -17,9 +17,9 @@ constexpr u64 ADDRESS_SPACE_SIZE = 1ull << GET_BLOCK_SHIFT(-1); enum class PageFlags : u8 { None = 0, - WriteTrackingEnabled = BITL(0), + WriteTrackingEnabled = ZTD_BITL(0), }; -ENABLE_ENUM_BITWISE_OPERATORS(PageFlags); +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(PageFlags); struct PageTableLevel { PageTableLevel(u32 level_, const Page page_, const vaddr_t base_va_); @@ -97,23 +97,23 @@ class PageTable { PageTable(paddr_t base_pa); ~PageTable(); - void Map(vaddr_t va, Range range, + void Map(vaddr_t va, ztd::Range range, const horizon::kernel::MemoryState state, ApFlags ap_flags); - void Unmap(Range range); + void Unmap(ztd::Range range); // State PageRegion QueryRegion(vaddr_t va) const; - void SetMemoryPermission(Range range, + void SetMemoryPermission(ztd::Range range, horizon::kernel::MemoryPermission perm, ApFlags ap_flags); - void SetMemoryAttribute(Range range, + void SetMemoryAttribute(ztd::Range range, horizon::kernel::MemoryAttribute mask, horizon::kernel::MemoryAttribute value); // Write tracking - void SetWriteTrackingEnabled(Range range, bool enable); - bool TrySuspendWriteTracking(Range range); - void ResumeWriteTracking(Range range); + void SetWriteTrackingEnabled(ztd::Range range, bool enable); + bool TrySuspendWriteTracking(ztd::Range range); + void ResumeWriteTracking(ztd::Range range); paddr_t UnmapAddr(vaddr_t va) const; @@ -130,12 +130,12 @@ class PageTable { ApFlags ap_flags); void - IterateRange(Range range, - const std::function, u64, + IterateRange(ztd::Range range, + const std::function, u64, const horizon::kernel::MemoryState&, PageFlags)>& callback) const; - void ModifyRange(Range range, - const std::function, u64&, + void ModifyRange(ztd::Range range, + const std::function, u64&, horizon::kernel::MemoryState&, PageFlags&)>& callback); }; diff --git a/src/core/hw/tegra_x1/cpu/hypervisor/thread.cpp b/src/core/hw/tegra_x1/cpu/hypervisor/thread.cpp index a35616fa..8058e4f2 100644 --- a/src/core/hw/tegra_x1/cpu/hypervisor/thread.cpp +++ b/src/core/hw/tegra_x1/cpu/hypervisor/thread.cpp @@ -179,7 +179,7 @@ void Thread::Run() { case ExceptionClass::DataAbortLowerEl: { // TODO: use the correct size if (far < ADDRESS_SPACE_SIZE && - MMU.TrackWrite(Range::FromSize(far, 8))) + MMU.TrackWrite(ztd::Range::fromSize(far, 8))) break; bool far_valid = (esr & 0x00000400) == 0; diff --git a/src/core/hw/tegra_x1/cpu/memory.hpp b/src/core/hw/tegra_x1/cpu/memory.hpp index 308b6bbc..0e7d8b5a 100644 --- a/src/core/hw/tegra_x1/cpu/memory.hpp +++ b/src/core/hw/tegra_x1/cpu/memory.hpp @@ -9,8 +9,8 @@ class IMemory { IMemory(u64 size_) : size{align(size_, GUEST_PAGE_SIZE)} {} virtual ~IMemory() = default; - MAKE_NON_COPYABLE(IMemory); - MAKE_NON_MOVABLE(IMemory); + ZTD_MAKE_NON_COPYABLE(IMemory); + ZTD_MAKE_NON_MOVABLE(IMemory); // The memory needs to be unmapped before resizing void Resize(u64 new_size) { diff --git a/src/core/hw/tegra_x1/cpu/mmu.cpp b/src/core/hw/tegra_x1/cpu/mmu.cpp index 9aea32a6..22f32c6f 100644 --- a/src/core/hw/tegra_x1/cpu/mmu.cpp +++ b/src/core/hw/tegra_x1/cpu/mmu.cpp @@ -30,7 +30,7 @@ horizon::kernel::MemoryInfo IMmu::QueryMemory(vaddr_t va) const { // Next vaddr_t addr = info.addr + info.size; - if (addr >= horizon::kernel::ADDRESS_SPACE.GetEnd()) + if (addr >= horizon::kernel::ADDRESS_SPACE.getEnd()) break; region = QueryRegion(addr); @@ -48,35 +48,35 @@ horizon::kernel::MemoryInfo IMmu::QueryMemory(vaddr_t va) const { return info; } -vaddr_t IMmu::FindFreeMemory(Range region, u64 size) const { +vaddr_t IMmu::FindFreeMemory(ztd::Range region, u64 size) const { size = align(size, GUEST_PAGE_SIZE); - auto crnt_region = Range::FromSize(region.GetBegin(), size); - while (region.Contains(crnt_region)) { - const auto info = QueryMemory(crnt_region.GetBegin()); - const auto mem_range = Range( - std::max(info.addr, region.GetBegin()), info.addr + info.size); + auto crnt_region = ztd::Range::fromSize(region.getBegin(), size); + while (region.contains(crnt_region)) { + const auto info = QueryMemory(crnt_region.getBegin()); + const auto mem_range = ztd::Range( + std::max(info.addr, region.getBegin()), info.addr + info.size); if (info.state.type == horizon::kernel::MemoryType::Free && - mem_range.Contains(crnt_region)) - return mem_range.GetBegin(); + mem_range.contains(crnt_region)) + return mem_range.getBegin(); - crnt_region += mem_range.GetSize(); + crnt_region += mem_range.getSize(); } return 0x0; } -bool IMmu::TrackWrite(Range range) { +bool IMmu::TrackWrite(ztd::Range range) { const auto aligned_range = - Range(align_down(range.GetBegin(), GUEST_PAGE_SIZE), - align(range.GetEnd(), GUEST_PAGE_SIZE)); + ztd::Range(align_down(range.getBegin(), GUEST_PAGE_SIZE), + align(range.getEnd(), GUEST_PAGE_SIZE)); if (!TrySuspendWriteTracking(aligned_range)) return false; // Notify the GPU // TODO: what about non-contiguous regions? - const auto ptr = UnmapAddr(aligned_range.GetBegin()); + const auto ptr = UnmapAddr(aligned_range.getBegin()); system.GetGpu().GetRenderer().InvalidateMemory( - Range::FromSize(ptr, aligned_range.GetSize())); + ztd::Range::fromSize(ptr, aligned_range.getSize())); { std::scoped_lock lock(write_tracking_mutex); diff --git a/src/core/hw/tegra_x1/cpu/mmu.hpp b/src/core/hw/tegra_x1/cpu/mmu.hpp index 8dff6bc2..5b76d080 100644 --- a/src/core/hw/tegra_x1/cpu/mmu.hpp +++ b/src/core/hw/tegra_x1/cpu/mmu.hpp @@ -24,35 +24,35 @@ class IMmu { IMmu(System& system_) : system{system_} {} virtual ~IMmu() = default; - virtual void Map(vaddr_t dst_va, Range range, + virtual void Map(vaddr_t dst_va, ztd::Range range, const horizon::kernel::MemoryState state) = 0; void Map(vaddr_t dst_va, IMemory* memory, const horizon::kernel::MemoryState state) { - Map(dst_va, Range::FromSize(memory->GetPtr(), memory->GetSize()), + Map(dst_va, ztd::Range::fromSize(memory->GetPtr(), memory->GetSize()), state); } - virtual void Map(vaddr_t dst_va, Range range) = 0; - virtual void Unmap(Range range) = 0; - virtual void Protect(Range range, + virtual void Map(vaddr_t dst_va, ztd::Range range) = 0; + virtual void Unmap(ztd::Range range) = 0; + virtual void Protect(ztd::Range range, horizon::kernel::MemoryPermission perm) = 0; virtual uptr UnmapAddr(vaddr_t va) const = 0; virtual MemoryRegion QueryRegion(vaddr_t va) const = 0; - virtual void SetMemoryAttribute(Range range, + virtual void SetMemoryAttribute(ztd::Range range, horizon::kernel::MemoryAttribute mask, horizon::kernel::MemoryAttribute value) = 0; horizon::kernel::MemoryInfo QueryMemory(vaddr_t va) const; - vaddr_t FindFreeMemory(Range region, u64 size) const; + vaddr_t FindFreeMemory(ztd::Range region, u64 size) const; // Write tracking - void EnableWriteTracking(Range range) { + void EnableWriteTracking(ztd::Range range) { SetWriteTrackingEnabled(range, true); } - void DisableWriteTracking(Range range) { + void DisableWriteTracking(ztd::Range range) { SetWriteTrackingEnabled(range, false); } - bool TrackWrite(Range range); + bool TrackWrite(ztd::Range range); void FlushTrackedPages(); // Read @@ -100,15 +100,15 @@ class IMmu { protected: // Write tracking - virtual void SetWriteTrackingEnabled(Range range, bool enable) = 0; - virtual bool TrySuspendWriteTracking(Range range) = 0; - virtual void ResumeWriteTracking(Range range) = 0; + virtual void SetWriteTrackingEnabled(ztd::Range range, bool enable) = 0; + virtual bool TrySuspendWriteTracking(ztd::Range range) = 0; + virtual void ResumeWriteTracking(ztd::Range range) = 0; private: System& system; std::mutex write_tracking_mutex; - std::vector> tracked_pages; + std::vector> tracked_pages; }; } // namespace hydra::hw::tegra_x1::cpu diff --git a/src/core/hw/tegra_x1/cpu/thread.hpp b/src/core/hw/tegra_x1/cpu/thread.hpp index d2144312..7f292852 100644 --- a/src/core/hw/tegra_x1/cpu/thread.hpp +++ b/src/core/hw/tegra_x1/cpu/thread.hpp @@ -44,7 +44,7 @@ class IThread { virtual void Run() = 0; virtual void - NotifyMemoryChanged([[maybe_unused]] Range mem_range) {} + NotifyMemoryChanged([[maybe_unused]] ztd::Range mem_range) {} // Debug void GetStackTrace(const stack_frame_callback_fn_t& callback); diff --git a/src/core/hw/tegra_x1/gpu/const.hpp b/src/core/hw/tegra_x1/gpu/const.hpp index 559c5b5e..52e11a5f 100644 --- a/src/core/hw/tegra_x1/gpu/const.hpp +++ b/src/core/hw/tegra_x1/gpu/const.hpp @@ -728,14 +728,14 @@ struct Fence { enum class GpfifoFlags : u32 { None = 0, - FenceWait = BIT(0), - FenceGet = BIT(1), - HwFormat = BIT(2), - SyncFence = BIT(3), - SuppressWfi = BIT(4), - SkipBufferRefcounting = BIT(5), + FenceWait = ZTD_BIT(0), + FenceGet = ZTD_BIT(1), + HwFormat = ZTD_BIT(2), + SyncFence = ZTD_BIT(3), + SuppressWfi = ZTD_BIT(4), + SkipBufferRefcounting = ZTD_BIT(5), }; -ENABLE_ENUM_BITWISE_OPERATORS(GpfifoFlags); +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(GpfifoFlags); struct GpfifoEntry { u64 gpu_addr_lo : 32; @@ -1011,9 +1011,9 @@ ENABLE_ENUM_FORMATTING( "zf32_x16v8x8__cov4r12v", ZF32_X16V8S8_COV4R12V, "zf32_x16v8s8__cov4r12v", Z16, "z16", V8Z24_COV8R24V, "v8z24__cov8r24v", X8Z24_X16V8S8_COV8R24V, "x8z24_x16v8s8__cov8r24v", ZF32_X16V8X8_COV8R24V, "zf32_x16v8x8__cov8r24v", - ZF32_X16V8S8_COV8R24V, "zf32_x16v8s8__cov8r24v", ASTC_2D_4X4, - "astc_2d_4x4", ASTC_2D_5X5, "astc_2d_5x5", ASTC_2D_6X6, "astc_2d_6x6", - ASTC_2D_8X8, "astc_2d_8x8", ASTC_2D_10X10, "astc_2d_10x10", ASTC_2D_12X12, + ZF32_X16V8S8_COV8R24V, "zf32_x16v8s8__cov8r24v", ASTC_2D_4X4, "astc_2d_4x4", + ASTC_2D_5X5, "astc_2d_5x5", ASTC_2D_6X6, "astc_2d_6x6", ASTC_2D_8X8, + "astc_2d_8x8", ASTC_2D_10X10, "astc_2d_10x10", ASTC_2D_12X12, "astc_2d_12x12", ASTC_2D_5X4, "astc_2d_5x4", ASTC_2D_6X5, "astc_2d_6x5", ASTC_2D_8X6, "astc_2d_8x6", ASTC_2D_10X8, "astc_2d_10x8", ASTC_2D_12X10, "astc_2d_12x10", ASTC_2D_8X5, "astc_2d_8x5", ASTC_2D_10X5, "astc_2d_10x5", diff --git a/src/core/hw/tegra_x1/gpu/engines/3d.cpp b/src/core/hw/tegra_x1/gpu/engines/3d.cpp index 0db22115..db4b36fb 100644 --- a/src/core/hw/tegra_x1/gpu/engines/3d.cpp +++ b/src/core/hw/tegra_x1/gpu/engines/3d.cpp @@ -338,7 +338,7 @@ void ThreeD::DrawVertexElements(const u32 index, u32 count) { regs.index_type); // u64(regs.index_buffer_limit_addr) + 1 // - u64(regs.index_buffer_addr); const auto range = - Range::FromSize(index_buffer_ptr, index_buffer_size); + ztd::Range::fromSize(index_buffer_ptr, index_buffer_size); index_buffer = gpu.GetRenderer().GetIndexCache().Decode( tls_crnt_command_buffer, @@ -418,7 +418,7 @@ void ThreeD::LoadConstBuffer(const u32 index, const u32 data) { // Invalidate // TODO: invalidate as a whole gpu.GetRenderer().InvalidateMemory( - Range::FromSize(ptr, sizeof(u32)), + ztd::Range::fromSize(ptr, sizeof(u32)), renderer::MemoryInvalidationScope::BufferCache); } @@ -437,12 +437,12 @@ void ThreeD::BindGroup(const u32 index, const u32 data) { const uptr const_buffer_gpu_ptr = tls_crnt_gmmu->UnmapAddr(regs.const_buffer_selector); - const auto range = Range::FromSize( + const auto range = ztd::Range::fromSize( const_buffer_gpu_ptr, regs.const_buffer_selector_size); bound_const_buffers[shader_stage_index][buffer_index] = range; } else { bound_const_buffers[shader_stage_index][buffer_index] = - Range(); + ztd::Range(); } break; } @@ -780,7 +780,7 @@ renderer::BufferView ThreeD::GetVertexBuffer(u32 vertex_array_index) const { static_cast(regs.vertex_array_limits[vertex_array_index]) + 1 - static_cast(vertex_array.addr); return gpu.GetRenderer().GetBufferCache().Get( - tls_crnt_command_buffer, Range::FromSize(ptr, size)); + tls_crnt_command_buffer, ztd::Range::fromSize(ptr, size)); } renderer::ITextureView* @@ -833,7 +833,7 @@ ThreeD::GetTexture(const TextureImageControl& tic) const { level_count, layer_count, tic.sparse_tile_width_gobs_log2, tic.tile_height_gobs_log2, tic.tile_depth_gobs_log2); const renderer::TextureViewDescriptor view_descriptor( - type, format, Range(0, level_count), Range(0, layer_count), + type, format, ztd::Range(0, level_count), ztd::Range(0, layer_count), renderer::SwizzleChannels( format, tic.format_word.swizzle_x, tic.format_word.swizzle_y, tic.format_word.swizzle_z, tic.format_word.swizzle_w)); @@ -884,7 +884,7 @@ void ThreeD::ConfigureShaderStage( // TODO: analyze the shader to get the max possible size const auto range = bound_const_buffers[stage_index][i]; - if (range.GetBegin() == 0x0) { + if (range.getBegin() == 0x0) { LOG_WARN(Engines, "Uniform buffer at index {} is not bound", index); continue; } @@ -902,7 +902,7 @@ void ThreeD::ConfigureShaderStage( auto tex_const_buffer = reinterpret_cast( bound_const_buffers[stage_index] [regs.bindless_texture_const_buffer_slot] - .GetBegin()); + .getBegin()); for (const auto [const_buffer_index, renderer_index] : resource_mapping.textures) { const auto texture_handle = tex_const_buffer[const_buffer_index]; diff --git a/src/core/hw/tegra_x1/gpu/engines/3d.hpp b/src/core/hw/tegra_x1/gpu/engines/3d.hpp index 282e0d53..9f7136df 100644 --- a/src/core/hw/tegra_x1/gpu/engines/3d.hpp +++ b/src/core/hw/tegra_x1/gpu/engines/3d.hpp @@ -177,10 +177,10 @@ enum class ViewportZClip : u32 { enum class WindowOriginFlags : u32 { None = 0, - LowerLeft = BIT(0), - FlipY = BIT(4), // Only for the purpose of figuring out polygon winding + LowerLeft = ZTD_BIT(0), + FlipY = ZTD_BIT(4), // Only for the purpose of figuring out polygon winding }; -ENABLE_ENUM_BITWISE_OPERATORS(WindowOriginFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(WindowOriginFlags) enum class ViewportSwizzle : u32 { PositiveX = 0, @@ -571,8 +571,9 @@ class ThreeD : public EngineWithRegsBase, public InlineBase { renderer::ShaderType::Count)] = {nullptr}; // State - Range bound_const_buffers[static_cast(ShaderStage::Count) - 1] - [CONST_BUFFER_BINDING_COUNT]; + ztd::Range + bound_const_buffers[static_cast(ShaderStage::Count) - 1] + [CONST_BUFFER_BINDING_COUNT]; // Methods DEFINE_INLINE_ENGINE_METHODS; diff --git a/src/core/hw/tegra_x1/gpu/engines/const.hpp b/src/core/hw/tegra_x1/gpu/engines/const.hpp index 9d893c5f..d6124f7d 100644 --- a/src/core/hw/tegra_x1/gpu/engines/const.hpp +++ b/src/core/hw/tegra_x1/gpu/engines/const.hpp @@ -8,7 +8,9 @@ struct Iova { u32 hi; u32 lo; - operator u64() const { return static_cast(hi) << 32 | static_cast(lo); } + operator u64() const { + return static_cast(hi) << 32 | static_cast(lo); + } }; enum class Winding : u32 { @@ -161,13 +163,13 @@ inline i32 get_block_size_log2(const BlockDim dim) { enum class ColorWriteMask : u32 { None = 0, - Red = BIT(0), - Green = BIT(4), - Blue = BIT(8), - Alpha = BIT(12), + Red = ZTD_BIT(0), + Green = ZTD_BIT(4), + Blue = ZTD_BIT(8), + Alpha = ZTD_BIT(12), All = Red | Green | Blue | Alpha, }; -ENABLE_ENUM_BITWISE_OPERATORS(ColorWriteMask) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(ColorWriteMask) } // namespace hydra::hw::tegra_x1::gpu::engines diff --git a/src/core/hw/tegra_x1/gpu/engines/copy.cpp b/src/core/hw/tegra_x1/gpu/engines/copy.cpp index 05bccc76..3aacc271 100644 --- a/src/core/hw/tegra_x1/gpu/engines/copy.cpp +++ b/src/core/hw/tegra_x1/gpu/engines/copy.cpp @@ -82,7 +82,7 @@ void Copy::LaunchDMA(const u32 index, const LaunchDMAData data) { // Invalidate memory if (data.dst_memory_layout == MemoryLayout::Pitch) { gpu.GetRenderer().InvalidateMemory( - Range::FromSize(dst_ptr, regs.line_count * regs.stride_out), + ztd::Range::fromSize(dst_ptr, regs.line_count * regs.stride_out), renderer::MemoryInvalidationScope::BufferCache | renderer::MemoryInvalidationScope::TextureCache); } else { @@ -95,7 +95,7 @@ void Copy::LaunchDMA(const u32 index, const LaunchDMAData data) { align(regs.dst.depth, 1u << static_cast(get_block_size_log2( regs.dst.block_size.depth))); gpu.GetRenderer().InvalidateMemory( - Range::FromSize(dst_ptr, + ztd::Range::fromSize(dst_ptr, static_cast(slices * rows * stride)), renderer::MemoryInvalidationScope::TextureCache); } diff --git a/src/core/hw/tegra_x1/gpu/engines/engine_base.hpp b/src/core/hw/tegra_x1/gpu/engines/engine_base.hpp index fbdf6573..5bead8d4 100644 --- a/src/core/hw/tegra_x1/gpu/engines/engine_base.hpp +++ b/src/core/hw/tegra_x1/gpu/engines/engine_base.hpp @@ -14,7 +14,7 @@ return; \ } \ switch (method) { \ - FOR_EACH_0_4(METHOD_CASE, __VA_ARGS__) \ + ZTD_FOR_EACH_0_4(METHOD_CASE, __VA_ARGS__) \ default: \ WriteReg(method, arg); \ break; \ diff --git a/src/core/hw/tegra_x1/gpu/engines/inline_base.cpp b/src/core/hw/tegra_x1/gpu/engines/inline_base.cpp index bcfd8b59..00a87853 100644 --- a/src/core/hw/tegra_x1/gpu/engines/inline_base.cpp +++ b/src/core/hw/tegra_x1/gpu/engines/inline_base.cpp @@ -31,7 +31,7 @@ void InlineBase::LoadInlineDataImpl(Gpu& gpu, RegsInline& regs, const u32 index, // Invalidate gpu.GetRenderer().InvalidateMemory( - Range::FromSize(dst_ptr, inline_data.size() * sizeof(u32))); + ztd::Range::fromSize(dst_ptr, inline_data.size() * sizeof(u32))); } } diff --git a/src/core/hw/tegra_x1/gpu/gmmu.cpp b/src/core/hw/tegra_x1/gpu/gmmu.cpp index ae0af09f..5e7e8714 100644 --- a/src/core/hw/tegra_x1/gpu/gmmu.cpp +++ b/src/core/hw/tegra_x1/gpu/gmmu.cpp @@ -13,24 +13,24 @@ uptr GMmu::UnmapAddr(uptr gpu_addr) const { return as.ptr + (gpu_addr - base); } -uptr GMmu::CreateAddressSpace(Range range, uptr gpu_addr) { +uptr GMmu::CreateAddressSpace(ztd::Range range, uptr gpu_addr) { uptr ptr; - if (range.GetBegin() != 0x0) { - ptr = mmu->UnmapAddr(range.GetBegin()); + if (range.getBegin() != 0x0) { + ptr = mmu->UnmapAddr(range.getBegin()); // Write tracking mmu->EnableWriteTracking(range); } else { - ptr = reinterpret_cast(malloc(range.GetSize())); + ptr = reinterpret_cast(malloc(range.getSize())); } AddressSpace as; as.ptr = ptr; - as.size = range.GetSize(); + as.size = range.getSize(); if (gpu_addr == invalid()) { gpu_addr = address_space_base; - address_space_base += align(range.GetSize(), GPU_PAGE_SIZE); + address_space_base += align(range.getSize(), GPU_PAGE_SIZE); } Map(gpu_addr, as); diff --git a/src/core/hw/tegra_x1/gpu/gmmu.hpp b/src/core/hw/tegra_x1/gpu/gmmu.hpp index 731cdbf4..db20f72a 100644 --- a/src/core/hw/tegra_x1/gpu/gmmu.hpp +++ b/src/core/hw/tegra_x1/gpu/gmmu.hpp @@ -39,14 +39,14 @@ class GMmu : public GenericMmu { [[maybe_unused]] AddressSpace as) {} // Address space - uptr CreateAddressSpace(Range range, uptr gpu_addr); + uptr CreateAddressSpace(ztd::Range range, uptr gpu_addr); uptr AllocatePrivateAddressSpace(u64 size, uptr gpu_addr) { - return CreateAddressSpace(Range::FromSize(0x0, size), + return CreateAddressSpace(ztd::Range::fromSize(0x0, size), gpu_addr); } - uptr MapBufferToAddressSpace(Range range, uptr gpu_addr) { + uptr MapBufferToAddressSpace(ztd::Range range, uptr gpu_addr) { return CreateAddressSpace(range, gpu_addr); } diff --git a/src/core/hw/tegra_x1/gpu/gpu.cpp b/src/core/hw/tegra_x1/gpu/gpu.cpp index f0a8977d..23330670 100644 --- a/src/core/hw/tegra_x1/gpu/gpu.cpp +++ b/src/core/hw/tegra_x1/gpu/gpu.cpp @@ -3,7 +3,7 @@ #include "core/hw/tegra_x1/cpu/mmu.hpp" #include "core/hw/tegra_x1/gpu/const.hpp" -#ifdef PLATFORM_APPLE +#ifdef ZTD_PLATFORM_APPLE #include "core/hw/tegra_x1/gpu/renderer/metal/renderer.hpp" #endif #include "core/hw/tegra_x1/gpu/renderer/null/renderer.hpp" @@ -16,7 +16,7 @@ renderer::IRenderer* CreateRenderer() { const auto renderer_type = CONFIG_INSTANCE.GetGpuRenderer(); switch (renderer_type) { case GpuRenderer::Metal: -#ifdef PLATFORM_APPLE +#ifdef ZTD_PLATFORM_APPLE return new renderer::metal::Renderer(); #else LOG_FATAL(Gpu, "Metal renderer not supported"); @@ -37,8 +37,8 @@ struct SetObjectArg { Gpu::Gpu() : pfifo(*this), three_d_engine(*this), compute_engine(*this), - inline_engine(*this), two_d_engine(*this), - copy_engine(*this), renderer{CreateRenderer()} {} + inline_engine(*this), two_d_engine(*this), copy_engine(*this), + renderer{CreateRenderer()} {} void Gpu::SubchannelMethod(u32 subchannel, u32 method, u32 arg) { if (method == 0x0) { // SetEngine @@ -103,7 +103,7 @@ Gpu::GetTexture(renderer::ICommandBuffer* command_buffer, cpu::IMmu* mmu, // TODO: why are there more planes? const renderer::TextureDescriptor descriptor( - mmu->UnmapAddr(GetMap(static_cast(buff.nvmap_id)).addr + + mmu->UnmapAddr(GetMap(static_cast(buff.nvmap_id)).value()->addr + plane.offset), renderer::TextureType::_2D, renderer::to_texture_format(plane.color_format), is_linear, plane.pitch, diff --git a/src/core/hw/tegra_x1/gpu/gpu.hpp b/src/core/hw/tegra_x1/gpu/gpu.hpp index de501551..5924450d 100644 --- a/src/core/hw/tegra_x1/gpu/gpu.hpp +++ b/src/core/hw/tegra_x1/gpu/gpu.hpp @@ -38,29 +38,23 @@ class Gpu { // Memory map u32 CreateMap(u64 size) { - handle_id_t handle_id = memory_maps.AllocateHandle(); - MemoryMap& memory_map = memory_maps.Get(handle_id); - memory_map = {}; - memory_map.size = size; - - // TODO: is this hack still needed? - // HACK: allocate one more index. Games are probably confused with - // handle IDs and IDs - memory_maps.AllocateHandle(); - - return handle_id; + return memory_maps.insert(0, size).value_or(INVALID_HANDLE_ID); } void AllocateMap(handle_id_t handle_id, uptr addr, bool write) { - MemoryMap& memory_map = memory_maps.Get(handle_id); - memory_map.addr = addr; - memory_map.write = write; + // TODO: error? + ZTD_ASSIGN_OR_RETURN(auto memory_map, memory_maps.get(handle_id)); + memory_map->addr = addr; + memory_map->write = write; } - void FreeMap(handle_id_t handle_id) { memory_maps.Free(handle_id); } + void FreeMap(handle_id_t handle_id) { + ASSERT_DEBUG(memory_maps.free(handle_id), Gpu, + "Failed to free map {:#x}", handle_id); + } - MemoryMap& GetMap(handle_id_t handle_id) { - return memory_maps.Get(handle_id); + std::optional GetMap(handle_id_t handle_id) { + return memory_maps.get(handle_id); } // Engines @@ -105,7 +99,8 @@ class Gpu { std::unique_ptr renderer; // Memory - DynamicPool memory_maps; + // TODO: dynamic pool? + ztd::mem::StaticPool memory_maps; }; } // namespace hydra::hw::tegra_x1::gpu diff --git a/src/core/hw/tegra_x1/gpu/macro/const.hpp b/src/core/hw/tegra_x1/gpu/macro/const.hpp index efe0e2b0..111798db 100644 --- a/src/core/hw/tegra_x1/gpu/macro/const.hpp +++ b/src/core/hw/tegra_x1/gpu/macro/const.hpp @@ -45,7 +45,7 @@ enum class ResultOperation : int32_t { }; constexpr usize REG_COUNT = 8; -constexpr u32 EXIT_BIT = BIT(7); +constexpr u32 EXIT_BIT = ZTD_BIT(7); } // namespace hydra::hw::tegra_x1::gpu::macro diff --git a/src/core/hw/tegra_x1/gpu/renderer/buffer_base.hpp b/src/core/hw/tegra_x1/gpu/renderer/buffer_base.hpp index 0c2b4b21..b2c32f84 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/buffer_base.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/buffer_base.hpp @@ -30,8 +30,8 @@ class BufferBase { } virtual void CopyFrom(ICommandBuffer* command_buffer, ITextureView* src, const uint3 src_origin, const uint3 src_size, - const Range src_levels, - const Range src_layers, u64 dst_offset = 0) = 0; + const ztd::Range src_levels, + const ztd::Range src_layers, u64 dst_offset = 0) = 0; protected: u64 size; diff --git a/src/core/hw/tegra_x1/gpu/renderer/buffer_cache.cpp b/src/core/hw/tegra_x1/gpu/renderer/buffer_cache.cpp index 6b994c0f..34b825e5 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/buffer_cache.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/buffer_cache.cpp @@ -10,12 +10,12 @@ BufferCache::~BufferCache() { delete entry.second.buffer; } -BufferView BufferCache::Get(ICommandBuffer* command_buffer, Range range) { +BufferView BufferCache::Get(ICommandBuffer* command_buffer, ztd::Range range) { auto& entry = Find(range); if (entry.buffer != nullptr) { // Check for memory invalidation if (entry.invalidation_range.has_value() && - entry.invalidation_range->Intersects(range)) { + entry.invalidation_range->intersects(range)) { const auto invalidation_range = entry.invalidation_range.value(); UpdateRange(command_buffer, entry, invalidation_range); entry.invalidation_range = std::nullopt; @@ -25,28 +25,28 @@ BufferView BufferCache::Get(ICommandBuffer* command_buffer, Range range) { } } else { // Create new buffer - entry.buffer = renderer.CreateBuffer(entry.range.GetSize()); + entry.buffer = renderer.CreateBuffer(entry.range.getSize()); UpdateRange(command_buffer, entry, entry.range); } - return {entry.buffer, range.GetBegin() - entry.range.GetBegin(), - range.GetSize()}; + return {entry.buffer, range.getBegin() - entry.range.getBegin(), + range.getSize()}; } -void BufferCache::InvalidateMemory(Range range) { - auto it = entries.upper_bound(range.GetBegin()); +void BufferCache::InvalidateMemory(ztd::Range range) { + auto it = entries.upper_bound(range.getBegin()); if (it != entries.begin()) it--; while (it != entries.end() && - it->second.range.GetBegin() < range.GetEnd()) { + it->second.range.getBegin() < range.getEnd()) { auto& entry = it->second; - if (entry.range.GetEnd() > range.GetBegin()) { - const auto invalidation_range = range.ClampedTo(entry.range); + if (entry.range.getEnd() > range.getBegin()) { + const auto invalidation_range = range.clampedTo(entry.range); if (entry.invalidation_range.has_value()) { // Combine with an existing invalidation range if it exists entry.invalidation_range = - entry.invalidation_range.value().Union(invalidation_range); + entry.invalidation_range.value().merged(invalidation_range); } else { // Set the range directly entry.invalidation_range = invalidation_range; @@ -57,30 +57,30 @@ void BufferCache::InvalidateMemory(Range range) { } void BufferCache::UpdateRange(ICommandBuffer* command_buffer, - BufferEntry& entry, Range range) { + BufferEntry& entry, ztd::Range range) { if (entry.inline_copy) { // Do an inline update if possible - entry.buffer->CopyFrom(range.GetBegin(), - range.GetBegin() - entry.range.GetBegin(), - range.GetSize()); + entry.buffer->CopyFrom(range.getBegin(), + range.getBegin() - entry.range.getBegin(), + range.getSize()); entry.inline_copy = false; } else { // Copy from a temporary buffer - auto tmp_buffer = renderer.AllocateTemporaryBuffer(range.GetSize()); - tmp_buffer->CopyFrom(range.GetBegin()); + auto tmp_buffer = renderer.AllocateTemporaryBuffer(range.getSize()); + tmp_buffer->CopyFrom(range.getBegin()); entry.buffer->CopyFrom(command_buffer, tmp_buffer, - range.GetBegin() - entry.range.GetBegin(), 0, - range.GetSize()); + range.getBegin() - entry.range.getBegin(), 0, + range.getSize()); renderer.FreeTemporaryBuffer(tmp_buffer); } } -BufferEntry& BufferCache::Find(Range range) { +BufferEntry& BufferCache::Find(ztd::Range range) { // Check for containing interval - auto it = entries.upper_bound(range.GetBegin()); + auto it = entries.upper_bound(range.getBegin()); if (it != entries.begin()) { auto prev = std::prev(it); - if (prev->second.range.GetEnd() >= range.GetEnd()) { + if (prev->second.range.getEnd() >= range.getEnd()) { // Fully contained return prev->second; } @@ -89,30 +89,30 @@ BufferEntry& BufferCache::Find(Range range) { // Insert and merge auto new_range = range; - it = entries.lower_bound(range.GetBegin()); + it = entries.lower_bound(range.getBegin()); // Merge with previous if overlapping/touching if (it != entries.begin()) { auto prev = std::prev(it); - if (prev->second.range.GetEnd() >= new_range.GetBegin()) { - new_range = Range( - prev->second.range.GetBegin(), - std::max(new_range.GetEnd(), prev->second.range.GetEnd())); + if (prev->second.range.getEnd() >= new_range.getBegin()) { + new_range = ztd::Range( + prev->second.range.getBegin(), + std::max(new_range.getEnd(), prev->second.range.getEnd())); it = entries.erase(prev); } } // Merge with following entries - while (it != entries.end() && it->first <= new_range.GetEnd()) { - new_range = Range( - new_range.GetBegin(), - std::max(new_range.GetEnd(), it->second.range.GetEnd())); + while (it != entries.end() && it->first <= new_range.getEnd()) { + new_range = ztd::Range( + new_range.getBegin(), + std::max(new_range.getEnd(), it->second.range.getEnd())); it = entries.erase(it); } // Insert merged interval auto inserted = - entries.emplace(new_range.GetBegin(), + entries.emplace(new_range.getBegin(), BufferEntry{.buffer = nullptr, .range = new_range}); return inserted.first->second; diff --git a/src/core/hw/tegra_x1/gpu/renderer/buffer_cache.hpp b/src/core/hw/tegra_x1/gpu/renderer/buffer_cache.hpp index e12638fa..5c7e1992 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/buffer_cache.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/buffer_cache.hpp @@ -13,8 +13,8 @@ class IRenderer; // TODO: also release the buffer struct BufferEntry { BufferBase* buffer{nullptr}; - Range range; - std::optional> invalidation_range; + ztd::Range range; + std::optional> invalidation_range; bool inline_copy{false}; // TODO: implement }; @@ -24,9 +24,9 @@ class BufferCache { BufferCache(IRenderer& renderer_) : renderer{renderer_} {} ~BufferCache(); - BufferView Get(ICommandBuffer* command_buffer, Range range); + BufferView Get(ICommandBuffer* command_buffer, ztd::Range range); - void InvalidateMemory(Range range); + void InvalidateMemory(ztd::Range range); private: IRenderer& renderer; @@ -36,8 +36,8 @@ class BufferCache { // Helpers void UpdateRange(ICommandBuffer* command_buffer, BufferEntry& entry, - Range range); - BufferEntry& Find(Range range); + ztd::Range range); + BufferEntry& Find(ztd::Range range); public: REF_GETTER(mutex, GetMutex); diff --git a/src/core/hw/tegra_x1/gpu/renderer/buffer_view.hpp b/src/core/hw/tegra_x1/gpu/renderer/buffer_view.hpp index 7461d8d9..4496f011 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/buffer_view.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/buffer_view.hpp @@ -31,7 +31,7 @@ struct BufferView { } void CopyFrom(ICommandBuffer* command_buffer, ITextureView* src, const uint3 src_origin, const uint3 src_size, - const Range src_levels, const Range src_layers) { + const ztd::Range src_levels, const ztd::Range src_layers) { base->CopyFrom(command_buffer, src, src_origin, src_size, src_levels, src_layers, offset); } diff --git a/src/core/hw/tegra_x1/gpu/renderer/const.cpp b/src/core/hw/tegra_x1/gpu/renderer/const.cpp index 48b8355b..8aff5853 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/const.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/const.cpp @@ -622,33 +622,33 @@ SwizzleChannels::SwizzleChannels(const TextureFormat format, } u32 TextureDescriptor::GetGroupHash() const { - HashCode hash; - hash.Add(GetTextureTypeClass(type)); + ztd::hash::XxHash32 hash; + hash.add(GetTextureTypeClass(type)); const auto& format_info = GetTextureFormatInfo(format); // TODO: make sure BC and ASTC formats are incompatible - hash.Add(format_info.bytes_per_block); - hash.Add(format_info.block_width); - hash.Add(format_info.block_height); - hash.Add(format_info.is_depth_stencil); + hash.add(format_info.bytes_per_block); + hash.add(format_info.block_width); + hash.add(format_info.block_height); + hash.add(format_info.is_depth_stencil); - return hash.ToHashCode(); + return hash.toHashCode(); } u32 TextureDescriptor::GetStorageHash() const { - HashCode hash; - hash.Add(ptr); + ztd::hash::XxHash32 hash; + hash.add(ptr); if (is_linear) - hash.Add(linear_stride); - hash.Add(width); - hash.Add(height); - hash.Add(depth); - hash.Add(level_count); - hash.Add(layer_count); + hash.add(linear_stride); + hash.add(width); + hash.add(height); + hash.add(depth); + hash.add(level_count); + hash.add(layer_count); // TODO: block size? - hash.Add(layer_size); + hash.add(layer_size); - return hash.ToHashCode(); + return hash.toHashCode(); } namespace { @@ -759,19 +759,19 @@ void TextureDescriptor::CalculateSize() { } u32 TextureViewDescriptor::GetHash() const { - HashCode hash; - hash.Add(type); - hash.Add(format); - hash.Add(levels.GetBegin()); - hash.Add(levels.GetEnd()); - hash.Add(layers.GetBegin()); - hash.Add(layers.GetEnd()); - hash.Add(swizzle_channels.r); - hash.Add(swizzle_channels.g); - hash.Add(swizzle_channels.b); - hash.Add(swizzle_channels.a); - - return hash.ToHashCode(); + ztd::hash::XxHash32 hash; + hash.add(type); + hash.add(format); + hash.add(levels.getBegin()); + hash.add(levels.getEnd()); + hash.add(layers.getBegin()); + hash.add(layers.getEnd()); + hash.add(swizzle_channels.r); + hash.add(swizzle_channels.g); + hash.add(swizzle_channels.b); + hash.add(swizzle_channels.a); + + return hash.toHashCode(); } usize get_vertex_format_size(engines::VertexAttribSize size) { diff --git a/src/core/hw/tegra_x1/gpu/renderer/const.hpp b/src/core/hw/tegra_x1/gpu/renderer/const.hpp index b9944ccb..0d6ab86c 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/const.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/const.hpp @@ -249,7 +249,7 @@ struct TextureDescriptor { CalculateSize(); } - Range GetRange() const { return Range::FromSize(ptr, size); } + ztd::Range GetRange() const { return ztd::Range::fromSize(ptr, size); } u32 GetGroupHash() const; u32 GetStorageHash() const; @@ -266,12 +266,12 @@ struct TextureDescriptor { struct TextureViewDescriptor { TextureType type; TextureFormat format; - Range levels; - Range layers; + ztd::Range levels; + ztd::Range layers; SwizzleChannels swizzle_channels; TextureViewDescriptor(TextureType type_, TextureFormat format_, - Range levels_, Range layers_, + ztd::Range levels_, ztd::Range layers_, SwizzleChannels swizzle_channels_ = SwizzleChannels()) : type{type_}, format{format_}, levels{levels_}, layers{layers_}, swizzle_channels{swizzle_channels_} {} diff --git a/src/core/hw/tegra_x1/gpu/renderer/index_cache.cpp b/src/core/hw/tegra_x1/gpu/renderer/index_cache.cpp index 5974eb82..dc8c6d52 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/index_cache.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/index_cache.cpp @@ -161,7 +161,7 @@ BufferView IndexCache::Decode(ICommandBuffer* command_buffer, static_cast(out_count * index_size)); uptr in_ptr = 0x0; if (descriptor.mem_range) - in_ptr = descriptor.mem_range->GetBegin(); + in_ptr = descriptor.mem_range->getBegin(); auto out_ptr = index_buffer->GetPtr(); #define DECODE(name) decode_##name(in_ptr, out_ptr, out_type, descriptor.count) @@ -183,15 +183,15 @@ BufferView IndexCache::Decode(ICommandBuffer* command_buffer, } // namespace hydra::hw::tegra_x1::gpu::renderer u32 IndexCache::Hash(const IndexDescriptor& descriptor) { - HashCode hash; - hash.Add(descriptor.type); - hash.Add(descriptor.primitive_type); + ztd::hash::XxHash32 hash; + hash.add(descriptor.type); + hash.add(descriptor.primitive_type); if (descriptor.mem_range) { - hash.Add(descriptor.mem_range->GetBegin()); - hash.Add(descriptor.mem_range->GetEnd()); + hash.add(descriptor.mem_range->getBegin()); + hash.add(descriptor.mem_range->getEnd()); } - hash.Add(descriptor.count); - return hash.ToHashCode(); + hash.add(descriptor.count); + return hash.toHashCode(); } } // namespace hydra::hw::tegra_x1::gpu::renderer diff --git a/src/core/hw/tegra_x1/gpu/renderer/index_cache.hpp b/src/core/hw/tegra_x1/gpu/renderer/index_cache.hpp index a3688b16..5670ca86 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/index_cache.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/index_cache.hpp @@ -11,7 +11,7 @@ struct IndexDescriptor { engines::IndexType type; engines::PrimitiveType primitive_type; u32 count; - std::optional> mem_range{std::nullopt}; + std::optional> mem_range{std::nullopt}; }; // TODO: memory invalidation diff --git a/src/core/hw/tegra_x1/gpu/renderer/metal/buffer.cpp b/src/core/hw/tegra_x1/gpu/renderer/metal/buffer.cpp index dc99c62d..9cf248f6 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/metal/buffer.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/metal/buffer.cpp @@ -17,7 +17,7 @@ Buffer::~Buffer() { buffer->release(); } void Buffer::CopyFrom(ICommandBuffer* command_buffer, ITextureView* src, const uint3 src_origin, const uint3 src_size, - const Range src_levels, const Range src_layers, + const ztd::Range src_levels, const ztd::Range src_layers, u64 dst_offset) { const auto command_buffer_impl = static_cast(command_buffer); @@ -26,9 +26,9 @@ void Buffer::CopyFrom(ICommandBuffer* command_buffer, ITextureView* src, auto blit_encoder = command_buffer_impl->GetBlitCommandEncoder(); // TODO: bytes per image // TODO: calculate the stride for the Metal pixel format - for (u32 layer = src_layers.GetBegin(); layer < src_layers.GetEnd(); + for (u32 layer = src_layers.getBegin(); layer < src_layers.getEnd(); layer++) { - for (u32 level = src_levels.GetBegin(); level < src_levels.GetEnd(); + for (u32 level = src_levels.getBegin(); level < src_levels.getEnd(); level++) { blit_encoder->copyFromTexture( src_impl->GetTexture(), layer, level, diff --git a/src/core/hw/tegra_x1/gpu/renderer/metal/buffer.hpp b/src/core/hw/tegra_x1/gpu/renderer/metal/buffer.hpp index d9aa1983..e67f34e1 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/metal/buffer.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/metal/buffer.hpp @@ -18,7 +18,7 @@ class Buffer final : public BufferBase { // Copying void CopyFrom(ICommandBuffer* command_buffer, ITextureView* src, const uint3 src_origin, const uint3 src_size, - const Range src_levels, const Range src_layers, + const ztd::Range src_levels, const ztd::Range src_layers, u64 dst_offset) override; private: diff --git a/src/core/hw/tegra_x1/gpu/renderer/metal/clear_color_pipeline_cache.cpp b/src/core/hw/tegra_x1/gpu/renderer/metal/clear_color_pipeline_cache.cpp index 2e55be3b..556b55a2 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/metal/clear_color_pipeline_cache.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/metal/clear_color_pipeline_cache.cpp @@ -73,13 +73,13 @@ MTL::RenderPipelineState* ClearColorPipelineCache::Create( color_attachment->setPixelFormat(descriptor.pixel_format); MTL::ColorWriteMask mask = MTL::ColorWriteMaskNone; - if ((descriptor.mask & BIT(0)) != 0u) + if ((descriptor.mask & ZTD_BIT(0)) != 0u) mask |= MTL::ColorWriteMaskRed; - if ((descriptor.mask & BIT(1)) != 0u) + if ((descriptor.mask & ZTD_BIT(1)) != 0u) mask |= MTL::ColorWriteMaskGreen; - if ((descriptor.mask & BIT(2)) != 0u) + if ((descriptor.mask & ZTD_BIT(2)) != 0u) mask |= MTL::ColorWriteMaskBlue; - if ((descriptor.mask & BIT(3)) != 0u) + if ((descriptor.mask & ZTD_BIT(3)) != 0u) mask |= MTL::ColorWriteMaskAlpha; color_attachment->setWriteMask(mask); @@ -98,11 +98,11 @@ MTL::RenderPipelineState* ClearColorPipelineCache::Create( u32 ClearColorPipelineCache::Hash( const ClearColorPipelineDescriptor& descriptor) { - HashCode hash; - hash.Add(descriptor.pixel_format); - hash.Add(descriptor.render_target_id); - hash.Add(descriptor.mask); - return hash.ToHashCode(); + ztd::hash::XxHash32 hash; + hash.add(descriptor.pixel_format); + hash.add(descriptor.render_target_id); + hash.add(descriptor.mask); + return hash.toHashCode(); } void ClearColorPipelineCache::DestroyElement( diff --git a/src/core/hw/tegra_x1/gpu/renderer/metal/depth_stencil_state_cache.cpp b/src/core/hw/tegra_x1/gpu/renderer/metal/depth_stencil_state_cache.cpp index 78a05af2..16781a3f 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/metal/depth_stencil_state_cache.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/metal/depth_stencil_state_cache.cpp @@ -23,11 +23,11 @@ DepthStencilStateCache::Create(const DepthStencilStateDescriptor& descriptor) { u32 DepthStencilStateCache::Hash( const DepthStencilStateDescriptor& descriptor) { - HashCode hash; - hash.Add(descriptor.depth_test_enabled); - hash.Add(descriptor.depth_write_enabled); - hash.Add(descriptor.depth_compare_op); - return hash.ToHashCode(); + ztd::hash::XxHash32 hash; + hash.add(descriptor.depth_test_enabled); + hash.add(descriptor.depth_write_enabled); + hash.add(descriptor.depth_compare_op); + return hash.toHashCode(); } void DepthStencilStateCache::DestroyElement( diff --git a/src/core/hw/tegra_x1/gpu/renderer/metal/maxwell_to_mtl.cpp b/src/core/hw/tegra_x1/gpu/renderer/metal/maxwell_to_mtl.cpp index dd9957dd..c58426f1 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/metal/maxwell_to_mtl.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/metal/maxwell_to_mtl.cpp @@ -28,20 +28,20 @@ MTL::TextureType ToMtlTextureType(TextureType type) { { \ TextureFormat::format, { \ MTL::PixelFormat##pixel_format, has_depth, has_stencil, \ - PASS(component_indices) \ + ZTD_PASS(component_indices) \ } \ } #define DS_PIXEL_FORMAT_ENTRY(format, pixel_format, has_depth, has_stencil) \ PIXEL_FORMAT_ENTRY(format, pixel_format, has_depth, has_stencil, \ - PASS({0, 1, 2, 3})) + ZTD_PASS({0, 1, 2, 3})) #define COLOR_PIXEL_FORMAT_ENTRY(format, pixel_format, component_indices) \ PIXEL_FORMAT_ENTRY(format, pixel_format, false, false, \ - PASS(component_indices)) + ZTD_PASS(component_indices)) #define COLOR_PIXEL_FORMAT_ENTRY_RGBA(format, pixel_format) \ - COLOR_PIXEL_FORMAT_ENTRY(format, pixel_format, PASS({0, 1, 2, 3})) + COLOR_PIXEL_FORMAT_ENTRY(format, pixel_format, ZTD_PASS({0, 1, 2, 3})) std::map pixel_format_lut = { COLOR_PIXEL_FORMAT_ENTRY_RGBA(R8Unorm, R8Unorm), @@ -93,10 +93,10 @@ std::map pixel_format_lut = { true), // HACK COLOR_PIXEL_FORMAT_ENTRY_RGBA(RGBX8Unorm_sRGB, RGBA8Unorm_sRGB), // HACK COLOR_PIXEL_FORMAT_ENTRY_RGBA(RGBA8Unorm_sRGB, RGBA8Unorm_sRGB), - COLOR_PIXEL_FORMAT_ENTRY(RGBA4Unorm, ABGR4Unorm, PASS({3, 2, 1, 0})), + COLOR_PIXEL_FORMAT_ENTRY(RGBA4Unorm, ABGR4Unorm, ZTD_PASS({3, 2, 1, 0})), COLOR_PIXEL_FORMAT_ENTRY_RGBA(RGB5Unorm, BGR5A1Unorm), // HACK COLOR_PIXEL_FORMAT_ENTRY(R5G6B5Unorm, B5G6R5Unorm, - PASS({2, 1, 0, 3})), // TODO: correct? + ZTD_PASS({2, 1, 0, 3})), // TODO: correct? COLOR_PIXEL_FORMAT_ENTRY_RGBA(RGB10A2Unorm, RGB10A2Unorm), COLOR_PIXEL_FORMAT_ENTRY_RGBA(RGB10A2Uint, RGB10A2Uint), COLOR_PIXEL_FORMAT_ENTRY_RGBA(RG11B10Float, RG11B10Float), diff --git a/src/core/hw/tegra_x1/gpu/renderer/metal/texture.cpp b/src/core/hw/tegra_x1/gpu/renderer/metal/texture.cpp index c817f587..c495670b 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/metal/texture.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/metal/texture.cpp @@ -56,8 +56,8 @@ Texture::CreateView(const TextureViewDescriptor& view_descriptor) { } void Texture::CopyFrom(ICommandBuffer* command_buffer, const BufferBase* src, - const Range dst_levels, - const Range dst_layers) { + const ztd::Range dst_levels, + const ztd::Range dst_layers) { const auto command_buffer_impl = static_cast(command_buffer); const auto mtl_src = static_cast(src)->GetBuffer(); @@ -65,9 +65,9 @@ void Texture::CopyFrom(ICommandBuffer* command_buffer, const BufferBase* src, auto encoder = command_buffer_impl->GetBlitCommandEncoder(); u32 offset = 0; - for (u32 layer = dst_layers.GetBegin(); layer < dst_layers.GetEnd(); + for (u32 layer = dst_layers.getBegin(); layer < dst_layers.getEnd(); layer++) { - for (u32 level = dst_levels.GetBegin(); level < dst_levels.GetEnd(); + for (u32 level = dst_levels.getBegin(); level < dst_levels.getEnd(); level++) { // Calculate sizes const auto dims = descriptor.GetLevelDimensions(level); diff --git a/src/core/hw/tegra_x1/gpu/renderer/metal/texture.hpp b/src/core/hw/tegra_x1/gpu/renderer/metal/texture.hpp index 463ac363..5b56b9e0 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/metal/texture.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/metal/texture.hpp @@ -15,8 +15,8 @@ class Texture final : public ITexture { // Copying void CopyFrom(ICommandBuffer* command_buffer, const BufferBase* src, - const Range dst_levels, - const Range dst_layers) override; + const ztd::Range dst_levels, + const ztd::Range dst_layers) override; void CopyFrom(ICommandBuffer* command_buffer, const ITexture* src, const u32 src_level, const u32 src_layer, const u32 dst_level, const u32 dst_layer, const u32 level_count, diff --git a/src/core/hw/tegra_x1/gpu/renderer/metal/texture_view.cpp b/src/core/hw/tegra_x1/gpu/renderer/metal/texture_view.cpp index 830f8cb5..a4f9c710 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/metal/texture_view.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/metal/texture_view.cpp @@ -27,15 +27,15 @@ TextureView::TextureView(Texture* base, const TextureViewDescriptor& descriptor) // Demote array types to non-array types if possible switch (type) { case TextureType::_1DArray: - if (descriptor.layers.GetSize() == 1) + if (descriptor.layers.getSize() == 1) type = TextureType::_1D; break; case TextureType::_2DArray: - if (descriptor.layers.GetSize() == 1) + if (descriptor.layers.getSize() == 1) type = TextureType::_2D; break; case TextureType::CubeArray: - if (descriptor.layers.GetSize() == 6) + if (descriptor.layers.getSize() == 6) type = TextureType::Cube; break; default: @@ -44,8 +44,8 @@ TextureView::TextureView(Texture* base, const TextureViewDescriptor& descriptor) texture = base->GetTexture()->newTextureView( to_mtl_pixel_format(descriptor.format), ToMtlTextureType(type), - NS::Range(descriptor.levels.GetBegin(), descriptor.levels.GetSize()), - NS::Range(descriptor.layers.GetBegin(), descriptor.layers.GetSize()), + NS::Range(descriptor.levels.getBegin(), descriptor.levels.getSize()), + NS::Range(descriptor.layers.getBegin(), descriptor.layers.getSize()), swizzle_channels_mtl); } diff --git a/src/core/hw/tegra_x1/gpu/renderer/null/buffer.cpp b/src/core/hw/tegra_x1/gpu/renderer/null/buffer.cpp index 64f710b9..a796fd40 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/null/buffer.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/null/buffer.cpp @@ -11,8 +11,8 @@ void Buffer::CopyFrom([[maybe_unused]] ICommandBuffer* command_buffer, [[maybe_unused]] ITextureView* src, [[maybe_unused]] const uint3 src_origin, [[maybe_unused]] const uint3 src_size, - [[maybe_unused]] const Range src_levels, - [[maybe_unused]] const Range src_layers, + [[maybe_unused]] const ztd::Range src_levels, + [[maybe_unused]] const ztd::Range src_layers, [[maybe_unused]] u64 dst_offset) {} void Buffer::CopyFromImpl([[maybe_unused]] const uptr data, diff --git a/src/core/hw/tegra_x1/gpu/renderer/null/buffer.hpp b/src/core/hw/tegra_x1/gpu/renderer/null/buffer.hpp index 0bb5f00a..83f400fe 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/null/buffer.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/null/buffer.hpp @@ -14,7 +14,7 @@ class Buffer final : public BufferBase { // Copying void CopyFrom(ICommandBuffer* command_buffer, ITextureView* src, const uint3 src_origin, const uint3 src_size, - const Range src_levels, const Range src_layers, + const ztd::Range src_levels, const ztd::Range src_layers, u64 dst_offset) override; private: @@ -28,4 +28,4 @@ class Buffer final : public BufferBase { GETTER(buffer, GetBuffer); }; -} // namespace hydra::hw::tegra_x1::gpu::renderer::null \ No newline at end of file +} // namespace hydra::hw::tegra_x1::gpu::renderer::null diff --git a/src/core/hw/tegra_x1/gpu/renderer/null/texture.cpp b/src/core/hw/tegra_x1/gpu/renderer/null/texture.cpp index 4789d017..29f20d4c 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/null/texture.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/null/texture.cpp @@ -12,8 +12,8 @@ Texture::CreateView(const TextureViewDescriptor& view_descriptor) { void Texture::CopyFrom([[maybe_unused]] ICommandBuffer* command_buffer, [[maybe_unused]] const BufferBase* src, - [[maybe_unused]] const Range dst_levels, - [[maybe_unused]] const Range dst_layers) {} + [[maybe_unused]] const ztd::Range dst_levels, + [[maybe_unused]] const ztd::Range dst_layers) {} void Texture::CopyFrom([[maybe_unused]] ICommandBuffer* command_buffer, [[maybe_unused]] const ITexture* src, [[maybe_unused]] const u32 src_level, diff --git a/src/core/hw/tegra_x1/gpu/renderer/null/texture.hpp b/src/core/hw/tegra_x1/gpu/renderer/null/texture.hpp index 7d516f88..bd4da621 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/null/texture.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/null/texture.hpp @@ -15,8 +15,8 @@ class Texture final : public ITexture { // Copying void CopyFrom(ICommandBuffer* command_buffer, const BufferBase* src, - const Range dst_levels, - const Range dst_layers) override; + const ztd::Range dst_levels, + const ztd::Range dst_layers) override; void CopyFrom(ICommandBuffer* command_buffer, const ITexture* src, const u32 src_level, const u32 src_layer, const u32 dst_level, const u32 dst_layer, const u32 level_count, diff --git a/src/core/hw/tegra_x1/gpu/renderer/pipeline_cache.cpp b/src/core/hw/tegra_x1/gpu/renderer/pipeline_cache.cpp index 5a9f35db..8300d941 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/pipeline_cache.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/pipeline_cache.cpp @@ -10,50 +10,50 @@ PipelineBase* PipelineCache::Create(const PipelineDescriptor& descriptor) { } u32 PipelineCache::Hash(const PipelineDescriptor& descriptor) { - HashCode hash; + ztd::hash::XxHash32 hash; // Shaders // TODO: use the shader hash instead of the pointer? - hash.Add(descriptor.shaders[0]); - hash.Add(descriptor.shaders[1]); + hash.add(descriptor.shaders[0]); + hash.add(descriptor.shaders[1]); // Vertex state // Vertex attributes for (const auto& vertex_attrib_state : descriptor.vertex_state.vertex_attrib_states) { - hash.Add(vertex_attrib_state.buffer_id); + hash.add(vertex_attrib_state.buffer_id); // is_fixed is in vertex shader hash - hash.Add(vertex_attrib_state.offset); + hash.add(vertex_attrib_state.offset); // size and type are in vertex shader hash - hash.Add(vertex_attrib_state.bgra); + hash.add(vertex_attrib_state.bgra); } // Vertex arrays for (const auto& vertex_array : descriptor.vertex_state.vertex_arrays) { - hash.Add(vertex_array.enable); - hash.Add(vertex_array.stride); - hash.Add(vertex_array.is_per_instance); - hash.Add(vertex_array.divisor); + hash.add(vertex_array.enable); + hash.add(vertex_array.stride); + hash.add(vertex_array.is_per_instance); + hash.add(vertex_array.divisor); } // Color state // Color targets for (const auto& color_target_state : descriptor.color_target_states) { - hash.Add(color_target_state.format); - hash.Add(color_target_state.blend_enabled); + hash.add(color_target_state.format); + hash.add(color_target_state.blend_enabled); if (color_target_state.blend_enabled) { - hash.Add(color_target_state.rgb_op); - hash.Add(color_target_state.src_rgb_factor); - hash.Add(color_target_state.dst_rgb_factor); - hash.Add(color_target_state.alpha_op); - hash.Add(color_target_state.src_alpha_factor); - hash.Add(color_target_state.dst_alpha_factor); + hash.add(color_target_state.rgb_op); + hash.add(color_target_state.src_rgb_factor); + hash.add(color_target_state.dst_rgb_factor); + hash.add(color_target_state.alpha_op); + hash.add(color_target_state.src_alpha_factor); + hash.add(color_target_state.dst_alpha_factor); } } - return hash.ToHashCode(); + return hash.toHashCode(); } void PipelineCache::DestroyElement(PipelineBase* pipeline) { delete pipeline; } diff --git a/src/core/hw/tegra_x1/gpu/renderer/render_pass_cache.cpp b/src/core/hw/tegra_x1/gpu/renderer/render_pass_cache.cpp index 67a86f07..44b89d2d 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/render_pass_cache.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/render_pass_cache.cpp @@ -11,15 +11,15 @@ RenderPassCache::Create(const RenderPassDescriptor& descriptor) { } u32 RenderPassCache::Hash(const RenderPassDescriptor& descriptor) { - HashCode hash; + ztd::hash::XxHash32 hash; // TODO: improve this // TODO: also hash metadata about clears for (const auto& color_target : descriptor.color_targets) - hash.Add(color_target.texture); - hash.Add(descriptor.depth_stencil_target.texture); + hash.add(color_target.texture); + hash.add(descriptor.depth_stencil_target.texture); - return hash.ToHashCode(); + return hash.toHashCode(); } void RenderPassCache::DestroyElement(RenderPassBase* render_pass) { diff --git a/src/core/hw/tegra_x1/gpu/renderer/renderer.hpp b/src/core/hw/tegra_x1/gpu/renderer/renderer.hpp index 5d459fee..fd714a1c 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/renderer.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/renderer.hpp @@ -34,11 +34,11 @@ struct Info { enum class MemoryInvalidationScope { None = 0, - BufferCache = BIT(0), - TextureCache = BIT(1), - ShaderCache = BIT(2), + BufferCache = ZTD_BIT(0), + TextureCache = ZTD_BIT(1), + ShaderCache = ZTD_BIT(2), }; -ENABLE_ENUM_BITWISE_OPERATORS(MemoryInvalidationScope) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(MemoryInvalidationScope) class IRenderer { public: @@ -49,7 +49,7 @@ class IRenderer { virtual ~IRenderer() = default; void InvalidateMemory( - Range range, + ztd::Range range, MemoryInvalidationScope scope = MemoryInvalidationScope::BufferCache | MemoryInvalidationScope::TextureCache | MemoryInvalidationScope::ShaderCache) { diff --git a/src/core/hw/tegra_x1/gpu/renderer/sampler_cache.cpp b/src/core/hw/tegra_x1/gpu/renderer/sampler_cache.cpp index ec6ea3ca..494fd534 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/sampler_cache.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/sampler_cache.cpp @@ -11,17 +11,17 @@ SamplerBase* SamplerCache::Create(const SamplerDescriptor& descriptor) { } u32 SamplerCache::Hash(const SamplerDescriptor& descriptor) { - HashCode hash; - hash.Add(descriptor.min_filter); - hash.Add(descriptor.mag_filter); - hash.Add(descriptor.mip_filter); - hash.Add(descriptor.address_mode_s); - hash.Add(descriptor.address_mode_t); - hash.Add(descriptor.address_mode_r); - hash.Add(descriptor.depth_compare_op); - hash.Add(descriptor.border_color_u); + ztd::hash::XxHash32 hash; + hash.add(descriptor.min_filter); + hash.add(descriptor.mag_filter); + hash.add(descriptor.mip_filter); + hash.add(descriptor.address_mode_s); + hash.add(descriptor.address_mode_t); + hash.add(descriptor.address_mode_r); + hash.add(descriptor.depth_compare_op); + hash.add(descriptor.border_color_u); - return hash.ToHashCode(); + return hash.toHashCode(); } void SamplerCache::DestroyElement(SamplerBase* sampler) { delete sampler; } diff --git a/src/core/hw/tegra_x1/gpu/renderer/shader_cache.cpp b/src/core/hw/tegra_x1/gpu/renderer/shader_cache.cpp index a01e4a29..cb0eeb68 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/shader_cache.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/shader_cache.cpp @@ -24,9 +24,9 @@ ShaderBase* ShaderCache::Create(const GuestShaderDescriptor& descriptor) { } u32 ShaderCache::Hash(const GuestShaderDescriptor& descriptor) { - HashCode hash; - hash.Add(descriptor.stage); - hash.Add(descriptor.code_ptr); + ztd::hash::XxHash32 hash; + hash.add(descriptor.stage); + hash.add(descriptor.code_ptr); // Take a few samples from the code // TODO: this should be limited by the size of the code @@ -35,7 +35,7 @@ u32 ShaderCache::Hash(const GuestShaderDescriptor& descriptor) { 0x1000)); // TODO: size code_stream.SeekBy(80); // Header for (u32 i = 0; i < 8; i++) { - hash.Add(code_stream.Read()); + hash.add(code_stream.Read()); code_stream.SeekBy(17); } @@ -43,9 +43,9 @@ u32 ShaderCache::Hash(const GuestShaderDescriptor& descriptor) { if (descriptor.stage == engines::ShaderStage::VertexB) { for (const auto& vertex_attrib_state : descriptor.state.vertex_attrib_states) { - hash.Add(vertex_attrib_state.is_fixed); - hash.Add(vertex_attrib_state.size); - hash.Add(vertex_attrib_state.type); + hash.add(vertex_attrib_state.is_fixed); + hash.add(vertex_attrib_state.size); + hash.add(vertex_attrib_state.type); } } @@ -53,11 +53,11 @@ u32 ShaderCache::Hash(const GuestShaderDescriptor& descriptor) { if (descriptor.stage == engines::ShaderStage::Fragment) { for (const auto& color_target_data_type : descriptor.state.color_target_data_types) { - hash.Add(color_target_data_type); + hash.add(color_target_data_type); } } - return hash.ToHashCode(); + return hash.toHashCode(); } void ShaderCache::DestroyElement(ShaderBase* shader) { delete shader; } diff --git a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/codegen/lang/msl/emitter.cpp b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/codegen/lang/msl/emitter.cpp index 9225883f..1669a52d 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/codegen/lang/msl/emitter.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/codegen/lang/msl/emitter.cpp @@ -250,7 +250,7 @@ void MslEmitter::EmitMainPrototype() { } WriteRaw("StageOut main_(StageIn __in [[stage_in]]"); -#define ADD_ARG(f, ...) WriteRaw(", " f PASS_VA_ARGS(__VA_ARGS__)) +#define ADD_ARG(f, ...) WriteRaw(", " f ZTD_PASS_VA_ARGS(__VA_ARGS__)) // Input SVs switch (context.type) { diff --git a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/const.hpp b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/const.hpp index 24ed18b0..94f59361 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/const.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/const.hpp @@ -120,11 +120,11 @@ inline bool IsTextureArray(TextureType type) { enum class TextureSampleFlags { None = 0, - IntCoords = BIT(0), - DepthCompare = BIT(1), - Lod = BIT(2), + IntCoords = ZTD_BIT(0), + DepthCompare = ZTD_BIT(1), + Lod = ZTD_BIT(2), }; -ENABLE_ENUM_BITWISE_OPERATORS(TextureSampleFlags) +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(TextureSampleFlags) enum class PixelImapType : u8 { Unused = 0, diff --git a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/const.hpp b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/const.hpp index 7ae6ac5b..9afe1876 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/const.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/const.hpp @@ -7,8 +7,9 @@ { \ /* TODO: comments */ \ /*BUILDER.OpDebugComment(fmt::format(f_comment \ - * PASS_VA_ARGS(__VA_ARGS__)));*/ \ - LOG_##log_level(ShaderDecompiler, f_log PASS_VA_ARGS(__VA_ARGS__)); \ + * ZTD_PASS_VA_ARGS(__VA_ARGS__)));*/ \ + LOG_##log_level(ShaderDecompiler, \ + f_log ZTD_PASS_VA_ARGS(__VA_ARGS__)); \ } #define COMMENT(f, ...) COMMENT_IMPL(DEBUG, f, f, __VA_ARGS__) #define COMMENT_NOT_IMPLEMENTED(f, ...) \ diff --git a/src/core/hw/tegra_x1/gpu/renderer/texture.hpp b/src/core/hw/tegra_x1/gpu/renderer/texture.hpp index b8981b66..b64f0566 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/texture.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/texture.hpp @@ -18,11 +18,11 @@ class ITexture { // Copying virtual void CopyFrom(ICommandBuffer* command_buffer, const BufferBase* src, - const Range dst_levels, - const Range dst_layers) = 0; + const ztd::Range dst_levels, + const ztd::Range dst_layers) = 0; void CopyFrom(ICommandBuffer* command_buffer, const BufferBase* src) { - CopyFrom(command_buffer, src, Range(0, descriptor.level_count), - Range(0, descriptor.layer_count)); + CopyFrom(command_buffer, src, ztd::Range(0, descriptor.level_count), + ztd::Range(0, descriptor.layer_count)); } virtual void CopyFrom(ICommandBuffer* command_buffer, const ITexture* src, const u32 src_level, const u32 src_layer, diff --git a/src/core/hw/tegra_x1/gpu/renderer/texture_cache.cpp b/src/core/hw/tegra_x1/gpu/renderer/texture_cache.cpp index 8f6995f4..a049635d 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/texture_cache.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/texture_cache.cpp @@ -26,8 +26,8 @@ ITextureView* TextureCache::Find(ICommandBuffer* command_buffer, TextureUsage usage) { return Find(command_buffer, descriptor, TextureViewDescriptor(descriptor.type, descriptor.format, - Range(0, descriptor.level_count), - Range(0, descriptor.layer_count), + ztd::Range(0, descriptor.level_count), + ztd::Range(0, descriptor.layer_count), SwizzleChannels()), usage); } @@ -39,11 +39,11 @@ ITextureView* TextureCache::Find(ICommandBuffer* command_buffer, const auto range = descriptor.GetRange(); // Check for containing interval - auto it = entries.upper_bound(range.GetBegin()); + auto it = entries.upper_bound(range.getBegin()); if (it != entries.begin()) { auto prev = std::prev(it); auto& prev_mem = prev->second; - if (prev_mem.range.GetEnd() >= range.GetEnd()) { + if (prev_mem.range.getEnd() >= range.getEnd()) { // Fully contained return AddToMemory(command_buffer, prev_mem, descriptor, view_descriptor, usage); @@ -53,37 +53,37 @@ ITextureView* TextureCache::Find(ICommandBuffer* command_buffer, // Insert and merge TextureMem mem{.range = range}; - it = entries.lower_bound(range.GetBegin()); + it = entries.lower_bound(range.getBegin()); // Merge with previous if overlapping if (it != entries.begin()) { auto prev = std::prev(it); auto& prev_mem = prev->second; - if (prev_mem.range.GetEnd() > mem.range.GetBegin()) { + if (prev_mem.range.getEnd() > mem.range.getBegin()) { MergeMemories(mem, prev_mem); it = entries.erase(prev); } } // Merge with following entries - while (it != entries.end() && it->first < mem.range.GetEnd()) { + while (it != entries.end() && it->first < mem.range.getEnd()) { auto& crnt_mem = it->second; MergeMemories(mem, crnt_mem); it = entries.erase(it); } // Insert merged interval - auto inserted = entries.emplace(mem.range.GetBegin(), std::move(mem)); + auto inserted = entries.emplace(mem.range.getBegin(), std::move(mem)); return AddToMemory(command_buffer, inserted.first->second, descriptor, view_descriptor, usage); } -void TextureCache::InvalidateMemory(Range range) { - auto it = entries.upper_bound(range.GetBegin()); +void TextureCache::InvalidateMemory(ztd::Range range) { + auto it = entries.upper_bound(range.getBegin()); if (it != entries.begin()) it--; - for (; it != entries.end() && it->first < range.GetEnd(); it++) { + for (; it != entries.end() && it->first < range.getEnd(); it++) { auto& mem = it->second; // We assume that textures that have been written to by the GPU are @@ -92,13 +92,13 @@ void TextureCache::InvalidateMemory(Range range) { continue; // Check if its in the range - if (mem.range.GetEnd() > range.GetBegin()) + if (mem.range.getEnd() > range.getBegin()) mem.info.MarkModified(); } } void TextureCache::MergeMemories(TextureMem& mem, TextureMem& other) { - mem.range = mem.range.Union(other.range); + mem.range = mem.range.merged(other.range); mem.info = { .modified_timestamp = std::max(mem.info.modified_timestamp, other.info.modified_timestamp), @@ -253,7 +253,7 @@ TextureCache::AddToMemory(ICommandBuffer* command_buffer, TextureMem& mem, for (auto& [key, storage] : group.cache) { const auto& other_descriptor = storage.base->GetDescriptor(); const auto other_range = other_descriptor.GetRange(); - if (other_range.Contains(range)) { + if (other_range.contains(range)) { u32 level; u32 layer; if (!CalculateLevelAndLayer(other_descriptor, descriptor, level, @@ -294,12 +294,12 @@ TextureCache::AddToMemory(ICommandBuffer* command_buffer, TextureMem& mem, command_buffer, *actual_storage, mem, TextureViewDescriptor( view_descriptor.type, view_descriptor.format, - Range::FromSize(level + - view_descriptor.levels.GetBegin(), - view_descriptor.levels.GetSize()), - Range::FromSize(layer + - view_descriptor.layers.GetBegin(), - view_descriptor.layers.GetSize()), + ztd::Range::fromSize(level + + view_descriptor.levels.getBegin(), + view_descriptor.levels.getSize()), + ztd::Range::fromSize(layer + + view_descriptor.layers.getBegin(), + view_descriptor.layers.getSize()), view_descriptor.swizzle_channels), usage); } @@ -321,10 +321,10 @@ TextureCache::AddToMemory(ICommandBuffer* command_buffer, TextureMem& mem, auto& storage = it->second; const auto& other_descriptor = storage.base->GetDescriptor(); const auto other_range = other_descriptor.GetRange(); - if (range.Intersects(other_range)) { + if (range.intersects(other_range)) { u32 layer = 0; u32 level = 0; - if (other_range.GetBegin() >= range.GetBegin()) { + if (other_range.getBegin() >= range.getBegin()) { if (!CalculateLevelAndLayer(descriptor, other_descriptor, level, layer)) { LOG_DEBUG(Gpu, @@ -442,7 +442,7 @@ void TextureCache::Update(ICommandBuffer* command_buffer, other_storage.base->GetDescriptor(); const auto other_range = other_descriptor.GetRange(); - if (range.Intersects(other_range)) { + if (range.intersects(other_range)) { const auto type_class = GetTextureTypeClass(descriptor.type); const auto other_type_class = @@ -493,14 +493,14 @@ void TextureCache::Synchronize2DWith2D(ICommandBuffer* command_buffer, const auto& descriptor = storage.base->GetDescriptor(); const auto& other_descriptor = other_storage.base->GetDescriptor(); const auto copy_range = - descriptor.GetRange().ClampedTo(other_descriptor.GetRange()); + descriptor.GetRange().clampedTo(other_descriptor.GetRange()); u32 level; u32 layer; u32 other_level; u32 other_layer; if (!CalculateLevelAndLayer(descriptor, other_descriptor, - copy_range.GetBegin(), level, layer, + copy_range.getBegin(), level, layer, other_level, other_layer)) { LOG_DEBUG(Gpu, "Cannot synchronize 2D textures ({}) and ({})", descriptor, other_descriptor); @@ -522,14 +522,14 @@ void TextureCache::Synchronize3DWith3D(ICommandBuffer* command_buffer, const auto& descriptor = storage.base->GetDescriptor(); const auto& other_descriptor = other_storage.base->GetDescriptor(); const auto copy_range = - descriptor.GetRange().ClampedTo(other_descriptor.GetRange()); + descriptor.GetRange().clampedTo(other_descriptor.GetRange()); u32 level; u32 slice; u32 other_level; u32 other_slice; if (!CalculateLevelAndSlice(descriptor, other_descriptor, - copy_range.GetBegin(), level, slice, + copy_range.getBegin(), level, slice, other_level, other_slice)) { LOG_DEBUG(Gpu, "Cannot synchronize 3D textures ({}) and ({})", descriptor, other_descriptor); @@ -566,11 +566,11 @@ u32 TextureCache::GetDataHash(const ITexture* texture) { u64 mem_range = descriptor.size; u64 mem_step = std::max(mem_range / SAMPLE_COUNT, 1ull); - HashCode hash; + ztd::hash::XxHash32 hash; for (u64 offset = 0; offset < mem_range; offset += mem_step) - hash.Add(*reinterpret_cast(descriptor.ptr + offset)); + hash.add(*reinterpret_cast(descriptor.ptr + offset)); - return hash.ToHashCode(); + return hash.toHashCode(); } void TextureCache::DecodeTexture(ICommandBuffer* command_buffer, diff --git a/src/core/hw/tegra_x1/gpu/renderer/texture_cache.hpp b/src/core/hw/tegra_x1/gpu/renderer/texture_cache.hpp index ac693f05..c3533c92 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/texture_cache.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/texture_cache.hpp @@ -49,7 +49,7 @@ struct TextureMemInfo { }; struct TextureMem { - Range range; + ztd::Range range; TextureMemInfo info; SmallCache cache; @@ -78,7 +78,7 @@ class TextureCache { const TextureViewDescriptor& view_descriptor, TextureUsage usage); - void InvalidateMemory(Range range); + void InvalidateMemory(ztd::Range range); // Debug usize GetMemoryCount() const { return entries.size(); } diff --git a/src/core/hw/tegra_x1/gpu/renderer/texture_view.cpp b/src/core/hw/tegra_x1/gpu/renderer/texture_view.cpp index ecb62527..1b42bb23 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/texture_view.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/texture_view.cpp @@ -5,21 +5,21 @@ namespace hydra::hw::tegra_x1::gpu::renderer { void ITextureView::CopyFrom(ICommandBuffer* command_buffer, - const BufferBase* src, const Range dst_levels, - const Range dst_layers) { + const BufferBase* src, const ztd::Range dst_levels, + const ztd::Range dst_layers) { base->CopyFrom(command_buffer, src, - Range::FromSize(descriptor.levels.GetBegin() + - dst_levels.GetBegin(), - dst_levels.GetSize()), - Range::FromSize(descriptor.layers.GetBegin() + - dst_layers.GetBegin(), - dst_layers.GetSize())); + ztd::Range::fromSize(descriptor.levels.getBegin() + + dst_levels.getBegin(), + dst_levels.getSize()), + ztd::Range::fromSize(descriptor.layers.getBegin() + + dst_layers.getBegin(), + dst_layers.getSize())); } void ITextureView::CopyFrom(ICommandBuffer* command_buffer, const BufferBase* src) { - CopyFrom(command_buffer, src, Range(0, descriptor.levels.GetSize()), - Range(0, descriptor.layers.GetSize())); + CopyFrom(command_buffer, src, ztd::Range(0, descriptor.levels.getSize()), + ztd::Range(0, descriptor.layers.getSize())); } void ITextureView::CopyFrom(ICommandBuffer* command_buffer, @@ -28,10 +28,10 @@ void ITextureView::CopyFrom(ICommandBuffer* command_buffer, const u32 dst_layer, const u32 level_count, const u32 layer_count) { base->CopyFrom(command_buffer, src->GetBase(), - src->GetDescriptor().levels.GetBegin() + src_level, - src->GetDescriptor().layers.GetBegin() + src_layer, - descriptor.levels.GetBegin() + dst_level, - descriptor.layers.GetBegin() + dst_layer, level_count, + src->GetDescriptor().levels.getBegin() + src_level, + src->GetDescriptor().layers.getBegin() + src_layer, + descriptor.levels.getBegin() + dst_level, + descriptor.layers.getBegin() + dst_layer, level_count, layer_count); } diff --git a/src/core/hw/tegra_x1/gpu/renderer/texture_view.hpp b/src/core/hw/tegra_x1/gpu/renderer/texture_view.hpp index 45495135..bcebed70 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/texture_view.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/texture_view.hpp @@ -16,7 +16,7 @@ class ITextureView { // Copying void CopyFrom(ICommandBuffer* command_buffer, const BufferBase* src, - const Range dst_levels, const Range dst_layers); + const ztd::Range dst_levels, const ztd::Range dst_layers); void CopyFrom(ICommandBuffer* command_buffer, const BufferBase* src); void CopyFrom(ICommandBuffer* command_buffer, const ITextureView* src, const u32 src_level, const u32 src_layer, const u32 dst_level, diff --git a/src/core/hw/wall_clock.cpp b/src/core/hw/wall_clock.cpp index 8693fbf8..6e4b4b01 100644 --- a/src/core/hw/wall_clock.cpp +++ b/src/core/hw/wall_clock.cpp @@ -13,22 +13,22 @@ u64 MultiplyByFactor(u64 num, u128 factor) { return (num * factor) >> 64; } } // namespace WallClock::WallClock() { - const auto host_freq = GetSystemFrequency(); + const auto host_freq = ztd::getSystemFrequency(); ns_factor = GetFactor(1'000'000'000, host_freq); guest_factor = GetFactor(GUEST_CNTFRQ, host_freq); gpu_tick_factor = GetFactor(GPU_TICK_FREQ, host_freq); } u64 WallClock::GetTimeNs() const { - return MultiplyByFactor(GetSystemTick(), ns_factor); + return MultiplyByFactor(ztd::getSystemTick(), ns_factor); } u64 WallClock::GetCntpct() const { - return MultiplyByFactor(GetSystemTick(), guest_factor); + return MultiplyByFactor(ztd::getSystemTick(), guest_factor); } u64 WallClock::GetGpuTick() const { - return MultiplyByFactor(GetSystemTick(), gpu_tick_factor); + return MultiplyByFactor(ztd::getSystemTick(), gpu_tick_factor); } } // namespace hydra::hw diff --git a/src/core/input/device_list.hpp b/src/core/input/device_list.hpp index 7b3671db..92202205 100644 --- a/src/core/input/device_list.hpp +++ b/src/core/input/device_list.hpp @@ -9,8 +9,8 @@ class IDeviceList { IDeviceList() noexcept = default; virtual ~IDeviceList() noexcept = default; - MAKE_NON_COPYABLE(IDeviceList); - MAKE_NON_MOVABLE(IDeviceList); + ZTD_MAKE_NON_COPYABLE(IDeviceList); + ZTD_MAKE_NON_MOVABLE(IDeviceList); virtual void PumpEvents() {} diff --git a/src/core/input/device_manager.cpp b/src/core/input/device_manager.cpp index 5f578c99..a1738f7b 100644 --- a/src/core/input/device_manager.cpp +++ b/src/core/input/device_manager.cpp @@ -1,6 +1,6 @@ #include "core/input/device_manager.hpp" -#ifdef PLATFORM_APPLE +#ifdef ZTD_PLATFORM_APPLE #include "core/input/apple_gc/device_list.hpp" #endif @@ -20,7 +20,7 @@ IDeviceList* CreateDeviceList() { LOG_FATAL(Input, "SDL not supported"); #endif case InputBackend::AppleGameController: -#ifdef PLATFORM_APPLE +#ifdef ZTD_PLATFORM_APPLE return new apple_gc::DeviceList(); #else LOG_FATAL(Input, "Apple GameController not supported"); diff --git a/src/core/input/profile.cpp b/src/core/input/profile.cpp index 20a473df..7d9b9e56 100644 --- a/src/core/input/profile.cpp +++ b/src/core/input/profile.cpp @@ -187,9 +187,9 @@ void Profile::LoadDefaults() { switch (index) { case horizon::services::hid::internal::NpadIndex::No1: { // Devices -#ifdef PLATFORM_MACOS +#ifdef ZTD_PLATFORM_MACOS device_names = {"Generic Keyboard"}; -#elifdef PLATFORM_IOS +#elifdef ZTD_PLATFORM_IOS device_names = {"Apple Touch Controller"}; #endif diff --git a/src/core/system.cpp b/src/core/system.cpp index 55b42726..8aef3a09 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -269,8 +269,8 @@ void System::LoadAndStart(horizon::loader::ILoader* loader) { const auto view_descriptor = hw::tegra_x1::gpu::renderer::TextureViewDescriptor( - descriptor.type, descriptor.format, Range(0, 1), - Range(0, 1)); + descriptor.type, descriptor.format, + ztd::Range(0, 1), ztd::Range(0, 1)); const auto texture_view = texture->CreateView(view_descriptor); nintendo_logo = {.base = texture, .view = texture_view}; @@ -301,8 +301,8 @@ void System::LoadAndStart(horizon::loader::ILoader* loader) { true, stride, width, height, 1, 1, 1, 0x0, 0x0, 0x0); const auto view_descriptor = hw::tegra_x1::gpu::renderer::TextureViewDescriptor( - descriptor.type, descriptor.format, Range(0, 1), - Range(0, 1)); + descriptor.type, descriptor.format, + ztd::Range(0, 1), ztd::Range(0, 1)); startup_movie.reserve(frame_count); // Command buffer @@ -596,7 +596,7 @@ void System::TakeScreenshot() { if (layer == nullptr) return; - ASSIGN_OR_RETURN(auto texture, layer->GetPresentTexture()); + ZTD_ASSIGN_OR_RETURN(auto texture, layer->GetPresentTexture()); std::thread thread([layer, texture, this]() { // Get the image data @@ -616,7 +616,7 @@ void System::TakeScreenshot() { auto buffer = gpu.GetRenderer().AllocateTemporaryBuffer( static_cast(rect.size.y() * rect.size.x() * 4)); buffer->CopyFrom(command_buffer, texture, rect.origin, rect.size, - Range(0, 1), Range(0, 1)); + ztd::Range(0, 1), ztd::Range(0, 1)); delete command_buffer; // TODO: wait for the command buffer to finish diff --git a/src/frontend/sdl3/window.cpp b/src/frontend/sdl3/window.cpp index d941a675..ef04eeed 100644 --- a/src/frontend/sdl3/window.cpp +++ b/src/frontend/sdl3/window.cpp @@ -128,8 +128,8 @@ void Window::BeginEmulation(const std::string& path) { // Create loader // TODO: support loading applets from firmware // TODO: display error when loading fails - ASSIGN_OR_RETURN(auto loader, - horizon::loader::ILoader::CreateFromPath(path)); + ZTD_ASSIGN_OR_RETURN(auto loader, + horizon::loader::ILoader::CreateFromPath(path)); // Connect cursor as a touch screen device system.GetInputDeviceManager().ConnectTouchScreenDevice("cursor", &cursor); diff --git a/src/ztd/.clang-tidy b/src/ztd/.clang-tidy new file mode 100644 index 00000000..f6aa9905 --- /dev/null +++ b/src/ztd/.clang-tidy @@ -0,0 +1,34 @@ +Checks: > + bugprone-*, + cppcoreguidelines-*, + modernize-*, + performance-*, + readability-*, + + -bugprone-easily-swappable-parameters, + -bugprone-exception-escape, + -bugprone-unchecked-optional-access, + -bugprone-derived-method-shadowing-base-method, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -cppcoreguidelines-macro-usage, + -cppcoreguidelines-pro-type-vararg, + -cppcoreguidelines-pro-type-reinterpret-cast, + -cppcoreguidelines-pro-bounds-avoid-unchecked-container-access, + -cppcoreguidelines-avoid-do-while, + -cppcoreguidelines-pro-type-static-cast-downcast, + -cppcoreguidelines-avoid-const-or-ref-data-members, + -cppcoreguidelines-init-variables, + -modernize-use-integer-sign-comparison, + -readability-magic-numbers, + -readability-uppercase-literal-suffix, + -readability-identifier-length, + -readability-braces-around-statements, + -readability-function-cognitive-complexity, + -readability-else-after-return, + -readability-avoid-nested-conditional-operator, + -readability-math-missing-parentheses, + -readability-redundant-declaration +WarningsAsErrors: '*' +HeaderFilterRegex: '.*' diff --git a/src/ztd/CMakeLists.txt b/src/ztd/CMakeLists.txt new file mode 100644 index 00000000..d862a817 --- /dev/null +++ b/src/ztd/CMakeLists.txt @@ -0,0 +1,95 @@ +cmake_minimum_required(VERSION 3.15...3.31) +set(CMAKE_POLICY_VERSION_MINIMUM 3.15) + +project(ztd VERSION 0.0.1 LANGUAGES CXX) + +option(ZTD_PRECOMPILE_HEADERS "Precompile the main ztd header" OFF) +option(ZTD_CLANG_TIDY_ENABLED "Enable clang-tidy" ON) +option(ZTD_FMT_ENABLED "Enable fmt support for some types" OFF) + +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +#set(CMAKE_CXX_MODULE_STD ON) +set(CMAKE_COLOR_DIAGNOSTICS ON) + +# Enable Objective-C on Apple platforms +if (APPLE) + enable_language(OBJC OBJCXX) +endif() + +if (ZTD_CLANG_TIDY_ENABLED) + set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-use-color;-extra-arg-before=-Wno-unknown-warning-option") +endif () + +add_library(ztd + src/ztd/compress/lz4.cpp + src/ztd/compress/lz4.hpp + src/ztd/hash/xxhash32.hpp + src/ztd/macros/constructor_helper.hpp + src/ztd/macros/crtp_helper.hpp + src/ztd/macros/enum_helper.hpp + src/ztd/macros/for_each_helper.hpp + src/ztd/macros/macro_helper.hpp + src/ztd/macros/optional_helper.hpp + src/ztd/macros/platform.hpp + src/ztd/mem/alignment.hpp + src/ztd/mem/allocator.hpp + src/ztd/mem/c_allocator.hpp + src/ztd/mem/default_allocator.hpp + src/ztd/mem/literals.hpp + src/ztd/mem/page.hpp + src/ztd/mem/page_allocator.hpp + src/ztd/mem/pool.hpp + src/ztd/mem/static_pool.hpp + src/ztd/linked_list.hpp + src/ztd/range.hpp + src/ztd/time.hpp + src/ztd/type_aliases.hpp + src/ztd/ztd.hpp +) + +set_target_properties(ztd PROPERTIES CXX_SCAN_FOR_MODULES ON) +target_compile_features(ztd PUBLIC cxx_std_23) + +target_compile_options(ztd PRIVATE + # TODO: uncomment + #-fno-exceptions + -fno-asynchronous-unwind-tables + -fno-rtti + -fno-threadsafe-statics + -fvisibility=hidden + + # Warnings + -Wall + -Wextra + -Wpedantic + -Wconversion + -Wsign-conversion + -Wimplicit-int-float-conversion + -Wshadow + -Wdouble-promotion + -Wundef + -Wnon-virtual-dtor + -Wold-style-cast + + # Disabled warnings + -Wno-missing-designated-field-initializers + + # Extensions + -Wno-c99-extensions + -Wno-gnu-anonymous-struct + -Wno-nested-anon-types + -Wno-zero-length-array + -Wno-vla-extension + -Wno-gnu-case-range + -Wno-gnu-zero-variadic-macro-arguments +) + +target_include_directories(ztd PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) + +if (ZTD_PRECOMPILE_HEADERS) + target_precompile_headers(ztd PUBLIC src/ztd/ztd.hpp) +endif () + +add_library(ztd::ztd ALIAS ztd) diff --git a/src/common/lz4.cpp b/src/ztd/src/ztd/compress/lz4.cpp similarity index 75% rename from src/common/lz4.cpp rename to src/ztd/src/ztd/compress/lz4.cpp index 479214c4..2f958295 100644 --- a/src/common/lz4.cpp +++ b/src/ztd/src/ztd/compress/lz4.cpp @@ -1,12 +1,13 @@ -#include "common/lz4.hpp" +#include "ztd/compress/lz4.hpp" #include -namespace hydra { +namespace ztd::compress { namespace { -u32 GetLength(std::span src, u32& cmp_pos, u32 length) { +auto getLength(std::span src, u32& cmp_pos, u32 length) noexcept + -> u32 { u8 sum = 0; if (length == 0xf) { do { @@ -19,7 +20,8 @@ u32 GetLength(std::span src, u32& cmp_pos, u32 length) { } // namespace -void DecompressLZ4(std::span src, std::span dst) { +auto decompressLz4(std::span src, std::span dst) noexcept + -> void { u32 cmp_pos = 0; u32 dec_pos = 0; @@ -30,7 +32,7 @@ void DecompressLZ4(std::span src, std::span dst) { u32 lit_count = (token >> 4) & 0xf; // Copy literal chunk - lit_count = GetLength(src, cmp_pos, lit_count); + lit_count = getLength(src, cmp_pos, lit_count); std::memcpy(dst.data() + dec_pos, src.data() + cmp_pos, lit_count); @@ -45,7 +47,7 @@ void DecompressLZ4(std::span src, std::span dst) { u32 back = static_cast(src[cmp_pos++]) << 0u; back |= static_cast(src[cmp_pos++]) << 8u; - enc_count = GetLength(src, cmp_pos, enc_count) + 4; + enc_count = getLength(src, cmp_pos, enc_count) + 4; u32 enc_pos = dec_pos - back; @@ -61,4 +63,4 @@ void DecompressLZ4(std::span src, std::span dst) { } while (cmp_pos < src.size() && dec_pos < dst.size()); } -} // namespace hydra +} // namespace ztd::compress diff --git a/src/ztd/src/ztd/compress/lz4.hpp b/src/ztd/src/ztd/compress/lz4.hpp new file mode 100644 index 00000000..73722742 --- /dev/null +++ b/src/ztd/src/ztd/compress/lz4.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include + +#include "ztd/type_aliases.hpp" + +namespace ztd::compress { + +auto decompressLz4(std::span src, std::span dst) noexcept -> void; + +} // namespace ztd::compress diff --git a/src/common/hash.hpp b/src/ztd/src/ztd/hash/xxhash32.hpp similarity index 53% rename from src/common/hash.hpp rename to src/ztd/src/ztd/hash/xxhash32.hpp index ffe15cb3..50074fd1 100644 --- a/src/common/hash.hpp +++ b/src/ztd/src/ztd/hash/xxhash32.hpp @@ -1,72 +1,73 @@ #pragma once -#include "type_aliases.hpp" +#include +#include -namespace hydra { +#include "ztd/type_aliases.hpp" -class HashCode { - public: - HashCode() : v1{prime1 + prime2}, v2{prime2}, v4{prime1} {} +namespace ztd::hash { - void Add(u32 value) { +class XxHash32 { + public: + void add(u32 value) noexcept { u32 previous_length = length++; u32 position = previous_length % 4; - if (position == 0) + if (position == 0) { queue1 = value; - else if (position == 1) + } else if (position == 1) { queue2 = value; - else if (position == 2) + } else if (position == 2) { queue3 = value; - else { - v1 = Round(v1, queue1); - v2 = Round(v2, queue2); - v3 = Round(v3, queue3); - v4 = Round(v4, value); + } else { + v1 = round(v1, queue1); + v2 = round(v2, queue2); + v3 = round(v3, queue3); + v4 = round(v4, value); } } - void Add(u64 value) { + void add(u64 value) noexcept { u32 lower = static_cast(value); u32 upper = static_cast(value >> 32); - Add(lower); - Add(upper); + add(lower); + add(upper); } template - void Add(T* ptr) { + void add(T* ptr) noexcept { uptr value = reinterpret_cast(ptr); if constexpr (sizeof(uptr) == 8) - Add(static_cast(value)); + add(static_cast(value)); else - Add(static_cast(value)); + add(static_cast(value)); } template - void Add(const T& value) + void add(const T& value) noexcept requires std::is_trivially_copyable_v { const u8* bytes = reinterpret_cast(&value); for (usize i = 0; i < sizeof(T); ++i) - Add(static_cast(bytes[i])); + add(static_cast(bytes[i])); } - u32 ToHashCode() const { - u32 hash = length < 4 ? MixEmptyState() : MixState(v1, v2, v3, v4); + [[nodiscard]] auto toHashCode() const noexcept -> u32 { + u32 hash = length < 4 ? mixEmptyState() : mixState(v1, v2, v3, v4); hash += length * 4; u32 position = length % 4; if (position > 0) { - hash = QueueRound(hash, queue1); + hash = queueRound(hash, queue1); if (position > 1) { - hash = QueueRound(hash, queue2); + hash = queueRound(hash, queue2); if (position > 2) { - hash = QueueRound(hash, queue3); + hash = queueRound(hash, queue3); } } } - return MixFinal(hash); + return mixFinal(hash); } private: @@ -76,26 +77,26 @@ class HashCode { static constexpr u32 prime4 = 668265263u; static constexpr u32 prime5 = 374761393u; - u32 v1, v2, v3{0}, v4; + u32 v1{prime1 + prime2}, v2{prime2}, v3{0}, v4{prime1}; u32 queue1{0}, queue2{0}, queue3{0}; u32 length{0}; - static u32 Round(u32 hash, u32 input) { + static auto round(u32 hash, u32 input) noexcept -> u32 { return std::rotl(hash + input * prime2, 13) * prime1; } - static u32 QueueRound(u32 hash, u32 queued_value) { + static auto queueRound(u32 hash, u32 queued_value) noexcept -> u32 { return std::rotl(hash + queued_value * prime3, 17) * prime4; } - static u32 MixState(u32 v1, u32 v2, u32 v3, u32 v4) { + static auto mixState(u32 v1, u32 v2, u32 v3, u32 v4) noexcept -> u32 { return std::rotl(v1, 1) + std::rotl(v2, 7) + std::rotl(v3, 12) + std::rotl(v4, 18); } - static u32 MixEmptyState() { return prime5; } + static auto mixEmptyState() noexcept -> u32 { return prime5; } - static u32 MixFinal(u32 hash) { + static auto mixFinal(u32 hash) noexcept -> u32 { hash ^= hash >> 15; hash *= prime2; hash ^= hash >> 13; @@ -105,4 +106,4 @@ class HashCode { } }; -} // namespace hydra +} // namespace ztd::hash diff --git a/src/ztd/src/ztd/linked_list.hpp b/src/ztd/src/ztd/linked_list.hpp new file mode 100644 index 00000000..53e61a9e --- /dev/null +++ b/src/ztd/src/ztd/linked_list.hpp @@ -0,0 +1,220 @@ +#pragma once + +#include "ztd/mem/default_allocator.hpp" +#include "ztd/type_aliases.hpp" + +namespace ztd { + +template +class LinkedList { + public: + class SinglyNode { + template + friend class LinkedList; + + public: + SinglyNode(T value_) noexcept : value{std::move(value_)} {} + + operator T&() noexcept { return value; } + operator const T&() const noexcept { return value; } + auto operator->() const noexcept -> const T* { return &value; } + auto operator->() noexcept -> T* { return &value; } + + auto get() noexcept -> T& { return value; } + auto get() const noexcept -> const T& { return value; } + + auto getNext() const noexcept -> std::optional { + return next; + } + + private: + T value; + std::optional next{}; + }; + + class DoublyNode { + template + friend class LinkedList; + + public: + DoublyNode(T value_) noexcept : value{std::move(value_)} {} + + operator T&() noexcept { return value; } + operator const T&() const noexcept { return value; } + auto operator->() const noexcept -> const T* { return &value; } + auto operator->() noexcept -> T* { return &value; } + + auto get() noexcept -> T& { return value; } + auto get() const noexcept -> const T& { return value; } + + auto getNext() const noexcept -> std::optional { + return next; + } + + auto getPrev() const noexcept -> std::optional { + return prev; + } + + private: + T value; + std::optional next{}; + std::optional prev{}; + }; + + using Node = + typename std::conditional_t; + + LinkedList( + mem::IAllocator& allocator_ = mem::getDefaultAllocator()) noexcept + : allocator{allocator_} {} + ~LinkedList() noexcept { clear(); } + + ZTD_MAKE_NON_COPYABLE(LinkedList); + ZTD_MAKE_DEFAULT_MOVABLE(LinkedList); + + auto addFirst(T value) noexcept + -> std::expected { + ZTD_ASSIGN_OR_RETURN_ERROR(auto node, + allocator.create(std::move(value))); + if (head.has_value()) { + const auto head_ = head.value(); + node->next = head_; + if constexpr (is_doubly_linked) + head_->prev = node; + head = node; + } else { + head = tail = node; + } + size++; + + return node; + } + + auto addLast(T value) noexcept + -> std::expected { + ZTD_ASSIGN_OR_RETURN_ERROR(auto node, + allocator.create(std::move(value))); + if (tail.has_value()) { + const auto tail_ = tail.value(); + tail_->next = node; + if constexpr (is_doubly_linked) + node->prev = tail_; + tail = node; + } else { + head = tail = node; + } + size++; + + return node; + } + + auto removeFirst() noexcept -> bool { + ZTD_ASSIGN_OR_RETURN_VALUE(auto head_, head, false); + + auto node = head_; + head = head_->next; + allocator.destroy(node); + if (!head.has_value()) + tail = std::nullopt; + size--; + + return true; + } + + auto removeLast() noexcept -> bool + requires is_doubly_linked + { + ZTD_ASSIGN_OR_RETURN_VALUE(auto head_, head, false); + + if (!head_->next.has_value()) { + allocator.destroy(head_); + head = tail = std::nullopt; + } else { + auto old_tail = tail.value(); + tail = old_tail->prev; + tail.value()->next = std::nullopt; + allocator.destroy(old_tail); + } + size--; + + return true; + } + + auto remove(Node* target) noexcept -> std::optional + requires is_doubly_linked + { + ZTD_ASSIGN_OR_RETURN_VALUE(auto head_, head, std::nullopt); + const auto tail_ = tail.value(); + + // Head + if (target == head_) { + head = target->next; + } else { + target->prev.value()->next = target->next; + } + + // Tail + if (target == tail_) { + tail = target->prev; + } else { + target->next.value()->prev = target->prev; + } + + auto next = target->next; + allocator.destroy(target); + size--; + return next; + } + + auto remove(const T& target) noexcept -> void { + // Remove all occurrences of the target + for (auto node = head; node.has_value();) { + const auto node_ = node.value(); + if (node_->value == target) { + if constexpr (is_doubly_linked) { + node = remove(node_); + } else { + // TODO + static_assert(false, "NOT IMPLEMENTED"); + } + } else { + node = node_->next; + } + } + } + + auto clear() noexcept -> void { + auto node = head; + while (node.has_value()) { + const auto node_ = node.value(); + const auto next_node = node_->next; + allocator.destroy(node_); + node = next_node; + } + head = std::nullopt; + tail = std::nullopt; + size = 0; + } + + [[nodiscard]] auto getHead() const noexcept -> std::optional { + return head; + } + [[nodiscard]] auto getTail() const noexcept -> std::optional { + return tail; + } + [[nodiscard]] auto getSize() const noexcept -> usize { return size; } + + private: + mem::IAllocator& allocator; + std::optional head{}; + std::optional tail{}; + usize size{0}; +}; + +template +using SinglyLinkedList = LinkedList; + +template +using DoublyLinkedList = LinkedList; + +} // namespace ztd diff --git a/src/ztd/src/ztd/macros/constructor_helper.hpp b/src/ztd/src/ztd/macros/constructor_helper.hpp new file mode 100644 index 00000000..d8958b50 --- /dev/null +++ b/src/ztd/src/ztd/macros/constructor_helper.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include "ztd/macros/for_each_helper.hpp" + +#define ZTD_MAKE_DEFAULT_COPYABLE(type) \ + type(const type&) noexcept = default; \ + auto operator=(const type&) noexcept -> type& = default; + +#define ZTD_MAKE_NON_COPYABLE(type) \ + type(const type&) = delete; \ + auto operator=(const type&) noexcept -> type& = delete; + +#define ZTD_MAKE_DEFAULT_MOVABLE(type) \ + type(type&&) noexcept = default; \ + auto operator=(type&&) noexcept -> type& = default; + +#define ZTD_MAKE_NON_MOVABLE(type) \ + type(type&&) = delete; \ + auto operator=(type&&) noexcept -> type& = delete; + +#define ZTD_SWAP_CASE(member) std::swap(a.member, b.member); + +#define ZTD_MAKE_MOVE_ASSIGNABLE(type, ...) \ + auto operator=(type&& other) noexcept -> type& { \ + if (this != &other) { \ + type temp(std::move(other)); \ + swap(*this, temp); \ + } \ + return *this; \ + } \ + friend auto swap(type& a, type& b) noexcept -> void { \ + ZTD_FOR_EACH_0_1(ZTD_SWAP_CASE, __VA_ARGS__) \ + } + +#define ZTD_MOVE_CASE(member, value) \ + , member { value } +#define ZTD_MOVE_MEMBERS(member1, value1, ...) \ + member1{value1} ZTD_FOR_EACH_0_2(ZTD_MOVE_CASE, __VA_ARGS__) + +#define ZTD_PASS_TO_MAKE_MOVE_ASSIGNABLE_CASE(member, value) , member +#define ZTD_PASS_TO_MAKE_MOVE_ASSIGNABLE(member1, value1, ...) \ + member1 ZTD_FOR_EACH_0_2(ZTD_PASS_TO_MAKE_MOVE_ASSIGNABLE_CASE, __VA_ARGS__) + +#define MAKE_MOVABLE(type, ...) \ + type(type&& other) noexcept : ZTD_MOVE_MEMBERS(__VA_ARGS__) {} \ + ZTD_MAKE_MOVE_ASSIGNABLE(type, \ + ZTD_PASS_TO_MAKE_MOVE_ASSIGNABLE(__VA_ARGS__)) diff --git a/src/ztd/src/ztd/macros/crtp_helper.hpp b/src/ztd/src/ztd/macros/crtp_helper.hpp new file mode 100644 index 00000000..8c0101a5 --- /dev/null +++ b/src/ztd/src/ztd/macros/crtp_helper.hpp @@ -0,0 +1,9 @@ +#pragma once + +#define ZTD_DEFINE_CRTP_GET_SELF() \ + auto getSelf() noexcept -> Derived& { \ + return *static_cast(this); \ + } \ + auto getSelf() const noexcept -> const Derived& { \ + return *static_cast(this); \ + } diff --git a/src/ztd/src/ztd/macros/enum_helper.hpp b/src/ztd/src/ztd/macros/enum_helper.hpp new file mode 100644 index 00000000..e31d2559 --- /dev/null +++ b/src/ztd/src/ztd/macros/enum_helper.hpp @@ -0,0 +1,73 @@ +#pragma once + +#define ZTD_BIT(n) (1u << (n)) +#define ZTD_BITL(n) (1ul << (n)) + +#define ZTD_ENABLE_ENUM_ARITHMETIC_OPERATORS(type) \ + [[maybe_unused]] [[nodiscard]] constexpr auto operator+( \ + type a, type b) noexcept -> type { \ + return static_cast( \ + static_cast>(a) + \ + static_cast>(b)); \ + } \ + [[maybe_unused]] [[nodiscard]] constexpr auto operator-( \ + type a, type b) noexcept -> type { \ + return static_cast( \ + static_cast>(a) - \ + static_cast>(b)); \ + } \ + [[maybe_unused]] constexpr auto operator++(type& x, i32) noexcept \ + -> type { \ + const auto tmp = x; \ + x = static_cast(static_cast>(x) + \ + 1); \ + return tmp; \ + } \ + [[maybe_unused]] constexpr auto operator--(type& x, i32) noexcept \ + -> type { \ + const auto tmp = x; \ + x = static_cast(static_cast>(x) - \ + 1); \ + return tmp; \ + } \ + [[maybe_unused]] constexpr auto operator++(type& x) noexcept -> type& { \ + x = static_cast(static_cast>(x) + \ + 1); \ + return x; \ + } \ + [[maybe_unused]] constexpr auto operator--(type& x) noexcept -> type& { \ + x = static_cast(static_cast>(x) - \ + 1); \ + return x; \ + } + +#define ZTD_ENABLE_ENUM_BITWISE_OPERATORS(type) \ + [[maybe_unused]] [[nodiscard]] constexpr auto operator|( \ + type a, type b) noexcept -> type { \ + return static_cast( \ + static_cast>(a) | \ + static_cast>(b)); \ + } \ + [[maybe_unused]] constexpr auto operator|=(type& a, type b) noexcept \ + -> type& { \ + return a = a | b; \ + } \ + [[maybe_unused]] [[nodiscard]] constexpr auto operator&( \ + type a, type b) noexcept -> type { \ + return static_cast( \ + static_cast>(a) & \ + static_cast>(b)); \ + } \ + [[maybe_unused]] constexpr auto operator&=(type& a, type b) noexcept \ + -> type& { \ + return a = a & b; \ + } \ + [[maybe_unused]] [[nodiscard]] constexpr auto operator~(type a) noexcept \ + -> type { \ + return static_cast( \ + ~static_cast>(a)); \ + } \ + [[maybe_unused]] [[nodiscard]] constexpr auto any(type a) noexcept \ + -> bool { \ + return a != type::None; \ + } diff --git a/src/ztd/src/ztd/macros/for_each_helper.hpp b/src/ztd/src/ztd/macros/for_each_helper.hpp new file mode 100644 index 00000000..dda0b09f --- /dev/null +++ b/src/ztd/src/ztd/macros/for_each_helper.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include "ztd/macros/macro_helper.hpp" + +#define ZTD_EXPAND(...) \ + ZTD_EXPAND4(ZTD_EXPAND4(ZTD_EXPAND4(ZTD_EXPAND4(__VA_ARGS__)))) +#define ZTD_EXPAND4(...) \ + ZTD_EXPAND3(ZTD_EXPAND3(ZTD_EXPAND3(ZTD_EXPAND3(__VA_ARGS__)))) +#define ZTD_EXPAND3(...) \ + ZTD_EXPAND2(ZTD_EXPAND2(ZTD_EXPAND2(ZTD_EXPAND2(__VA_ARGS__)))) +#define ZTD_EXPAND2(...) \ + ZTD_EXPAND1(ZTD_EXPAND1(ZTD_EXPAND1(ZTD_EXPAND1(__VA_ARGS__)))) +#define ZTD_EXPAND1(...) __VA_ARGS__ + +#define ZTD_FOR_EACH_0_1(macro, ...) \ + __VA_OPT__(ZTD_EXPAND(ZTD_FOR_EACH_HELPER_0_1(macro, __VA_ARGS__))) +#define ZTD_FOR_EACH_HELPER_0_1(macro, a, ...) \ + macro(a) __VA_OPT__(ZTD_FOR_EACH_AGAIN_0_1 ZTD_PARENS(macro, __VA_ARGS__)) +#define ZTD_FOR_EACH_AGAIN_0_1() ZTD_FOR_EACH_HELPER_0_1 + +#define ZTD_FOR_EACH_0_2(macro, ...) \ + __VA_OPT__(ZTD_EXPAND(ZTD_FOR_EACH_HELPER_0_2(macro, __VA_ARGS__))) +#define ZTD_FOR_EACH_HELPER_0_2(macro, a1, a2, ...) \ + macro(a1, a2) \ + __VA_OPT__(ZTD_FOR_EACH_AGAIN_0_2 ZTD_PARENS(macro, __VA_ARGS__)) +#define ZTD_FOR_EACH_AGAIN_0_2() ZTD_FOR_EACH_HELPER_0_2 + +#define ZTD_FOR_EACH_0_3(macro, ...) \ + __VA_OPT__(ZTD_EXPAND(ZTD_FOR_EACH_HELPER_0_3(macro, __VA_ARGS__))) +#define ZTD_FOR_EACH_HELPER_0_3(macro, a1, a2, a3, ...) \ + macro(a1, a2, a3) \ + __VA_OPT__(ZTD_FOR_EACH_AGAIN_0_3 ZTD_PARENS(macro, __VA_ARGS__)) +#define ZTD_FOR_EACH_AGAIN_0_3() ZTD_FOR_EACH_HELPER_0_3 + +#define ZTD_FOR_EACH_0_4(macro, ...) \ + __VA_OPT__(ZTD_EXPAND(ZTD_FOR_EACH_HELPER_0_4(macro, __VA_ARGS__))) +#define ZTD_FOR_EACH_HELPER_0_4(macro, a1, a2, a3, a4, ...) \ + macro(a1, a2, a3, a4) \ + __VA_OPT__(ZTD_FOR_EACH_AGAIN_0_4 ZTD_PARENS(macro, __VA_ARGS__)) +#define ZTD_FOR_EACH_AGAIN_0_4() ZTD_FOR_EACH_HELPER_0_4 + +#define ZTD_FOR_EACH_1_2(macro, e, ...) \ + __VA_OPT__(ZTD_EXPAND(ZTD_FOR_EACH_HELPER_1_2(macro, e, __VA_ARGS__))) +#define ZTD_FOR_EACH_HELPER_1_2(macro, e, a1, a2, ...) \ + macro(e, a1, a2) \ + __VA_OPT__(ZTD_FOR_EACH_AGAIN_1_2 ZTD_PARENS(macro, e, __VA_ARGS__)) +#define ZTD_FOR_EACH_AGAIN_1_2() ZTD_FOR_EACH_HELPER_1_2 + +#define ZTD_FOR_EACH_1_3(macro, e, ...) \ + __VA_OPT__(ZTD_EXPAND(ZTD_FOR_EACH_HELPER_1_3(macro, e, __VA_ARGS__))) +#define ZTD_FOR_EACH_HELPER_1_3(macro, e, a1, a2, a3, ...) \ + macro(e, a1, a2, a3) \ + __VA_OPT__(ZTD_FOR_EACH_AGAIN_1_3 ZTD_PARENS(macro, e, __VA_ARGS__)) +#define ZTD_FOR_EACH_AGAIN_1_3() ZTD_FOR_EACH_HELPER_1_3 + +#define ZTD_FOR_EACH_2_1(macro, e1, e2, ...) \ + __VA_OPT__(ZTD_EXPAND(ZTD_FOR_EACH_HELPER_2_1(macro, e1, e2, __VA_ARGS__))) +#define ZTD_FOR_EACH_HELPER_2_1(macro, e1, e2, a, ...) \ + macro(e1, e2, a) __VA_OPT__( \ + ZTD_FOR_EACH_AGAIN_2_1 ZTD_PARENS(macro, e1, e2, __VA_ARGS__)) +#define ZTD_FOR_EACH_AGAIN_2_1() ZTD_FOR_EACH_HELPER_2_1 + +#define ZTD_FOR_EACH_2_2(macro, e1, e2, ...) \ + __VA_OPT__(ZTD_EXPAND(ZTD_FOR_EACH_HELPER_2_2(macro, e1, e2, __VA_ARGS__))) +#define ZTD_FOR_EACH_HELPER_2_2(macro, e1, e2, a1, a2, ...) \ + macro(e1, e2, a1, a2) __VA_OPT__( \ + ZTD_FOR_EACH_AGAIN_2_2 ZTD_PARENS(macro, e1, e2, __VA_ARGS__)) +#define ZTD_FOR_EACH_AGAIN_2_2() ZTD_FOR_EACH_HELPER_2_2 diff --git a/src/ztd/src/ztd/macros/macro_helper.hpp b/src/ztd/src/ztd/macros/macro_helper.hpp new file mode 100644 index 00000000..85a4c0ad --- /dev/null +++ b/src/ztd/src/ztd/macros/macro_helper.hpp @@ -0,0 +1,11 @@ +#pragma once + +#define ZTD_CONCAT_IMPL(a, b) a##b +#define ZTD_CONCAT(a, b) ZTD_CONCAT_IMPL(a, b) + +#define ZTD_PASS(...) __VA_ARGS__ +#define ZTD_PASS_VA_ARGS(...) , ##__VA_ARGS__ + +#define ZTD_PARENS () + +#define ZTD_UNIQUE_SUFFIX(var) ZTD_CONCAT(var, __LINE__) diff --git a/src/ztd/src/ztd/macros/optional_helper.hpp b/src/ztd/src/ztd/macros/optional_helper.hpp new file mode 100644 index 00000000..8db8d7d9 --- /dev/null +++ b/src/ztd/src/ztd/macros/optional_helper.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "macro_helper.hpp" + +#define ZTD_ASSIGN_OR(var, expected, fail_statement) \ + const auto ZTD_UNIQUE_SUFFIX(_) = expected; \ + if (!ZTD_UNIQUE_SUFFIX(_).has_value()) \ + fail_statement; \ + var = ZTD_UNIQUE_SUFFIX(_).value(); + +#define ZTD_ASSIGN_OR_RETURN_VALUE(var, expected, ret) \ + ZTD_ASSIGN_OR(var, expected, return ret) +#define ZTD_ASSIGN_OR_RETURN(var, expected) \ + ZTD_ASSIGN_OR_RETURN_VALUE(var, expected, ) +#define ZTD_ASSIGN_OR_RETURN_ERROR(var, expected) \ + ZTD_ASSIGN_OR_RETURN_VALUE(var, expected, std::unexpected(expected.error())) + +#define ZTD_ASSIGN_OR_CONTINUE(var, expected, ret) \ + ZTD_ASSIGN_OR(var, expected, continue) + +#define ZTD_ASSIGN_OR_BREAK(var, expected, ret) \ + ZTD_ASSIGN_OR(var, expected, break) diff --git a/src/ztd/src/ztd/macros/platform.hpp b/src/ztd/src/ztd/macros/platform.hpp new file mode 100644 index 00000000..64db7a6f --- /dev/null +++ b/src/ztd/src/ztd/macros/platform.hpp @@ -0,0 +1,58 @@ +#pragma once + +// Architecture + +#if defined(__aarch64__) || defined(_M_ARM64) +#define ZTD_ARCH_AARCH64 +#elif defined(__arm__) || defined(_M_ARM) +#define ZTD_ARCH_ARM32 +#elif defined(__x86_64__) || defined(_M_X64) +#define ZTD_ARCH_X86_64 +#elifdef __riscv +#define ZTD_ARCH_RISCV +#else +#define ZTD_ARCH_UNKNOWN +#endif + +// Platform + +// Windows +#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || \ + defined(__WINDOWS__) +#define ZTD_PLATFORM_WINDOWS +#ifdef _WIN64 +#define ZTD_PLATFORM_WINDOWS64 +#else +#define ZTD_PLATFORM_WINDOWS32 +#endif + +// Apple platforms +#elif defined(__APPLE__) || defined(__MACH__) +#include +#define ZTD_PLATFORM_APPLE +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +#define ZTD_PLATFORM_IOS +#elif TARGET_OS_MAC +#define ZTD_PLATFORM_MACOS +#endif + +// Android +#elifdef __ANDROID__ +#define ZTD_PLATFORM_ANDROID + +// Linux +#elif defined(__linux__) || defined(__linux) +#define ZTD_PLATFORM_LINUX + +// FreeBSD +#elifdef __FreeBSD__ +#define ZTD_PLATFORM_FREEBSD + +#else +#error ZTD_PLATFORM_UNKNOWN +#endif + +// Unix +#if defined(__unix__) || defined(__unix) +#define ZTD_PLATFORM_UNIX +#endif diff --git a/src/ztd/src/ztd/mem/alignment.hpp b/src/ztd/src/ztd/mem/alignment.hpp new file mode 100644 index 00000000..74230d59 --- /dev/null +++ b/src/ztd/src/ztd/mem/alignment.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "ztd/type_aliases.hpp" + +namespace ztd::mem { + +template +constexpr auto alignDown(T value, T alignment) noexcept -> T { + return value & ~(alignment - 1); +} + +template +constexpr auto alignUp(T value, T alignment) noexcept -> T { + return alignDown(value + alignment - 1, alignment); +} + +template +constexpr auto ceilDivide(T value, T divisor) noexcept -> T { + return (value + divisor - 1) / divisor; +} + +} // namespace ztd::mem diff --git a/src/ztd/src/ztd/mem/allocator.hpp b/src/ztd/src/ztd/mem/allocator.hpp new file mode 100644 index 00000000..978d9563 --- /dev/null +++ b/src/ztd/src/ztd/mem/allocator.hpp @@ -0,0 +1,73 @@ +#pragma once + +#include +#include + +#include "ztd/macros/constructor_helper.hpp" +#include "ztd/macros/optional_helper.hpp" +#include "ztd/type_aliases.hpp" + +namespace ztd::mem { + +class IAllocator { + public: + enum class Error : u8 { + OutOfMemory, + }; + + IAllocator() noexcept = default; + virtual ~IAllocator() noexcept = default; + + ZTD_MAKE_DEFAULT_COPYABLE(IAllocator); + ZTD_MAKE_DEFAULT_MOVABLE(IAllocator); + + template + auto create(Args... args) noexcept -> std::expected { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto bytes, + allocImpl(sizeof(T), alignof(T)), + std::unexpected(Error::OutOfMemory)); + const auto ptr = reinterpret_cast(bytes.data()); + new (ptr) T(std::forward(args)...); + return ptr; + } + + template + auto alloc() noexcept -> std::expected { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto bytes, + allocImpl(sizeof(T), alignof(T)), + std::unexpected(Error::OutOfMemory)); + return reinterpret_cast(bytes.data()); + } + + template + auto alloc(usize count) noexcept -> std::expected, Error> { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto bytes, + allocImpl(sizeof(T) * count, alignof(T)), + std::unexpected(Error::OutOfMemory)); + return {reinterpret_cast(bytes.data()), count}; + } + + template + auto destroy(T* ptr) noexcept -> void { + ptr->~T(); + freeImpl({reinterpret_cast(ptr), sizeof(T)}); + } + + template + auto free(T* ptr) noexcept -> void { + freeImpl({reinterpret_cast(ptr), sizeof(T)}); + } + + template + auto free(std::span span) noexcept -> void { + freeImpl( + {reinterpret_cast(span.data()), span.size_bytes()}); + } + + protected: + virtual auto allocImpl(usize size, usize alignment) noexcept + -> std::optional> = 0; + virtual auto freeImpl(std::span bytes) noexcept -> void = 0; +}; + +} // namespace ztd::mem diff --git a/src/ztd/src/ztd/mem/c_allocator.hpp b/src/ztd/src/ztd/mem/c_allocator.hpp new file mode 100644 index 00000000..6c9a3105 --- /dev/null +++ b/src/ztd/src/ztd/mem/c_allocator.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include "ztd/mem/allocator.hpp" + +namespace ztd::mem { + +class CAllocator : public IAllocator { + public: + static auto getInstance() noexcept -> CAllocator& { + static CAllocator g_instance; + return g_instance; + } + + protected: + auto allocImpl(usize size, usize alignment) noexcept + -> std::optional> override { + (void)alignment; + // NOLINTBEGIN(cppcoreguidelines-owning-memory, + // cppcoreguidelines-no-malloc) + const auto ptr = malloc(size); + // NOLINTEND(cppcoreguidelines-owning-memory, + // cppcoreguidelines-no-malloc) + if (ptr == nullptr) + return std::nullopt; + + return std::span{reinterpret_cast(ptr), size}; + } + + auto freeImpl(std::span bytes) noexcept -> void override { + // NOLINTBEGIN(cppcoreguidelines-owning-memory, + // cppcoreguidelines-no-malloc) + ::free(bytes.data()); + // NOLINTEND(cppcoreguidelines-owning-memory, + // cppcoreguidelines-no-malloc) + } +}; + +} // namespace ztd::mem diff --git a/src/ztd/src/ztd/mem/default_allocator.hpp b/src/ztd/src/ztd/mem/default_allocator.hpp new file mode 100644 index 00000000..93543acb --- /dev/null +++ b/src/ztd/src/ztd/mem/default_allocator.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "ztd/mem/c_allocator.hpp" + +namespace ztd::mem { + +// TODO: don't use the C allocator as the default allocator +inline auto getDefaultAllocator() noexcept -> IAllocator& { + return CAllocator::getInstance(); +} + +} // namespace ztd::mem diff --git a/src/ztd/src/ztd/mem/literals.hpp b/src/ztd/src/ztd/mem/literals.hpp new file mode 100644 index 00000000..7317cd54 --- /dev/null +++ b/src/ztd/src/ztd/mem/literals.hpp @@ -0,0 +1,25 @@ +#pragma once + +namespace ztd::mem::inline literals { + +constexpr auto operator""_KiB(unsigned long long x) noexcept + -> unsigned long long { + return x * 1024; +} + +constexpr auto operator""_MiB(unsigned long long x) noexcept + -> unsigned long long { + return x * 1024_KiB; +} + +constexpr auto operator""_GiB(unsigned long long x) noexcept + -> unsigned long long { + return x * 1024_MiB; +} + +constexpr auto operator""_TiB(unsigned long long x) noexcept + -> unsigned long long { + return x * 1024_GiB; +} + +} // namespace ztd::mem::inline literals diff --git a/src/ztd/src/ztd/mem/page.hpp b/src/ztd/src/ztd/mem/page.hpp new file mode 100644 index 00000000..c66240d1 --- /dev/null +++ b/src/ztd/src/ztd/mem/page.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include "ztd/macros/platform.hpp" +#include "ztd/mem/literals.hpp" +#include "ztd/type_aliases.hpp" + +namespace ztd::mem { + +#ifdef ZTD_PLATFORM_APPLE +#ifdef ZTD_ARCH_AARCH64 +// All Apple Silicon devices have fixed 16KiB page size +constexpr usize PAGE_SIZE_MIN = 16_KiB; +constexpr usize PAGE_SIZE_MAX = 16_KiB; +#elifdef ZTD_ARCH_X86_64 +// All Intel Macs have fixed 4KiB page size +constexpr usize PAGE_SIZE_MIN = 4_KiB; +constexpr usize PAGE_SIZE_MAX = 4_KiB; +#else +// Fallback +constexpr usize PAGE_SIZE_MIN = 4_KiB; +constexpr usize PAGE_SIZE_MAX = 2_GiB; +#endif +// TODO: other platforms +#else +// Fallback +constexpr usize PAGE_SIZE_MIN = 4_KiB; +constexpr usize PAGE_SIZE_MAX = 2_GiB; +#endif + +inline auto getPageSize() noexcept -> usize { + if constexpr (PAGE_SIZE_MIN == PAGE_SIZE_MAX) { + return PAGE_SIZE_MIN; + } + + return static_cast(sysconf(_SC_PAGESIZE)); +} + +} // namespace ztd::mem diff --git a/src/ztd/src/ztd/mem/page_allocator.hpp b/src/ztd/src/ztd/mem/page_allocator.hpp new file mode 100644 index 00000000..b8f5d0d8 --- /dev/null +++ b/src/ztd/src/ztd/mem/page_allocator.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include + +#include "ztd/mem/alignment.hpp" +#include "ztd/mem/allocator.hpp" +#include "ztd/mem/page.hpp" + +namespace ztd::mem { + +class PageAllocator : public IAllocator { + public: + static auto getInstance() noexcept -> PageAllocator& { + static PageAllocator g_instance; + return g_instance; + } + + protected: + auto allocImpl(usize size, usize alignment) noexcept + -> std::optional> override { + (void)alignment; + const auto aligned_size = alignUp(size, getPageSize()); + const auto ptr = mmap(nullptr, aligned_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + if (ptr == MAP_FAILED) { + return std::nullopt; + } + + return std::span{reinterpret_cast(ptr), aligned_size}; + } + + auto freeImpl(std::span bytes) noexcept -> void override { + munmap(bytes.data(), bytes.size()); + } +}; + +} // namespace ztd::mem diff --git a/src/ztd/src/ztd/mem/pool.hpp b/src/ztd/src/ztd/mem/pool.hpp new file mode 100644 index 00000000..7ce00ad1 --- /dev/null +++ b/src/ztd/src/ztd/mem/pool.hpp @@ -0,0 +1,83 @@ +#pragma once + +#include "ztd/macros/crtp_helper.hpp" +#include "ztd/type_aliases.hpp" + +namespace ztd::mem { + +template +class Pool { + public: + template + auto insert(Args... args) noexcept + -> std::expected { + ZTD_ASSIGN_OR_RETURN_ERROR(const auto index, getSelf().findFreeIndex()); + getSelf().getByIndex(index).emplace(std::forward(args)...); + return indexToHandle(index); + } + + [[nodiscard]] auto free(u32 handle) noexcept -> bool { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handleToIndex(handle), + false); + return getSelf().freeByIndex(index); + } + + auto get(u32 handle) noexcept -> std::optional + requires std::is_pointer_v + { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handleToIndex(handle), + std::nullopt); + return getSelf().getByIndex(index); + } + + auto get(u32 handle) const noexcept -> std::optional + requires std::is_pointer_v + { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handleToIndex(handle), + std::nullopt); + return getSelf().getByIndex(index); + } + + auto get(u32 handle) noexcept -> std::optional + requires(!std::is_pointer_v) + { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handleToIndex(handle), + std::nullopt); + return getSelf().getByIndex(index).transform( + [](T& value) -> auto { return &value; }); + } + + auto get(u32 handle) const noexcept -> std::optional + requires(!std::is_pointer_v) + { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handleToIndex(handle), + std::nullopt); + return getSelf().getByIndex(index).transform( + [](const T& value) -> auto { return &value; }); + } + + private: + ZTD_DEFINE_CRTP_GET_SELF(); + + // Helpers + static auto indexToHandle(u32 index) noexcept -> u32 { + if constexpr (allow_zero_handle) + return index; + else + return index + 1; + } + + static auto handleToIndex(u32 handle) noexcept -> std::optional { + if constexpr (allow_zero_handle) { + return handle; + } else { + if (handle == 0) { + return std::nullopt; + } + + return handle - 1; + } + } +}; + +} // namespace ztd::mem diff --git a/src/ztd/src/ztd/mem/static_pool.hpp b/src/ztd/src/ztd/mem/static_pool.hpp new file mode 100644 index 00000000..4d48118e --- /dev/null +++ b/src/ztd/src/ztd/mem/static_pool.hpp @@ -0,0 +1,121 @@ +#pragma once + +#include "ztd/mem/pool.hpp" + +namespace ztd::mem { + +template +class StaticPool : public Pool, T, allow_zero_handle> { + friend class Pool, T, allow_zero_handle>; + + public: + StaticPool() noexcept = default; + ~StaticPool() noexcept = default; + + ZTD_MAKE_DEFAULT_COPYABLE(StaticPool); + ZTD_MAKE_DEFAULT_MOVABLE(StaticPool); + + auto begin() noexcept { return Iterator(this, 0); } + auto end() noexcept { return Iterator(this, capacity); } + + auto begin() const noexcept { return ConstIterator(this, 0); } + auto end() const noexcept { return ConstIterator(this, capacity); } + + auto cbegin() const noexcept { return begin(); } + auto cend() const noexcept { return end(); } + + [[nodiscard]] auto getCapacity() const noexcept -> usize { + return capacity; + } + + private: + template + struct IteratorBase { + using PoolType = + std::conditional_t; + PoolType* pool; + usize index; + + IteratorBase(PoolType* p, usize i) noexcept : pool(p), index(i) { + while (index < capacity && !pool->isValidByIndex(index)) { + index++; + } + } + + auto operator*() const noexcept -> T + requires std::is_pointer_v + { + return *pool->objects[index]; + } + auto operator->() const noexcept -> T + requires std::is_pointer_v + { + return *pool->objects[index]; + } + + auto operator*() const noexcept -> T* + requires(!std::is_pointer_v) + { + return &*pool->objects[index]; + } + auto operator->() const noexcept -> T* + requires(!std::is_pointer_v) + { + return &*pool->objects[index]; + } + + auto operator++() noexcept -> IteratorBase& { + do { + index++; + } while (index < capacity && !pool->isValidByIndex(index)); + return *this; + } + + auto operator!=(const IteratorBase& other) const noexcept -> bool { + return index != other.index; + } + }; + + using Iterator = IteratorBase; + using ConstIterator = IteratorBase; + + std::array, capacity> objects; + u32 crnt{0}; + + auto findFreeIndex() noexcept -> std::expected { + if (crnt < capacity) { + return crnt++; + } + + for (u32 i = 0; i < capacity; i++) { + if (!isValidByIndex(i)) { + return i; + } + } + + return std::unexpected(IAllocator::Error::OutOfMemory); + } + + [[nodiscard]] auto freeByIndex(u32 index) noexcept -> bool { + auto& object = objects[index]; + if (object.has_value()) { + object = std::nullopt; + return true; + } else { + return false; + } + } + + [[nodiscard]] auto isValidByIndex(u32 index) const noexcept -> bool { + return objects[index].has_value(); + } + + auto getByIndex(u32 index) noexcept -> std::optional& { + return objects[index]; + } + auto getByIndex(u32 index) const noexcept -> const std::optional& { + return objects[index]; + } +}; + +} // namespace ztd::mem diff --git a/src/ztd/src/ztd/range.hpp b/src/ztd/src/ztd/range.hpp new file mode 100644 index 00000000..f14553b1 --- /dev/null +++ b/src/ztd/src/ztd/range.hpp @@ -0,0 +1,73 @@ +#pragma once + +#include + +#include "ztd/type_aliases.hpp" + +namespace ztd { + +template +class Range { + public: + static constexpr auto fromSize(T begin_, T size) noexcept -> ztd::Range { + return ztd::Range(begin_, begin_ + size); + } + + constexpr Range() noexcept : begin{0}, end{0} {} + constexpr Range(T begin_, T end_) noexcept : begin{begin_}, end{end_} {} + + constexpr auto operator==(const ztd::Range& other) const noexcept { + return begin == other.begin && end == other.end; + } + + constexpr auto operator+=(T offset) noexcept { + begin += offset; + end += offset; + } + + constexpr auto operator-=(T offset) noexcept { + begin -= offset; + end -= offset; + } + + constexpr auto getBegin() const noexcept -> T { return begin; } + constexpr auto setBegin(T begin_) noexcept { begin = begin_; } + + constexpr auto getEnd() const noexcept -> T { return end; } + constexpr auto setEnd(T end_) noexcept { end = end_; } + + constexpr auto getSize() const noexcept -> T { return end - begin; } + constexpr auto setSize(T size) noexcept { end = begin + size; } + + // Intersection + constexpr auto contains(T value) const noexcept -> bool { + return value >= begin && value < end; + } + constexpr auto contains(const ztd::Range& other) const noexcept -> bool { + return other.begin >= begin && other.end <= end; + } + + constexpr auto intersects(const ztd::Range& other) const noexcept + -> bool { + return begin < other.end && end > other.begin; + } + + // Combining + constexpr auto clampedTo(const ztd::Range& bounds) const noexcept + -> ztd::Range { + return ztd::Range(std::max(begin, bounds.begin), + std::min(end, bounds.end)); + } + + constexpr auto merged(const ztd::Range& other) const noexcept + -> ztd::Range { + return ztd::Range(std::min(begin, other.begin), + std::max(end, other.end)); + } + + private: + T begin; + T end; +}; + +} // namespace ztd diff --git a/src/common/time.hpp b/src/ztd/src/ztd/time.hpp similarity index 72% rename from src/common/time.hpp rename to src/ztd/src/ztd/time.hpp index 9166fd10..7a05f496 100644 --- a/src/common/time.hpp +++ b/src/ztd/src/ztd/time.hpp @@ -2,37 +2,37 @@ #include +#include "ztd/type_aliases.hpp" + #if defined(__x86_64__) || defined(_M_X64) || defined(__amd64__) #include #endif -#include "common/types.hpp" - using namespace std::chrono_literals; -namespace hydra { +namespace ztd { #if defined(__x86_64__) || defined(_M_X64) || defined(__amd64__) -inline u64 GetSystemTick() { +inline auto getSystemTick() noexcept -> u64 { _mm_lfence(); u64 res = __rdtsc(); _mm_lfence(); return res; } -inline u64 GetSystemFrequency() { +inline auto getSystemFrequency() noexcept -> u64 { auto nsc_start = std::chrono::steady_clock::now().time_since_epoch(); - u64 tsc_start = GetSystemTick(); + u64 tsc_start = getSystemTick(); // More sleep, more precision. std::this_thread::sleep_for(10ms); auto nsc_end = std::chrono::steady_clock::now().time_since_epoch(); - u64 tsc_end = GetSystemTick(); + u64 tsc_end = getSystemTick(); u64 ns_diff = static_cast(std::chrono::duration_cast( nsc_end - nsc_start) .count()); - u64 res = (tsc_end - tsc_start) * 1000000000ULL / (ns_diff); + u64 res = (tsc_end - tsc_start) * 1000000000ull / (ns_diff); res = res + 100'000 / 2; res -= res % 100'000; return res; @@ -40,13 +40,13 @@ inline u64 GetSystemFrequency() { #elif defined(_M_ARM64) || defined(__aarch64__) -inline u64 GetSystemTick() { +inline auto getSystemTick() noexcept -> u64 { u64 res; __asm__ __volatile__("mrs %0, cntvct_el0; " : "=r"(res)::"memory"); return res; } -inline u64 GetSystemFrequency() { +inline auto getSystemFrequency() noexcept -> u64 { u64 res; __asm__ __volatile__("mrs %0, cntfrq_el0; isb; " : "=r"(res)::"memory"); return res; @@ -54,4 +54,4 @@ inline u64 GetSystemFrequency() { #endif -} // namespace hydra +} // namespace ztd diff --git a/src/ztd/src/ztd/type_aliases.hpp b/src/ztd/src/ztd/type_aliases.hpp new file mode 100644 index 00000000..6b298f48 --- /dev/null +++ b/src/ztd/src/ztd/type_aliases.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +namespace ztd { + +using i8 = std::int8_t; +using i16 = std::int16_t; +using i32 = std::int32_t; +using i64 = std::int64_t; +using i128 = __int128_t; +using u8 = std::uint8_t; +using u16 = std::uint16_t; +using u32 = std::uint32_t; +using u64 = std::uint64_t; +using u128 = __uint128_t; +using usize = std::size_t; +using uptr = std::uintptr_t; +using f32 = float; +using f64 = double; + +} // namespace ztd diff --git a/src/ztd/src/ztd/ztd.hpp b/src/ztd/src/ztd/ztd.hpp new file mode 100644 index 00000000..40092a78 --- /dev/null +++ b/src/ztd/src/ztd/ztd.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "ztd/compress/lz4.hpp" +#include "ztd/hash/xxhash32.hpp" +#include "ztd/linked_list.hpp" +#include "ztd/macros/enum_helper.hpp" +#include "ztd/macros/for_each_helper.hpp" +#include "ztd/mem/c_allocator.hpp" +#include "ztd/mem/default_allocator.hpp" +#include "ztd/mem/page_allocator.hpp" +#include "ztd/mem/static_pool.hpp" +#include "ztd/range.hpp" +#include "ztd/time.hpp" +#include "ztd/type_aliases.hpp"