diff --git a/.clang-tidy b/.clang-tidy index 48098124f..b079e4e03 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -4,10 +4,13 @@ Checks: > modernize-*, performance-*, readability-*, + -bugprone-easily-swappable-parameters, -bugprone-exception-escape, -bugprone-unchecked-optional-access, -bugprone-derived-method-shadowing-base-method, + -bugprone-branch-clone, + -bugprone-signed-bitwise, -cppcoreguidelines-pro-bounds-pointer-arithmetic, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-pro-bounds-array-to-pointer-decay, @@ -18,6 +21,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,19 +32,22 @@ 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, -cppcoreguidelines-pro-type-union-access, -cppcoreguidelines-prefer-member-initializer, + -cppcoreguidelines-avoid-c-arrays, -modernize-use-nodiscard, + -modernize-avoid-c-arrays, -readability-qualified-auto, -readability-avoid-const-params-in-decls, -readability-convert-member-functions-to-static, + -readability-trailing-comma, -performance-enum-size, -performance-no-int-to-ptr, -clang-analyzer-optin.performance.Padding diff --git a/CMakeLists.txt b/CMakeLists.txt index a38e4ec0d..b85b8bb1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,7 @@ add_subdirectory(externals/nx2elf SYSTEM) # date set(BUILD_TZ_LIB ON) +set(USE_SYSTEM_TZ_DB ON) add_subdirectory(externals/date SYSTEM) set(CMAKE_COMPILE_WARNING_AS_ERROR ON) @@ -192,6 +193,7 @@ target_compile_options(hydra_compile_options INTERFACE # Disabled warnings -Wno-missing-designated-field-initializers + -Wno-unused-template # Extensions -Wno-c99-extensions diff --git a/externals/hatch b/externals/hatch index 4ec92a20f..2d8c2fb58 160000 --- a/externals/hatch +++ b/externals/hatch @@ -1 +1 @@ -Subproject commit 4ec92a20f7df5b70679b69e0bdb2ac22ed1d754d +Subproject commit 2d8c2fb5892f654818a9195b02915059320e4050 diff --git a/externals/nx2elf b/externals/nx2elf index 74069c77c..338860b52 160000 --- a/externals/nx2elf +++ b/externals/nx2elf @@ -1 +1 @@ -Subproject commit 74069c77c6dcd2ec184c160fd16f8fe5f9dfe107 +Subproject commit 338860b52ce3307a8c3378504c4e213304547d11 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 17b50c154..d6b7c3d97 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 bf9a75c77..070b4c7f0 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,43 +1,27 @@ add_library(hydra-common - platform.hpp macros.hpp type_aliases.hpp + handle.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 - io/iostream_stream.hpp - io/stream_view.hpp - 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/atomic.hpp b/src/common/atomic.hpp index a9568f297..7ae24ab3c 100644 --- a/src/common/atomic.hpp +++ b/src/common/atomic.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "type_aliases.hpp" #if __cpp_lib_atomic_ref >= 201806L @@ -67,7 +69,8 @@ template <> inline constexpr bool atomic_supported_size = true; template -concept valid_atomic = std::is_trivially_copyable_v and atomic_supported_size; +concept valid_atomic = + std::is_trivially_copyable_v and atomic_supported_size; template void atomic_store(T* ptr, T value) { diff --git a/src/common/common.hpp b/src/common/common.hpp index 86236154e..3c40fe81f 100644 --- a/src/common/common.hpp +++ b/src/common/common.hpp @@ -11,23 +11,13 @@ #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/handle.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 8febaedcf..2fa6f24b3 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 3f2ff14ff..7d551d036 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 8dc7fc33f..000000000 --- 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 e85822190..1aa4ebd80 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 000000000..bc4b3d9ff --- /dev/null +++ b/src/common/fmt_helper.hpp @@ -0,0 +1,115 @@ +#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; + } +}; + +ENABLE_ENUM_FLAGS_FORMATTING(ztd::fs::File::OpenFlags, Read, "read", Write, + "write", Append, "append") + +ENABLE_ENUM_FLAGS_FORMATTING(ztd::fs::File::CreateFlags, Read, "read", Append, + "append", Exclusive, "exclusive", Truncate, + "truncate") diff --git a/src/common/functions.hpp b/src/common/functions.hpp index f131640ed..c5e5c2c33 100644 --- a/src/common/functions.hpp +++ b/src/common/functions.hpp @@ -11,19 +11,11 @@ namespace hydra { -[[noreturn]] inline void builtin_unreachable() { -#if defined(_MSC_VER) && !defined(__clang__) // MSVC - __assume(false); -#else // GCC, Clang - __builtin_unreachable(); -#endif -} - [[noreturn]] inline void unreachable() { #ifdef HYDRA_DEBUG LOG_FATAL(Common, "Unreachable code reached"); #else - builtin_unreachable(); + ztd::builtin::unreachable(); #endif } @@ -84,8 +76,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/handle.hpp b/src/common/handle.hpp new file mode 100644 index 000000000..cfa2be9c8 --- /dev/null +++ b/src/common/handle.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include "common/type_aliases.hpp" + +namespace hydra { + +struct Handle { + public: + static constexpr Handle FromIndex(usize index) noexcept { + return {static_cast(index + 1)}; + } + + constexpr Handle() noexcept = default; + constexpr Handle(u32 raw_) noexcept : raw{raw_} {} + + bool operator==(Handle other) const noexcept { return raw == other.raw; } + + u32 GetRaw() const noexcept { return raw; } + + std::optional ToIndex() const noexcept { + if (raw == 0) + return std::nullopt; + return raw - 1; + } + + [[nodiscard]] bool IsValid() const noexcept { return raw != 0; } + + private: + u32 raw{0}; +}; + +constexpr Handle INVALID_HANDLE = Handle(0); + +} // namespace hydra + +template <> +struct fmt::formatter : formatter { + template + auto format(hydra::Handle handle, FormatContext& ctx) const { + if (!handle.IsValid()) + return formatter::format("null", ctx); + return formatter::format( + fmt::format("{:#x}", handle.GetRaw()), ctx); + } +}; diff --git a/src/common/io/continuous_stream.hpp b/src/common/io/continuous_stream.hpp deleted file mode 100644 index 134a00a32..000000000 --- a/src/common/io/continuous_stream.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "common/io/stream.hpp" - -namespace hydra::io { - -class IContinuousStream : public IStream { - public: - IContinuousStream() noexcept = default; - ~IContinuousStream() noexcept = default; - - MAKE_DEFAULT_COPYABLE(IContinuousStream); - MAKE_NON_MOVABLE(IContinuousStream); - - u64 GetSeek() const override { return seek; } - void SeekTo(u64 seek_) override { seek = seek_; } - void SeekBy(u64 offset) override { seek += offset; } - - protected: - void ReadRaw(std::span buffer) override { - const auto ptr = ConsumePtrRaw(buffer.size()); - std::copy(ptr, ptr + buffer.size(), buffer.data()); - } - - void WriteRaw(std::span buffer) override { - auto ptr = ConsumePtrRaw(buffer.size()); - std::copy(buffer.data(), buffer.data() + buffer.size(), ptr); - } - - u8* ConsumePtrRaw(usize size) override { - const auto ptr = GetPtr() + seek; - SeekBy(size); - return ptr; - } - - virtual u8* GetPtr() = 0; - - private: - u64 seek{0}; -}; - -} // namespace hydra::io diff --git a/src/common/io/iostream_stream.hpp b/src/common/io/iostream_stream.hpp deleted file mode 100644 index 1d9f67d09..000000000 --- a/src/common/io/iostream_stream.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include -#include - -#include "common/io/stream.hpp" - -namespace hydra::io { - -class IostreamStream : public IStream { - public: - IostreamStream(std::iostream& stream_) : stream{stream_} {} - - u64 GetSeek() const override { return static_cast(stream.tellg()); } - void SeekTo(u64 seek) override { - stream.seekg(static_cast(seek), std::ios::beg); - } - void SeekBy(u64 offset) override { - stream.seekg(static_cast(offset), std::ios::cur); - } - - u64 GetSize() const override { - const auto seek = stream.tellg(); - stream.seekg(0, std::ios::end); - const auto size = stream.tellg(); - stream.seekg(seek, std::ios::beg); - return static_cast(size); - } - - void Flush() override { stream.flush(); } - - void ReadRaw(std::span buffer) override { - stream.read(reinterpret_cast(buffer.data()), - static_cast(buffer.size())); - } - - void WriteRaw(std::span buffer) override { - stream.write(reinterpret_cast(buffer.data()), - static_cast(buffer.size())); - } - - private: - std::iostream& stream; -}; - -} // namespace hydra::io diff --git a/src/common/io/memory_stream.hpp b/src/common/io/memory_stream.hpp deleted file mode 100644 index 1a3f92128..000000000 --- a/src/common/io/memory_stream.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "common/io/continuous_stream.hpp" - -namespace hydra::io { - -class MemoryStream : public IContinuousStream { - public: - MemoryStream(std::span data_) : data{data_} {} - - MAKE_DEFAULT_COPYABLE(MemoryStream); - MAKE_DEFAULT_MOVABLE(MemoryStream); - - u64 GetSize() const override { return data.size(); } - - u8* GetPtr() override { return data.data(); } - - private: - std::span data; -}; - -} // namespace hydra::io diff --git a/src/common/io/sparse_stream.hpp b/src/common/io/sparse_stream.hpp deleted file mode 100644 index 499a043bb..000000000 --- a/src/common/io/sparse_stream.hpp +++ /dev/null @@ -1,132 +0,0 @@ -#pragma once - -#include "common/io/stream.hpp" -#include "common/range.hpp" - -namespace hydra::io { - -class SparseStream : public IStream { - public: - struct Entry { - Range range; - IStream* stream; - }; - - // Entries must be sorted by offset - SparseStream(std::vector entries_, u64 size_) - : entries{std::move(entries_)}, size{size_} {} - - u64 GetSeek() const override { return seek; } - void SeekTo(u64 seek_) override { seek = seek_; } - void SeekBy(u64 offset) override { seek += offset; } - - u64 GetSize() const override { return size; } - - void Flush() override { - // TODO: only flush modified entries - for (auto entry : entries) - entry.stream->Flush(); - } - - void ReadRaw(std::span buffer) override { - while (!buffer.empty()) { - ASSERT_DEBUG(seek + buffer.size() <= size, Common, - "Seek out of bounds ({} > {})", seek + buffer.size(), - size); - - const auto entry = GetEntry(seek); - const auto max_read_size = std::min( - entry.range.GetEnd() - seek, static_cast(buffer.size())); - if (entry.stream != nullptr) { - entry.stream->SeekTo(seek - entry.range.GetBegin()); - entry.stream->ReadRaw(buffer.subspan(0, max_read_size)); - } else { - std::fill(buffer.begin(), - buffer.begin() + static_cast(max_read_size), 0); - } - - seek += max_read_size; - buffer = buffer.subspan(max_read_size); - } - } - - void WriteRaw(std::span buffer) override { - while (!buffer.empty()) { - ASSERT_DEBUG(seek + buffer.size() <= size, Common, - "Seek out of bounds ({} > {})", seek + buffer.size(), - size); - - const auto entry = GetEntry(seek); - const auto max_write_size = std::min( - entry.range.GetEnd() - seek, static_cast(buffer.size())); - if (entry.stream != nullptr) { - entry.stream->SeekTo(seek - entry.range.GetBegin()); - entry.stream->WriteRaw(buffer.subspan(0, max_write_size)); - } - - seek += max_write_size; - buffer = buffer.subspan(max_write_size); - } - } - - protected: - std::vector entries; - - private: - u64 size; - - u64 seek{0}; - std::optional cached_entry{std::nullopt}; - - // Helpers - Entry GetEntry(u64 offset) { - // First, check if the entry has been cached - if (cached_entry.has_value()) { - const auto entry = cached_entry.value(); - if (entry.range.Contains(offset)) - return entry; - } - - // Find the entry that contains the offset - auto next_it = - std::upper_bound(entries.begin(), entries.end(), offset, - [](u64 offset, const Entry& entry) { - 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}; - - auto it = std::prev(next_it); - - // Check if entry is past the range - if (!it->range.Contains(offset)) { - if (next_it == entries.end()) - return {.range = {it->range.GetEnd(), size - offset}, - .stream = nullptr}; - - return {.range = {it->range.GetEnd(), next_it->range.GetBegin()}, - .stream = nullptr}; - } - - // Cache the entry and return it - cached_entry = *it; - return *it; - } -}; - -// TODO: remove -class OwnedSparseStream : public SparseStream { - public: - using SparseStream::SparseStream; - - ~OwnedSparseStream() override { - for (auto entry : entries) - delete entry.stream; - } - - MAKE_NON_COPYABLE(OwnedSparseStream); -}; - -} // namespace hydra::io diff --git a/src/common/io/stream.hpp b/src/common/io/stream.hpp deleted file mode 100644 index f5a1384f4..000000000 --- a/src/common/io/stream.hpp +++ /dev/null @@ -1,134 +0,0 @@ -#pragma once - -#include "common/log.hpp" -#include "common/types.hpp" - -namespace hydra::io { - -class IStream { - friend class StreamView; - friend class SparseStream; - - public: - IStream() = default; - virtual ~IStream() noexcept = default; - - MAKE_DEFAULT_COPYABLE(IStream); - MAKE_DEFAULT_MOVABLE(IStream); - - virtual u64 GetSeek() const = 0; - virtual void SeekTo(u64 seek) { - (void)seek; - LOG_FATAL(Common, "Stream does not support arbitrary seeking"); - } - virtual void SeekBy(u64 offset) = 0; - - virtual u64 GetSize() const = 0; - u64 GetRemainingSize() const { return GetSize() - GetSeek(); } - - virtual void Flush() {} - - // Read - template - T Read() { - T result; - ReadRaw(std::span(reinterpret_cast(&result), sizeof(T))); - return result; - } - - template - void ReadToRef(T& result) { - ReadRaw(std::span(reinterpret_cast(&result), sizeof(T))); - } - - template - void ReadToSpan(std::span buffer) { - ReadRaw(std::span(reinterpret_cast(buffer.data()), - buffer.size_bytes())); - } - - template - const T* ReadPtr() { - return reinterpret_cast(ConsumePtrRaw(sizeof(T))); - } - - template - std::span ReadSpan(usize count = 1) { - const auto ptr = - reinterpret_cast(ConsumePtrRaw(count * sizeof(T))); - return std::span(ptr, count); - } - - template - std::span ReadSpanWhole() { - return ReadSpan((GetSize() - GetSeek()) / sizeof(T)); - } - - std::string_view ReadString(usize size) { - const auto ptr = ReadPtr(); - return {ptr, size}; - } - - std::string_view ReadNullTerminatedString() { - const char* ptr = ReadPtr(); - usize size = 0; - while (ptr[size] != '\0') { - SeekBy(1); - size++; - } - - return {ptr, size}; - } - - // Write - template - void Write(const T& value) { - WriteRaw(std::span(reinterpret_cast(&value), sizeof(T))); - } - - template - void WriteSpan(std::span span) { - WriteRaw(std::span(reinterpret_cast(span.data()), - span.size_bytes())); - } - - template - T* WriteReturningPtr() { - return WriteReturningSpan(1).data(); - } - - template - T* WriteReturningPtr(const T& value) { - auto ptr = WriteReturningPtr(); - *ptr = value; - return ptr; - } - - template - std::span WriteReturningSpan(usize count) { - return std::span( - reinterpret_cast(ConsumePtrRaw(count * sizeof(T))), count); - } - - void WriteNullTerminatedString(std::string_view str) { - WriteSpan( - std::span(reinterpret_cast(str.data()), str.size())); - Write('\0'); - } - - protected: - virtual void ReadRaw(std::span buffer) { - (void)buffer; - LOG_FATAL(Common, "Stream is write-only"); - } - virtual void WriteRaw(std::span buffer) { - (void)buffer; - LOG_FATAL(Common, "Stream is read-only"); - } - virtual u8* ConsumePtrRaw(usize size) { - (void)size; - LOG_FATAL(Common, "Stream is not continuous"); - } -}; - -} // namespace hydra::io diff --git a/src/common/io/stream_view.hpp b/src/common/io/stream_view.hpp deleted file mode 100644 index 1c95ab65d..000000000 --- a/src/common/io/stream_view.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "common/io/stream.hpp" - -namespace hydra::io { - -class StreamView : public IStream { - public: - StreamView(IStream* base_, u64 offset_, u64 size_) - : base{base_}, offset{offset_}, size{size_} { - base->SeekTo(offset); - } - StreamView(IStream* base_, u64 offset_) - : StreamView(base_, offset_, base_->GetSize() - offset_) {} - - u64 GetSeek() const override { return base->GetSeek() - offset; } - void SeekTo(u64 seek) override { base->SeekTo(offset + seek); } - void SeekBy(u64 offset_) override { base->SeekBy(offset_); } - - u64 GetSize() const override { return size; } - - void Flush() override { base->Flush(); } - - void ReadRaw(std::span buffer) override { base->ReadRaw(buffer); } - void WriteRaw(std::span buffer) override { - base->WriteRaw(buffer); - } - u8* ConsumePtrRaw(usize size_) override { - return base->ConsumePtrRaw(size_); - } - - protected: - IStream* base; - - private: - u64 offset; - u64 size; -}; - -// TODO: remove -class OwnedStreamView : public StreamView { - public: - using StreamView::StreamView; - - ~OwnedStreamView() override { delete base; } - - 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 7b3d6269f..000000000 --- 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 4f775508e..000000000 --- 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 656d230e5..0b9e04b62 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 @@ -43,14 +43,14 @@ { \ LOG(Fatal, c, __VA_ARGS__); \ abort(); \ - builtin_unreachable(); \ + ztd::builtin::unreachable(); \ } #define LOG_FUNC_STUBBED(c) LOG_STUBBED(c, "{}", __func__) #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 a75b7a4ad..000000000 --- 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 0facb327b..48ec9064a 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 b75e15924..000000000 --- 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 9b05e4556..000000000 --- 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 5f423b8d1..000000000 --- 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 c1a975972..430b2b73b 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 183824a67..000000000 --- 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 b0d78f147..599e740b0 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 50f10c798..3d7ad583b 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 6afa97f57..60154f340 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; @@ -27,8 +26,7 @@ using magic4_t = u32; using paddr_t = u64; using vaddr_t = u64; using gpu_vaddr_t = u64; -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 71c8c176d..96a68a81e 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/CMakeLists.txt b/src/core/CMakeLists.txt index a2fa3bf69..46614de05 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,5 +1,6 @@ add_library(hydra-core horizon/const.hpp + horizon/handle_pool.hpp horizon/os.cpp horizon/os.hpp horizon/kernel/const.hpp diff --git a/src/core/debugger/debugger.hpp b/src/core/debugger/debugger.hpp index 5cdd6af0c..283d97ba6 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 126f4c3fc..ab9560383 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 += ";"; @@ -706,8 +706,8 @@ void GdbServer::HandleGetExecutables() { auto file = debugger.executables.at(module_.name); auto stream = file->Open(horizon::filesystem::FileOpenFlags::Read); - std::vector data(stream->GetSize()); - stream->ReadToSpan(std::span(data)); + std::vector data(stream->getSize()); + stream->readToSpan(std::span(data)); delete stream; @@ -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 3eb0b0ad4..3fb2b61a1 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/applet_base.hpp b/src/core/horizon/applets/applet_base.hpp index efa92dc0f..2dbbdc3e1 100644 --- a/src/core/horizon/applets/applet_base.hpp +++ b/src/core/horizon/applets/applet_base.hpp @@ -21,7 +21,7 @@ class AppletBase { // Helpers // Data - io::MemoryStream PopInDataRaw() { + ztd::io::MemoryStream PopInDataRaw() { auto data = controller.PopInData()->GetData(); return {data}; } @@ -29,10 +29,10 @@ class AppletBase { template T PopInData() { auto stream = PopInDataRaw(); - ASSERT(stream.GetSize() >= sizeof(T), Applets, - "Not enough space ({} < {})", stream.GetSize(), sizeof(T)); + ASSERT(stream.getSize() >= sizeof(T), Applets, + "Not enough space ({} < {})", stream.getSize(), sizeof(T)); - return stream.Read(); + return stream.read(); } void PushOutDataRaw(std::vector data) { @@ -47,7 +47,7 @@ class AppletBase { } // Interactive data - io::MemoryStream PopInteractiveInDataRaw() { + ztd::io::MemoryStream PopInteractiveInDataRaw() { // TODO: wait // controller.GetInteractiveInDataEvent().Wait(); auto data = controller.PopInteractiveInData()->GetData(); @@ -57,10 +57,10 @@ class AppletBase { template T PopInteractiveInData() { auto stream = PopInteractiveInDataRaw(); - ASSERT(stream.GetSize() >= sizeof(T), Applets, - "Not enough space ({} < {})", stream.GetSize(), sizeof(T)); + ASSERT(stream.getSize() >= sizeof(T), Applets, + "Not enough space ({} < {})", stream.getSize(), sizeof(T)); - return stream.Read(); + return stream.read(); } void PushInteractiveOutDataRaw(std::vector data) { diff --git a/src/core/horizon/applets/error/applet.cpp b/src/core/horizon/applets/error/applet.cpp index 1db06cec5..7904a6205 100644 --- a/src/core/horizon/applets/error/applet.cpp +++ b/src/core/horizon/applets/error/applet.cpp @@ -9,14 +9,14 @@ namespace hydra::horizon::applets::error { result_t Applet::Run(System& system) { // TODO: PopInData auto param_reader = PopInDataRaw(); - const auto param_common = param_reader.Read(); + const auto param_common = param_reader.read(); // TODO: context (if present) ReturnValue ret; switch (param_common.type) { case ErrorType::ApplicationError: { - const auto param = param_reader.Read(); + const auto param = param_reader.read(); // TODO: handle empty messages system.GetUIHandler().ShowMessageDialog( diff --git a/src/core/horizon/applets/player_select/applet.cpp b/src/core/horizon/applets/player_select/applet.cpp index 69097d2db..019e3a619 100644 --- a/src/core/horizon/applets/player_select/applet.cpp +++ b/src/core/horizon/applets/player_select/applet.cpp @@ -7,7 +7,7 @@ namespace hydra::horizon::applets::player_select { result_t Applet::Run(System& system) { auto settings_reader = PopInDataRaw(); - const auto settings = settings_reader.Read(); + const auto settings = settings_reader.read(); (void)settings; // This should give the user an option to select a profile to use. However, diff --git a/src/core/horizon/applets/software_keyboard/applet.cpp b/src/core/horizon/applets/software_keyboard/applet.cpp index 682247a34..89d197ba9 100644 --- a/src/core/horizon/applets/software_keyboard/applet.cpp +++ b/src/core/horizon/applets/software_keyboard/applet.cpp @@ -43,19 +43,19 @@ result_t Applet::Run(System& system) { const usize size = sizeof(u64) + ((output_text.size() + 1) * sizeof(char16_t)); std::vector bytes(size); - io::MemoryStream stream(bytes); - stream.Write(size); - stream.WriteSpan(std::span(output_text)); - stream.Write(u'\0'); + ztd::io::MemoryStream stream(bytes); + stream.write(size); + stream.writeSpan(std::span(output_text)); + stream.write(u'\0'); PushInteractiveOutDataRaw(std::move(bytes)); auto reader = PopInteractiveInDataRaw(); - auto res = reader.Read(); + auto res = reader.read(); if (res == TextCheckResult::Success) break; // Dialog - std::u16string msg = reader.ReadPtr(); + std::u16string msg = reader.readPtr(); system.GetUIHandler().ShowMessageDialog( (res == TextCheckResult::ShowFailureDialog ? ui::MessageDialogType::Error @@ -69,10 +69,10 @@ result_t Applet::Run(System& system) { const usize size = sizeof(SoftwareKeyboardResult) + ((output_text.size() + 1) * sizeof(char16_t)); std::vector bytes(size); - io::MemoryStream stream(bytes); - stream.Write(result); - stream.WriteSpan(std::span(output_text)); - stream.Write(u'\0'); + ztd::io::MemoryStream stream(bytes); + stream.write(result); + stream.writeSpan(std::span(output_text)); + stream.write(u'\0'); PushOutDataRaw(std::move(bytes)); } diff --git a/src/core/horizon/applets/software_keyboard/const.hpp b/src/core/horizon/applets/software_keyboard/const.hpp index 0d022f2ec..8734784d6 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 28073628f..ed5c508e4 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 67b13c4fe..e3ca1c067 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 26ad5dde1..78a7eef35 100644 --- a/src/core/horizon/display/driver.hpp +++ b/src/core/horizon/display/driver.hpp @@ -2,6 +2,7 @@ #include "core/horizon/display/binder.hpp" #include "core/horizon/display/display.hpp" +#include "core/horizon/handle_pool.hpp" namespace hydra::horizon::display { @@ -10,12 +11,14 @@ class Driver { Driver(System& system_); // Displays - Display& GetDisplay(handle_id_t id) { + Display& GetDisplay(Handle handle) { std::scoped_lock lock(display_mutex); - return *display_pool.Get(id); + ZTD_ASSIGN_OR(auto display, display_pool.Get(handle), + LOG_FATAL(Horizon, "Failed to get display {}", handle)); + return *display; } - handle_id_t GetDisplayIDFromName(const std::string& name) { + Handle GetDisplayIDFromName(const std::string& name) { (void)this; LOG_NOT_IMPLEMENTED(Horizon, "GetDisplayIDFromName (name: {})", name); @@ -28,37 +31,42 @@ class Driver { } // Layers - u32 CreateLayer(kernel::Process* process, u32 binder_id) { + Handle CreateLayer(kernel::Process* process, Handle binder_handle) { 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_handle) + .value(); } - void DestroyLayer(u32 id) { + void DestroyLayer(Handle handle) { std::scoped_lock lock(layer_mutex); - delete layer_pool.Get(id); - layer_pool.Free(id); + ASSERT_DEBUG(layer_pool.Free(handle), Horizon, "Invalid layer {}", + handle); } - Layer& GetLayer(u32 id) { + Layer& GetLayer(Handle handle) { std::scoped_lock lock(layer_mutex); - return *layer_pool.Get(id); + ZTD_ASSIGN_OR(auto layer, layer_pool.Get(handle), + LOG_FATAL(Horizon, "Failed to get layer {}", handle)); + return *layer; } // Binders - u32 CreateBinder() { + Handle CreateBinder() { std::scoped_lock lock(binder_mutex); - return binder_pool.Insert(new Binder()); + return binder_pool.Insert().value(); } - void DestroyBinder(u32 id) { + void DestroyBinder(Handle handle) { std::scoped_lock lock(binder_mutex); - delete binder_pool.Get(id); - binder_pool.Free(id); + ASSERT_DEBUG(binder_pool.Free(handle), Horizon, "Invalid binder {}", + handle); } - Binder& GetBinder(u32 id) { + Binder& GetBinder(Handle handle) { std::scoped_lock lock(binder_mutex); - return *binder_pool.Get(id); + ZTD_ASSIGN_OR(auto binder, binder_pool.Get(handle), + LOG_FATAL(Horizon, "Failed to get binder {}", handle)); + return *binder; } // Presenting @@ -75,11 +83,11 @@ class Driver { System& system; std::mutex display_mutex; - StaticPool display_pool; + StaticHandlePool display_pool; std::mutex layer_mutex; - StaticPool layer_pool; + StaticHandlePool layer_pool; std::mutex binder_mutex; - StaticPool binder_pool; + StaticHandlePool binder_pool; }; } // namespace hydra::horizon::display diff --git a/src/core/horizon/display/layer.cpp b/src/core/horizon/display/layer.cpp index ba22cfafe..ed3aee6ab 100644 --- a/src/core/horizon/display/layer.cpp +++ b/src/core/horizon/display/layer.cpp @@ -13,7 +13,7 @@ namespace hydra::horizon::display { bool Layer::AcquirePresentTexture( hw::tegra_x1::gpu::renderer::ICommandBuffer* command_buffer) { // Get the buffer to present - auto& binder = system.GetOS().GetDisplayDriver().GetBinder(binder_id); + auto& binder = system.GetOS().GetDisplayDriver().GetBinder(binder_handle); BqBufferInput input; i32 slot = binder.ConsumeBuffer(input); @@ -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) @@ -78,7 +78,7 @@ void Layer::Present(hw::tegra_x1::gpu::renderer::ICommandBuffer* command_buffer, AccumulatedTime Layer::GetAccumulatedDT() { return system.GetOS() .GetDisplayDriver() - .GetBinder(binder_id) + .GetBinder(binder_handle) .GetAccumulatedDT(); } diff --git a/src/core/horizon/display/layer.hpp b/src/core/horizon/display/layer.hpp index 2d02cb239..11224fc2d 100644 --- a/src/core/horizon/display/layer.hpp +++ b/src/core/horizon/display/layer.hpp @@ -16,8 +16,8 @@ class Driver; class Layer { public: - Layer(System& system_, kernel::Process* process_, u32 binder_id_) - : system{system_}, process{process_}, binder_id{binder_id_} {} + Layer(System& system_, kernel::Process* process_, Handle binder_handle_) + : system{system_}, process{process_}, binder_handle{binder_handle_} {} // TODO void Open() {} @@ -35,7 +35,7 @@ class Layer { private: System& system; kernel::Process* process; - u32 binder_id; + Handle binder_handle; float2 position{0, 0}; uint2 size{LAYER_SIZE_AUTO}; @@ -47,7 +47,7 @@ class Layer { public: GETTER(process, GetProcess); - GETTER(binder_id, GetBinderID); + GETTER(binder_handle, GetBinderHandle); SETTER(position, SetPosition); SETTER(size, SetSize); GETTER_AND_SETTER(z, GetZ, SetZ); diff --git a/src/core/horizon/filesystem/const.hpp b/src/core/horizon/filesystem/const.hpp index 255e1b63a..2032a3e32 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/content_archive.cpp b/src/core/horizon/filesystem/content_archive.cpp index 1a26d6af5..d58ae2e8c 100644 --- a/src/core/horizon/filesystem/content_archive.cpp +++ b/src/core/horizon/filesystem/content_archive.cpp @@ -203,7 +203,7 @@ ContentArchive::ContentArchive(IFile* file) { auto stream = file->Open(FileOpenFlags::Read); // Header - const auto header = stream->Read
(); + const auto header = stream->read
(); // TODO: allow other NCA versions as well ASSERT(header.magic == make_magic4('N', 'C', 'A', '3'), Filesystem, "Invalid NCA magic 0x{:08x}", header.magic); diff --git a/src/core/horizon/filesystem/disk_file.cpp b/src/core/horizon/filesystem/disk_file.cpp index 5d110f1be..6d5bc7711 100644 --- a/src/core/horizon/filesystem/disk_file.cpp +++ b/src/core/horizon/filesystem/disk_file.cpp @@ -50,16 +50,16 @@ void DiskFile::Flush() { // LOG_FS_ACCESS(host_path, "file flushed"); } -io::IStream* DiskFile::Open(FileOpenFlags flags) { - std::ios::openmode std_flags = std::ios::binary; +ztd::io::IStream* DiskFile::Open(FileOpenFlags flags) { + auto ztd_flags = ztd::fs::File::OpenFlags::None; if (any(flags & FileOpenFlags::Read)) - std_flags |= std::ios::in; + ztd_flags |= ztd::fs::File::OpenFlags::Read; if (any(flags & FileOpenFlags::Write)) - std_flags |= std::ios::out; + ztd_flags |= ztd::fs::File::OpenFlags::Write; if (any(flags & FileOpenFlags::Append)) - std_flags |= std::ios::app; + ztd_flags |= ztd::fs::File::OpenFlags::Append; - return new DiskStream(path, std_flags); + return new DiskStream(path, ztd_flags); } u64 DiskFile::GetSize() const { diff --git a/src/core/horizon/filesystem/disk_file.hpp b/src/core/horizon/filesystem/disk_file.hpp index 43414c6d7..9dc360e05 100644 --- a/src/core/horizon/filesystem/disk_file.hpp +++ b/src/core/horizon/filesystem/disk_file.hpp @@ -5,28 +5,28 @@ #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 { -class DiskStream : public io::IostreamStream { +class DiskStream : public ztd::io::FileStream { public: - // Fucking C++ STL doesn't allow creating std::fstream with std::string_view - // as a path - DiskStream(const std::string_view path, std::ios::openmode flags) - : io::IostreamStream(stream), stream(std::string(path), flags) { - LOG_FS_ACCESS(path, "file opened (flags: {})", flags); - } - ~DiskStream() override { - stream.close(); + // HACK: FileStream takes a reference to File, so its okay to initialize + // file after calling the base constructor + DiskStream(const std::string_view path, + ztd::fs::File::OpenFlags flags) noexcept + : ztd::io::FileStream(file) { + // HACK: construct a temporary string + ZTD_ASSIGN_OR( + file, ztd::fs::openFileAbsolute(std::string(path), flags), + { LOG_FATAL(Filesystem, "Failed to open file at path {}", path); }); - // TODO - // LOG_FS_ACCESS(path, "file closed"); + LOG_FS_ACCESS(path, "file opened (flags: {})", flags); } private: - std::fstream stream; + ztd::fs::File file; }; class DiskFile : public IFile { @@ -37,7 +37,7 @@ class DiskFile : public IFile { void Resize(u64 new_size) override; void Flush() override; - io::IStream* Open(FileOpenFlags flags) override; + ztd::io::IStream* Open(FileOpenFlags flags) override; u64 GetSize() const override; diff --git a/src/core/horizon/filesystem/file.cpp b/src/core/horizon/filesystem/file.cpp index feb6a3a33..3cb0fc0cc 100644 --- a/src/core/horizon/filesystem/file.cpp +++ b/src/core/horizon/filesystem/file.cpp @@ -4,23 +4,29 @@ namespace hydra::horizon::filesystem { void IFile::Save(std::string_view host_path) const { // Create file - std::fstream ofs( - std::string(host_path), - std::ios::out | std::ios::binary); // HACK: construct a temporary string - io::IostreamStream out_stream(ofs); + // HACK: construct a temporary string + ZTD_ASSIGN_OR(auto file, + ztd::fs::openFileAbsolute(std::string(host_path), + ztd::fs::File::OpenFlags::Write), + { + LOG_ERROR(Services, "Failed to write user at path {}", + host_path); + return; + }); + ztd::io::FileStream out_stream(file); // Read const auto stream = const_cast(this)->Open(FileOpenFlags::Read); // HACK std::array buffer; - while (stream->GetSeek() < stream->GetSize()) { + while (stream->getSeek() < stream->getSize()) { std::span span(buffer.data(), buffer.data() + std::min(static_cast(buffer.size()), - stream->GetSize() - stream->GetSeek())); - stream->ReadToSpan(span); - out_stream.WriteSpan(std::span(span)); + stream->getSize() - stream->getSeek())); + stream->readToSpan(span); + out_stream.writeSpan(std::span(span)); } delete stream; diff --git a/src/core/horizon/filesystem/file.hpp b/src/core/horizon/filesystem/file.hpp index a4fb11510..031664728 100644 --- a/src/core/horizon/filesystem/file.hpp +++ b/src/core/horizon/filesystem/file.hpp @@ -20,7 +20,7 @@ class IFile : public IEntry { } virtual void Flush() {} - virtual io::IStream* Open(FileOpenFlags flags) = 0; + virtual ztd::io::IStream* Open(FileOpenFlags flags) = 0; virtual u64 GetSize() const = 0; diff --git a/src/core/horizon/filesystem/file_view.hpp b/src/core/horizon/filesystem/file_view.hpp index 0f7e63f89..d429ffb29 100644 --- a/src/core/horizon/filesystem/file_view.hpp +++ b/src/core/horizon/filesystem/file_view.hpp @@ -4,6 +4,18 @@ namespace hydra::horizon::filesystem { +class OwnedStreamView : public ztd::io::StreamView { + public: + OwnedStreamView(ztd::io::IStream* base_, u64 offset, u64 size) noexcept + : StreamView(base_, offset, size), base{base_} {} + ~OwnedStreamView() noexcept override { delete base; } + + ZTD_MAKE_NON_COPYABLE(OwnedStreamView); + + private: + ztd::io::IStream* base; +}; + class FileView : public IFile { public: FileView(IFile* base_, u64 offset_, u64 size_ = invalid()) @@ -18,8 +30,8 @@ class FileView : public IFile { } } - io::IStream* Open(FileOpenFlags flags) override { - return new io::OwnedStreamView(base->Open(flags), offset, size); + ztd::io::IStream* Open(FileOpenFlags flags) override { + return new OwnedStreamView(base->Open(flags), offset, size); } u64 GetSize() const override { return size; } diff --git a/src/core/horizon/filesystem/memory_file.hpp b/src/core/horizon/filesystem/memory_file.hpp index a2bbb15d4..1f9792bd7 100644 --- a/src/core/horizon/filesystem/memory_file.hpp +++ b/src/core/horizon/filesystem/memory_file.hpp @@ -11,8 +11,8 @@ class MemoryFile : public IFile { void Resize(u64 new_size) override { data.resize(new_size); } - io::IStream* Open([[maybe_unused]] FileOpenFlags flags) override { - return new io::MemoryStream(data); + ztd::io::IStream* Open([[maybe_unused]] FileOpenFlags flags) override { + return new ztd::io::MemoryStream(data); } u64 GetSize() const override { return data.size(); } diff --git a/src/core/horizon/filesystem/partition_filesystem.hpp b/src/core/horizon/filesystem/partition_filesystem.hpp index 504c7da92..891a00bf1 100644 --- a/src/core/horizon/filesystem/partition_filesystem.hpp +++ b/src/core/horizon/filesystem/partition_filesystem.hpp @@ -42,7 +42,7 @@ class PartitionFilesystem final : public Directory { auto stream = file->Open(FileOpenFlags::Read); // Header - const auto header = stream->Read(); + const auto header = stream->read(); if (!is_hfs) { ASSERT(header.magic == make_magic4('P', 'F', 'S', '0'), Filesystem, "Invalid PFS0 magic 0x{:08x}", header.magic); @@ -59,15 +59,15 @@ class PartitionFilesystem final : public Directory { const u64 data_offset = string_table_offset + header.string_table_size; // String table - stream->SeekTo(string_table_offset); + stream->seekTo(string_table_offset); std::string string_table; string_table.resize(header.string_table_size); - stream->ReadToSpan(std::span(string_table)); + stream->readToSpan(std::span(string_table)); // Entries - stream->SeekTo(entries_offset); + stream->seekTo(entries_offset); for (u32 i = 0; i < header.entry_count; i++) { - const auto entry = stream->Read(); + const auto entry = stream->read(); const std::string entry_name(string_table.data() + entry.string_offset); diff --git a/src/core/horizon/filesystem/romfs/parser.cpp b/src/core/horizon/filesystem/romfs/parser.cpp index 986b4aad8..eb3d10af5 100644 --- a/src/core/horizon/filesystem/romfs/parser.cpp +++ b/src/core/horizon/filesystem/romfs/parser.cpp @@ -4,19 +4,19 @@ namespace hydra::horizon::filesystem::romfs { -Parser::Parser(io::IStream* stream, IFile* data_file_, +Parser::Parser(ztd::io::IStream* stream, IFile* data_file_, const TableLocation& file_meta_loc, const TableLocation& directory_meta_loc) : data_file{data_file_} { // File meta file_meta.resize(file_meta_loc.size); - stream->SeekTo(file_meta_loc.offset); - stream->ReadToSpan(std::span(file_meta)); + stream->seekTo(file_meta_loc.offset); + stream->readToSpan(std::span(file_meta)); // Directory meta directory_meta.resize(directory_meta_loc.size); - stream->SeekTo(directory_meta_loc.offset); - stream->ReadToSpan(std::span(directory_meta)); + stream->seekTo(directory_meta_loc.offset); + stream->readToSpan(std::span(directory_meta)); } void Parser::LoadFile(Directory* parent, u32 offset) const { diff --git a/src/core/horizon/filesystem/romfs/parser.hpp b/src/core/horizon/filesystem/romfs/parser.hpp index eb9fce1d3..0a884ee54 100644 --- a/src/core/horizon/filesystem/romfs/parser.hpp +++ b/src/core/horizon/filesystem/romfs/parser.hpp @@ -8,7 +8,7 @@ namespace hydra::horizon::filesystem::romfs { class Parser { public: - Parser(io::IStream* stream, IFile* data_file_, + Parser(ztd::io::IStream* stream, IFile* data_file_, const TableLocation& file_meta_loc, const TableLocation& directory_meta_loc); diff --git a/src/core/horizon/filesystem/romfs/romfs.cpp b/src/core/horizon/filesystem/romfs/romfs.cpp index 7d451fc83..8572d16e9 100644 --- a/src/core/horizon/filesystem/romfs/romfs.cpp +++ b/src/core/horizon/filesystem/romfs/romfs.cpp @@ -11,7 +11,7 @@ RomFS::RomFS(IFile* file) { auto stream = file->Open(FileOpenFlags::Read); // Header - const auto header = stream->Read
(); + const auto header = stream->read
(); ASSERT(header.header_size == sizeof(Header), Filesystem, "Invalid romFS header size 0x{:x}", header.header_size); diff --git a/src/core/horizon/filesystem/sparse_file.hpp b/src/core/horizon/filesystem/sparse_file.hpp index d2fe1c04e..719629912 100644 --- a/src/core/horizon/filesystem/sparse_file.hpp +++ b/src/core/horizon/filesystem/sparse_file.hpp @@ -4,6 +4,23 @@ namespace hydra::horizon::filesystem { +class OwnedSparseStream : public ztd::io::SparseStream { + public: + // HACK: SparseStream takes a reference to the entries, so its okay to + // initialize entries after calling the base constructor + OwnedSparseStream(std::vector entries_, u64 size) noexcept + : SparseStream(entries, size), entries{std::move(entries_)} {} + ~OwnedSparseStream() noexcept override { + for (auto entry : entries) + delete entry.stream; + } + + ZTD_MAKE_NON_COPYABLE(OwnedSparseStream); + + private: + std::vector entries; +}; + struct SparseFileEntry { u64 offset; IFile* file; @@ -80,17 +97,17 @@ class SparseFile : public IFile { */ } - io::IStream* Open(FileOpenFlags flags) override { - std::vector streams; + ztd::io::IStream* Open(FileOpenFlags flags) override { + std::vector streams; streams.reserve(entries.size()); for (const auto& entry : entries) { streams.push_back( - {.range = - Range(entry.offset, entry.offset + entry.file->GetSize()), + {.range = ztd::Range(entry.offset, + entry.offset + entry.file->GetSize()), .stream = entry.file->Open(flags)}); } - return new io::OwnedSparseStream(std::move(streams), size); + return new OwnedSparseStream(std::move(streams), size); } u64 GetSize() const override { return size; } diff --git a/src/core/horizon/handle_pool.hpp b/src/core/horizon/handle_pool.hpp new file mode 100644 index 000000000..87c0eda62 --- /dev/null +++ b/src/core/horizon/handle_pool.hpp @@ -0,0 +1,84 @@ +#pragma once + +namespace hydra::horizon { + +template +class HandlePool { + public: + using Iterator = Pool::Iterator; + using ConstIterator = Pool::ConstIterator; + + HandlePool() noexcept = default; + ~HandlePool() noexcept = default; + + ZTD_MAKE_DEFAULT_COPYABLE(HandlePool); + ZTD_MAKE_DEFAULT_MOVABLE(HandlePool); + + template + auto Insert(Args... args) noexcept + -> std::expected { + return pool.insert(std::forward(args)...) + .transform( + [](usize index) -> Handle { return Handle::FromIndex(index); }); + } + + [[nodiscard]] auto Free(Handle handle) noexcept -> bool { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handle.ToIndex(), false); + return pool.free(index); + } + + [[nodiscard]] auto IsValid(Handle handle) const noexcept -> bool { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handle.ToIndex(), false); + return pool.isValid(index); + } + + auto Get(Handle handle) noexcept -> std::optional + requires std::is_pointer_v + { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handle.ToIndex(), + std::nullopt); + return pool.get(index); + } + + auto Get(Handle handle) const noexcept -> std::optional + requires std::is_pointer_v + { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handle.ToIndex(), + std::nullopt); + return pool.get(index); + } + + auto Get(Handle handle) noexcept -> std::optional + requires(!std::is_pointer_v) + { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handle.ToIndex(), + std::nullopt); + return pool.get(index); + } + + auto Get(Handle handle) const noexcept -> std::optional + requires(!std::is_pointer_v) + { + ZTD_ASSIGN_OR_RETURN_VALUE(const auto index, handle.ToIndex(), + std::nullopt); + return pool.get(index); + } + + // Iterating + auto begin() noexcept { return pool.begin(); } + auto end() noexcept { return pool.end(); } + + auto begin() const noexcept { return pool.begin(); } + auto end() const noexcept { return pool.end(); } + + auto cbegin() const noexcept { return pool.cbegin(); } + auto cend() const noexcept { return pool.cend(); } + + private: + Pool pool; +}; + +template +using StaticHandlePool = HandlePool>; + +} // namespace hydra::horizon diff --git a/src/core/horizon/kernel/auto_object.hpp b/src/core/horizon/kernel/auto_object.hpp index 9bfc42f82..26cd10bac 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 d5a556d1e..72ae54e35 100644 --- a/src/core/horizon/kernel/const.hpp +++ b/src/core/horizon/kernel/const.hpp @@ -2,17 +2,21 @@ 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 Handle CURRENT_PROCESS_PSEUDO_HANDLE = 0xffff8001; +constexpr Handle CURRENT_THREAD_PSEUDO_HANDLE = 0xffff8000; + +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/hipc/cmif.hpp b/src/core/horizon/kernel/hipc/cmif.hpp index 04e60c19b..58f02f0ff 100644 --- a/src/core/horizon/kernel/hipc/cmif.hpp +++ b/src/core/horizon/kernel/hipc/cmif.hpp @@ -65,8 +65,8 @@ struct OutHeader { u32 token; }; -inline result_t* write_out_header(io::MemoryStream& stream) { - auto hdr = stream.WriteReturningPtr({ +inline result_t* write_out_header(ztd::io::MemoryStream& stream) { + auto hdr = stream.writeReturningPtr({ .magic = OUT_HEADER_MAGIC, .version = 0, .result = RESULT_SUCCESS, @@ -76,8 +76,8 @@ inline result_t* write_out_header(io::MemoryStream& stream) { return &hdr->result; } -inline void write_domain_out_header(io::MemoryStream& stream) { - stream.Write({ +inline void write_domain_out_header(ztd::io::MemoryStream& stream) { + stream.write({ .num_out_objects = 0, }); } diff --git a/src/core/horizon/kernel/hipc/const.hpp b/src/core/horizon/kernel/hipc/const.hpp index 40d27d726..1da82210f 100644 --- a/src/core/horizon/kernel/hipc/const.hpp +++ b/src/core/horizon/kernel/hipc/const.hpp @@ -72,8 +72,8 @@ struct Response { u32 num_move_handles; StaticDescriptor* statics; u32* data_words; - handle_id_t* copy_handles; - handle_id_t* move_handles; + Handle* copy_handles; + Handle* move_handles; }; // From https://github.com/switchbrew/libnx @@ -84,8 +84,8 @@ struct Request { BufferDescriptor* exch_buffers; u32* data_words; RecvListEntry* recv_list; - handle_id_t* copy_handles; - handle_id_t* move_handles; + Handle* copy_handles; + Handle* move_handles; }; // From https://github.com/switchbrew/libnx @@ -106,16 +106,16 @@ struct SpecialHeader { // From https://github.com/switchbrew/libnx inline Request calc_request_layout(Metadata meta, void* base) { // Copy handles - handle_id_t* copy_handles = nullptr; + Handle* copy_handles = nullptr; if (meta.num_copy_handles != 0) { - copy_handles = reinterpret_cast(base); + copy_handles = reinterpret_cast(base); base = copy_handles + meta.num_copy_handles; } // Move handles - handle_id_t* move_handles = nullptr; + Handle* move_handles = nullptr; if (meta.num_move_handles != 0) { - move_handles = reinterpret_cast(base); + move_handles = reinterpret_cast(base); base = move_handles + meta.num_move_handles; } @@ -281,28 +281,28 @@ u8* get_list_entry_ptr(const hw::tegra_x1::cpu::IMmu* mmu, u8* ptr = get_##buffer_or_static##_ptr( \ mmu, hipc_in.data.type##_##buffer_or_static##s[i], size); \ type##_##buffer_or_static##s_streams.push_back( \ - ptr != nullptr \ - ? std::make_optional(std::span(ptr, size)) \ - : std::nullopt); \ + ptr != nullptr ? std::make_optional( \ + std::span(ptr, size)) \ + : std::nullopt); \ } #define CREATE_STATIC_STREAMS(type) CREATE_STREAMS(static, type) #define CREATE_BUFFER_STREAMS(type) CREATE_STREAMS(buffer, type) struct Streams { - io::MemoryStream in_stream; - std::optional in_objects_stream{std::nullopt}; - io::MemoryStream in_copy_handles_stream; - io::MemoryStream in_move_handles_stream; - io::MemoryStream out_stream; - io::MemoryStream out_objects_stream; - io::MemoryStream out_copy_handles_stream; - io::MemoryStream out_move_handles_stream; - std::vector> send_statics_streams; - std::vector> send_buffers_streams; - std::vector> recv_list_streams; - std::vector> recv_buffers_streams; - std::vector> exch_buffers_streams; + ztd::io::MemoryStream in_stream; + std::optional in_objects_stream{std::nullopt}; + ztd::io::MemoryStream in_copy_handles_stream; + ztd::io::MemoryStream in_move_handles_stream; + ztd::io::MemoryStream out_stream; + ztd::io::MemoryStream out_objects_stream; + ztd::io::MemoryStream out_copy_handles_stream; + ztd::io::MemoryStream out_move_handles_stream; + std::vector> send_statics_streams; + std::vector> send_buffers_streams; + std::vector> recv_list_streams; + std::vector> recv_buffers_streams; + std::vector> exch_buffers_streams; Streams(const hw::tegra_x1::cpu::IMmu* mmu, ParsedRequest hipc_in, u8* scratch_buffer, u8* scratch_buffer_objects, @@ -311,10 +311,10 @@ struct Streams { hipc_in.meta.num_data_words * sizeof(u32))), in_copy_handles_stream( std::span(reinterpret_cast(hipc_in.data.copy_handles), - hipc_in.meta.num_copy_handles * sizeof(handle_id_t))), + hipc_in.meta.num_copy_handles * sizeof(Handle))), in_move_handles_stream( std::span(reinterpret_cast(hipc_in.data.move_handles), - hipc_in.meta.num_move_handles * sizeof(handle_id_t))), + hipc_in.meta.num_move_handles * sizeof(Handle))), out_stream(std::span(scratch_buffer, 0x1000)), out_objects_stream(std::span(scratch_buffer_objects, 0x1000)), out_copy_handles_stream( @@ -329,9 +329,9 @@ struct Streams { u8* ptr = get_list_entry_ptr(mmu, hipc_in.data.recv_list[i], size); // TODO: should we continue or push std::nullopt in case of nullptr? recv_list_streams.push_back( - ptr != nullptr - ? std::make_optional(std::span(ptr, size)) - : std::nullopt); + ptr != nullptr ? std::make_optional( + std::span(ptr, size)) + : std::nullopt); } CREATE_BUFFER_STREAMS(recv); CREATE_BUFFER_STREAMS(exch); diff --git a/src/core/horizon/kernel/kernel.cpp b/src/core/horizon/kernel/kernel.cpp index be49782fb..5bc0d8851 100644 --- a/src/core/horizon/kernel/kernel.cpp +++ b/src/core/horizon/kernel/kernel.cpp @@ -66,12 +66,12 @@ void Kernel::SupervisorCall(Process* crnt_process, IThread* crnt_thread, crnt_process, state.r[1], state.r[2], state.r[3], std::bit_cast(static_cast(state.r[4])), std::bit_cast(static_cast(state.r[5])), thread); - state.r[1] = crnt_process->AddHandleNoRetain(thread); + state.r[1] = crnt_process->AddHandleNoRetain(thread).GetRaw(); break; } case 0x9: state.r[0] = StartThread(crnt_process->GetHandle( - static_cast(state.r[0]))); + Handle(static_cast(state.r[0])))); break; case 0xa: ExitThread(crnt_thread); @@ -80,30 +80,26 @@ void Kernel::SupervisorCall(Process* crnt_process, IThread* crnt_thread, SleepThread(std::bit_cast(state.r[0])); break; case 0xc: - state.r[0] = - GetThreadPriority(crnt_process->GetHandle( - static_cast(state.r[1])), - tmp_i32); + state.r[0] = GetThreadPriority( + crnt_process->GetHandle(static_cast(state.r[1])), + tmp_i32); state.r[1] = std::bit_cast(tmp_i32); break; case 0xd: - state.r[0] = - SetThreadPriority(crnt_process->GetHandle( - static_cast(state.r[0])), - std::bit_cast(static_cast(state.r[1]))); + state.r[0] = SetThreadPriority( + crnt_process->GetHandle(static_cast(state.r[0])), + std::bit_cast(static_cast(state.r[1]))); break; case 0xe: - state.r[0] = - GetThreadCoreMask(crnt_process->GetHandle( - static_cast(state.r[0])), - tmp_i32, tmp_u64); + state.r[0] = GetThreadCoreMask( + crnt_process->GetHandle(static_cast(state.r[0])), + tmp_i32, tmp_u64); state.r[1] = std::bit_cast(tmp_i32); state.r[2] = tmp_u64; break; case 0xf: state.r[0] = SetThreadCoreMask( - crnt_process->GetHandle( - static_cast(state.r[0])), + crnt_process->GetHandle(static_cast(state.r[0])), std::bit_cast(static_cast(state.r[1])), state.r[2]); break; case 0x10: @@ -111,51 +107,48 @@ void Kernel::SupervisorCall(Process* crnt_process, IThread* crnt_thread, state.r[0] = tmp_u32; break; case 0x11: - state.r[0] = SignalEvent(crnt_process->GetHandle( - static_cast(state.r[0]))); + state.r[0] = SignalEvent( + crnt_process->GetHandle(static_cast(state.r[0]))); break; case 0x12: - state.r[0] = ClearEvent(crnt_process->GetHandle( - static_cast(state.r[0]))); + state.r[0] = ClearEvent( + crnt_process->GetHandle(static_cast(state.r[0]))); break; case 0x13: - state.r[0] = MapSharedMemory(crnt_process, - crnt_process->GetHandle( - static_cast(state.r[0])), - state.r[1], state.r[2], - static_cast(state.r[3])); + state.r[0] = MapSharedMemory( + crnt_process, + crnt_process->GetHandle(static_cast(state.r[0])), + state.r[1], state.r[2], static_cast(state.r[3])); break; case 0x14: - state.r[0] = - UnmapSharedMemory(crnt_process, - crnt_process->GetHandle( - static_cast(state.r[0])), - state.r[1], state.r[2]); + state.r[0] = UnmapSharedMemory( + crnt_process, + crnt_process->GetHandle(static_cast(state.r[0])), + state.r[1], state.r[2]); break; case 0x15: { TransferMemory* tmem = nullptr; state.r[0] = CreateTransferMemory( state.r[1], state.r[2], static_cast(state.r[3]), tmem); - state.r[1] = crnt_process->AddHandleNoRetain(tmem); + state.r[1] = crnt_process->AddHandleNoRetain(tmem).GetRaw(); break; } case 0x16: - state.r[0] = - CloseHandle(crnt_process, static_cast(state.r[0])); + state.r[0] = CloseHandle(crnt_process, static_cast(state.r[0])); break; case 0x17: state.r[0] = ResetSignal(crnt_process->GetHandle( - static_cast(state.r[0]))); + static_cast(state.r[0]))); break; case 0x18: { - const auto handle_ids = reinterpret_cast( + const auto handles = reinterpret_cast( crnt_process->GetMmu()->UnmapAddr(state.r[1])); const auto num_handles = std::bit_cast(state.r[2]); SynchronizationObject* sync_objs[num_handles]; for (auto i = 0; i < num_handles; i++) sync_objs[i] = - crnt_process->GetHandle(handle_ids[i]); + crnt_process->GetHandle(handles[i]); state.r[0] = WaitSynchronization( crnt_thread, std::span(sync_objs, static_cast(num_handles)), @@ -164,17 +157,15 @@ void Kernel::SupervisorCall(Process* crnt_process, IThread* crnt_thread, break; } case 0x19: - state.r[0] = CancelSynchronization(crnt_process->GetHandle( - static_cast(state.r[0]))); + state.r[0] = CancelSynchronization( + crnt_process->GetHandle(static_cast(state.r[0]))); break; case 0x1a: - state.r[0] = - ArbitrateLock(crnt_thread, - crnt_process->GetHandle( - static_cast(state.r[0])), - crnt_process->GetMmu()->UnmapAddr(state.r[1]), - static_cast(state.r[2]), - static_cast(state.r[0])); + state.r[0] = ArbitrateLock( + crnt_thread, + crnt_process->GetHandle(static_cast(state.r[0])), + crnt_process->GetMmu()->UnmapAddr(state.r[1]), + static_cast(state.r[2]), static_cast(state.r[0])); break; case 0x1b: state.r[0] = ArbitrateUnlock( @@ -185,8 +176,7 @@ void Kernel::SupervisorCall(Process* crnt_process, IThread* crnt_thread, crnt_process, crnt_thread, crnt_process->GetMmu()->UnmapAddr(state.r[0]), crnt_process->GetMmu()->UnmapAddr(state.r[1]), - static_cast(state.r[2]), - std::bit_cast(state.r[3])); + static_cast(state.r[2]), std::bit_cast(state.r[3])); break; case 0x1d: state.r[0] = SignalProcessWideKey( @@ -203,19 +193,19 @@ void Kernel::SupervisorCall(Process* crnt_process, IThread* crnt_thread, reinterpret_cast( crnt_process->GetMmu()->UnmapAddr(state.r[1])), client_session); - state.r[1] = crnt_process->AddHandleNoRetain(client_session); + state.r[1] = crnt_process->AddHandleNoRetain(client_session).GetRaw(); break; } case 0x21: state.r[0] = SendSyncRequest(crnt_process, crnt_thread, crnt_process->GetHandle( - static_cast(state.r[0]))); + static_cast(state.r[0]))); break; case 0x25: - state.r[0] = GetThreadId(crnt_process->GetHandle( - static_cast(state.r[1])), - tmp_u64); + state.r[0] = GetThreadId( + crnt_process->GetHandle(static_cast(state.r[1])), + tmp_u64); state.r[1] = tmp_u64; break; case 0x26: { @@ -233,25 +223,23 @@ void Kernel::SupervisorCall(Process* crnt_process, IThread* crnt_thread, state.r[1]); break; case 0x29: - state.r[0] = GetInfo(crnt_process, static_cast(state.r[1]), - crnt_process->GetHandle( - static_cast(state.r[2])), - state.r[3], tmp_u64); + state.r[0] = GetInfo( + crnt_process, static_cast(state.r[1]), + crnt_process->GetHandle(static_cast(state.r[2])), + state.r[3], tmp_u64); state.r[1] = tmp_u64; break; case 0x2c: state.r[0] = MapPhysicalMemory(crnt_process, state.r[0], state.r[1]); break; case 0x32: - state.r[0] = - SetThreadActivity(crnt_process->GetHandle( - static_cast(state.r[0])), - static_cast(state.r[1])); + state.r[0] = SetThreadActivity( + crnt_process->GetHandle(static_cast(state.r[0])), + static_cast(state.r[1])); break; case 0x33: state.r[0] = GetThreadContext3( - crnt_process->GetHandle( - static_cast(state.r[1])), + crnt_process->GetHandle(static_cast(state.r[1])), *reinterpret_cast( crnt_process->GetMmu()->UnmapAddr(state.r[0]))); break; @@ -275,31 +263,31 @@ void Kernel::SupervisorCall(Process* crnt_process, IThread* crnt_thread, hipc::ClientSession* client_session = nullptr; state.r[0] = CreateSession(state.r[2] != 0, state.r[3], server_session, client_session); - state.r[1] = crnt_process->AddHandleNoRetain(server_session); - state.r[2] = crnt_process->AddHandleNoRetain(client_session); + state.r[1] = crnt_process->AddHandleNoRetain(server_session).GetRaw(); + state.r[2] = crnt_process->AddHandleNoRetain(client_session).GetRaw(); break; } case 0x41: { hipc::ServerSession* server_session = nullptr; state.r[0] = AcceptSession(crnt_process->GetHandle( - static_cast(state.r[1])), + static_cast(state.r[1])), server_session); - state.r[1] = crnt_process->AddHandleNoRetain(server_session); + state.r[1] = crnt_process->AddHandleNoRetain(server_session).GetRaw(); break; } case 0x43: { - const auto handle_ids = reinterpret_cast( + const auto handles = reinterpret_cast( crnt_process->GetMmu()->UnmapAddr(state.r[1])); const auto num_handles = std::bit_cast(state.r[2]); SynchronizationObject* sync_objs[num_handles]; for (auto i = 0; i < num_handles; i++) sync_objs[i] = - crnt_process->GetHandle(handle_ids[i]); + crnt_process->GetHandle(handles[i]); state.r[0] = ReplyAndReceive( crnt_thread, std::span(sync_objs, static_cast(num_handles)), crnt_process->GetHandle( - static_cast(state.r[3])), + static_cast(state.r[3])), std::bit_cast(state.r[4]), tmp_u32); state.r[1] = tmp_u32; break; @@ -307,15 +295,14 @@ void Kernel::SupervisorCall(Process* crnt_process, IThread* crnt_thread, case 0x4b: { CodeMemory* code_mem = nullptr; state.r[0] = CreateCodeMemory(state.r[1], state.r[2], code_mem); - state.r[1] = crnt_process->AddHandleNoRetain(code_mem); + state.r[1] = crnt_process->AddHandleNoRetain(code_mem).GetRaw(); break; } case 0x4c: - state.r[0] = - ControlCodeMemory(crnt_process->GetHandle( - static_cast(state.r[0])), - CodeMemoryOperation(state.r[1]), state.r[2], - state.r[3], MemoryPermission(state.r[4])); + state.r[0] = ControlCodeMemory( + crnt_process->GetHandle(static_cast(state.r[0])), + CodeMemoryOperation(state.r[1]), state.r[2], state.r[3], + MemoryPermission(state.r[4])); break; case 0x65: state.r[0] = @@ -326,30 +313,27 @@ void Kernel::SupervisorCall(Process* crnt_process, IThread* crnt_thread, break; case 0x73: state.r[0] = SetProcessMemoryPermission( - crnt_process->GetHandle( - static_cast(state.r[0])), + crnt_process->GetHandle(static_cast(state.r[0])), state.r[1], state.r[2], MemoryPermission(state.r[3])); break; case 0x74: - state.r[0] = MapProcessMemory(crnt_process, state.r[0], - crnt_process->GetHandle( - static_cast(state.r[1])), - state.r[2], state.r[3]); + state.r[0] = MapProcessMemory( + crnt_process, state.r[0], + crnt_process->GetHandle(static_cast(state.r[1])), + state.r[2], state.r[3]); break; case 0x77: - state.r[0] = - MapProcessCodeMemory(crnt_process->GetHandle( - static_cast(state.r[0])), - state.r[1], state.r[2], state.r[3]); + state.r[0] = MapProcessCodeMemory( + crnt_process->GetHandle(static_cast(state.r[0])), + state.r[1], state.r[2], state.r[3]); break; case 0x78: - state.r[0] = - UnmapProcessCodeMemory(crnt_process->GetHandle( - static_cast(state.r[0])), - state.r[1], state.r[2], state.r[3]); + state.r[0] = UnmapProcessCodeMemory( + crnt_process->GetHandle(static_cast(state.r[0])), + state.r[1], state.r[2], state.r[3]); break; default: - LOG_NOT_IMPLEMENTED(Kernel, "SVC 0x{:x}", id); + LOG_NOT_IMPLEMENTED(Kernel, "SVC {:#x}", id); state.r[0] = MAKE_RESULT(Svc, Error::NotImplemented); break; } @@ -363,7 +347,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 +376,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 +389,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 +405,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 +562,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 +576,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; } @@ -608,17 +593,14 @@ result_t Kernel::CreateTransferMemory(uptr addr, u64 size, return RESULT_SUCCESS; } -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)"); +result_t Kernel::CloseHandle(Process* crnt_process, Handle handle) { + LOG_DEBUG(Kernel, "CloseHandle called (handle: {})", handle); + + if (crnt_process->FreeHandle(handle)) { + 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? @@ -711,11 +693,11 @@ result_t Kernel::CancelSynchronization(IThread* thread) { } result_t Kernel::ArbitrateLock(IThread* crnt_thread, IThread* owner_thread, - uptr mutex_addr, handle_id_t self_handle, - handle_id_t owner_handle) { + uptr mutex_addr, Handle self_handle, + Handle owner_handle) { LOG_DEBUG(Kernel, - "ArbitrateLock called (owner: {}, mutex: 0x{:08x}, self: " - "0x{:x})", + "ArbitrateLock called (owner: {}, mutex: {:#x}, self: " + "{})", owner_thread->GetDebugName(), mutex_addr, self_handle); crnt_thread->self_handle_for_mutex = self_handle; @@ -725,7 +707,7 @@ result_t Kernel::ArbitrateLock(IThread* crnt_thread, IThread* owner_thread, CriticalSectionLock cs_lock(*this); if (atomic_load(reinterpret_cast(mutex_addr)) != - (owner_thread->self_handle_for_mutex | MUTEX_WAIT_MASK)) + (owner_thread->self_handle_for_mutex.GetRaw() | MUTEX_WAIT_MASK)) return RESULT_SUCCESS; crnt_thread->mutex_wait_addr = mutex_addr; @@ -762,14 +744,12 @@ result_t Kernel::ArbitrateUnlock(IThread* crnt_thread, uptr mutex_addr) { result_t Kernel::WaitProcessWideKeyAtomic(Process* crnt_process, IThread* crnt_thread, uptr mutex_addr, - uptr var_addr, - handle_id_t self_handle, + uptr var_addr, Handle self_handle, i64 timeout) { - LOG_DEBUG( - Kernel, - "WaitProcessWideKeyAtomic called (mutex: 0x{:08x}, var: 0x{:08x}, " - "self: 0x{:x}, timeout: {})", - mutex_addr, var_addr, self_handle, timeout); + LOG_DEBUG(Kernel, + "WaitProcessWideKeyAtomic called (mutex: {:#x}, var: {:#x}, " + "self: {}, timeout: {})", + mutex_addr, var_addr, self_handle, timeout); crnt_thread->self_handle_for_mutex = self_handle; crnt_thread->mutex_wait_addr = mutex_addr; @@ -779,7 +759,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 +782,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 +802,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 +949,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 +986,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 +1051,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 +1121,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 +1146,7 @@ result_t Kernel::WaitForAddress(IThread* crnt_thread, uptr addr, /* { CriticalSectionLock cs_lock(*this); - arbiters.Remove(crnt_thread); + arbiters.remove(crnt_thread); } */ @@ -1187,15 +1170,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 +1328,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 +1341,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 +1357,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; } @@ -1385,7 +1370,7 @@ void Kernel::TryAcquireMutex(Process* crnt_process, IThread* thread) { do { if (value == 0) { // Register this thread as the owner - new_value = thread->self_handle_for_mutex; + new_value = thread->self_handle_for_mutex.GetRaw(); } else { // Register this thread as a waiter new_value = value | MUTEX_WAIT_MASK; @@ -1400,7 +1385,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); } @@ -1414,7 +1399,7 @@ void Kernel::UnlockMutex(IThread* thread, uptr mutex_addr) { return; } - u32 value = new_owner->self_handle_for_mutex; + u32 value = new_owner->self_handle_for_mutex.GetRaw(); if (waiter_count > 0) value |= MUTEX_WAIT_MASK; diff --git a/src/core/horizon/kernel/kernel.hpp b/src/core/horizon/kernel/kernel.hpp index 948ac1e2f..fb6ee1d7e 100644 --- a/src/core/horizon/kernel/kernel.hpp +++ b/src/core/horizon/kernel/kernel.hpp @@ -88,19 +88,19 @@ class Kernel { uptr addr, u64 size); result_t CreateTransferMemory(uptr addr, u64 size, MemoryPermission perm, TransferMemory*& out_tmem); - result_t CloseHandle(Process* crnt_process, handle_id_t handle_id); + result_t CloseHandle(Process* crnt_process, Handle handle); result_t ResetSignal(SynchronizationObject* sync_object); result_t WaitSynchronization(IThread* crnt_thread, std::span sync_objs, i64 timeout, u32& out_signalled_index); result_t CancelSynchronization(IThread* thread); result_t ArbitrateLock(IThread* crnt_thread, IThread* owner_thread, - uptr mutex_addr, handle_id_t self_handle, - handle_id_t owner_handle); + uptr mutex_addr, Handle self_handle, + Handle owner_handle); result_t ArbitrateUnlock(IThread* crnt_thread, uptr mutex_addr); result_t WaitProcessWideKeyAtomic(Process* crnt_process, IThread* crnt_thread, uptr mutex_addr, - uptr var_addr, handle_id_t self_handle, + uptr var_addr, Handle self_handle, i64 timeout); result_t SignalProcessWideKey(Process* crnt_process, uptr addr, i32 count); void GetSystemTick(u64& out_tick); @@ -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 dd71705f4..147a68e85 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; } @@ -91,10 +92,10 @@ hw::tegra_x1::cpu::IMemory* Process::CreateTlsMemory(vaddr_t& base) { void Process::CreateStackMemory(u64 stack_size) { // main_thread = new GuestThread(this, STACK_REGION.begin + stack_size - - // 0x10, priority); auto handle_id = AddHandle(main_thread); + // 0x10, priority); auto handle = 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 11f8d2c3a..cbc8a097b 100644 --- a/src/core/horizon/kernel/process.hpp +++ b/src/core/horizon/kernel/process.hpp @@ -1,5 +1,6 @@ #pragma once +#include "core/horizon/handle_pool.hpp" #include "core/horizon/kernel/applet_state.hpp" #include "core/horizon/kernel/synchronization_object.hpp" #include "core/horizon/kernel/thread.hpp" @@ -28,9 +29,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 +42,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); @@ -50,7 +51,7 @@ class Process : public SynchronizationObject { void ResizeHeap(u64 size); // Thread - handle_id_t SetMainThread(GuestThread* thread) { + Handle SetMainThread(GuestThread* thread) { main_thread = thread; return AddHandle(main_thread); } @@ -85,50 +86,66 @@ class Process : public SynchronizationObject { // Handles template - T* GetHandle(handle_id_t handle_id) { + // TODO: uncomment + /*std::optional*/ T* GetHandle(Handle handle) { static_assert(std::is_base_of_v, "T must be derived from AutoObject"); - if (handle_id == INVALID_HANDLE_ID) - return nullptr; + if (!handle.IsValid()) + return nullptr; // TODO: std::nullopt - 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; + if constexpr (std::is_base_of_v) { + if (handle == CURRENT_PROCESS_PSEUDO_HANDLE) [[unlikely]] { + return this; + } + } - obj = handle_pool.Get(handle_id); + if constexpr (std::is_base_of_v) { + if (handle == CURRENT_THREAD_PSEUDO_HANDLE) [[unlikely]] { + return tls_current_thread; + } } - return static_cast(obj); + // HACK + return handle_pool.Get(handle) + .transform( + [](AutoObject* obj) -> auto { return static_cast(obj); }) + .value_or(nullptr); } - handle_id_t AddHandleNoRetain(AutoObject* obj) { + Handle AddHandleNoRetain(AutoObject* obj) { + // TODO: remove if (obj == nullptr) [[unlikely]] - return INVALID_HANDLE_ID; + return INVALID_HANDLE; - return handle_pool.Insert(obj); + return handle_pool.Insert(obj).value(); } - handle_id_t AddHandle(AutoObject* obj) { + Handle AddHandle(AutoObject* obj) { + // TODO: remove if (obj == nullptr) [[unlikely]] - return INVALID_HANDLE_ID; + return INVALID_HANDLE; obj->Retain(); - return handle_pool.Insert(obj); + return handle_pool.Insert(obj).value(); } - void FreeHandle(handle_id_t handle_id) { - ASSERT_DEBUG(handle_id != CURRENT_PROCESS_PSEUDO_HANDLE, Kernel, + bool FreeHandle(Handle handle) { + ASSERT_DEBUG(handle != CURRENT_PROCESS_PSEUDO_HANDLE, Kernel, "Cannot free current process handle"); - ASSERT_DEBUG(handle_id != CURRENT_THREAD_PSEUDO_HANDLE, Kernel, + ASSERT_DEBUG(handle != 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); + if (!object.has_value()) { + LOG_WARN(Kernel, "Invalid handle {}", handle); + return false; + } + + object.value()->Release(); + ASSERT_DEBUG(handle_pool.Free(handle), Kernel, + "Failed to free handle {}", handle); + return true; } hw::tegra_x1::cpu::IMmu* GetMmu() const { return mmu.get(); } @@ -153,7 +170,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 +178,8 @@ class Process : public SynchronizationObject { std::vector threads; // Handles - StaticPool + // TODO: store as strong refs + StaticHandlePool 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 40eadb7fc..a712921bd 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 69a27b91e..f1b191e87 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 283682dc1..833cd04ee 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 2e1c35a41..6c54c41ca 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 00a5907f6..db17018ce 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 5d192c98d..50c50c222 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 706355cc9..92976ca95 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; } @@ -133,10 +133,10 @@ class IThread : public SynchronizationObject { // Mutex and cond var uptr mutex_wait_addr{0x0}; - u32 self_handle_for_mutex{0x0}; + Handle self_handle_for_mutex{INVALID_HANDLE}; 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 fe6d66fda..58a63cbb0 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_} {} @@ -157,8 +157,9 @@ class HomebrewThread : public kernel::GuestThread { auto entry = reinterpret_cast(executable_ptr + config_offset); - ADD_ENTRY_OPTIONAL(MainThreadHandle, self_handle, 0); - ADD_ENTRY_OPTIONAL(ProcessHandle, self_process_handle, 0); + ADD_ENTRY_OPTIONAL(MainThreadHandle, self_handle.GetRaw(), 0); + ADD_ENTRY_OPTIONAL(ProcessHandle, self_process_handle.GetRaw(), + 0); ADD_ENTRY_OPTIONAL( AppletType, static_cast(kernel::AppletType::Application), 0); @@ -176,11 +177,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)); @@ -222,7 +223,7 @@ class HomebrewThread : public kernel::GuestThread { System& system; std::string path; - handle_id_t self_handle{INVALID_HANDLE_ID}; + Handle self_handle{INVALID_HANDLE}; public: SETTER(self_handle, SetSelfHandle); @@ -242,7 +243,7 @@ void HomebrewLoader::LoadProcess(System& system, kernel::Process* process) { auto stream = nacp_file->Open(filesystem::FileOpenFlags::Read); // Create a virtual filename - const auto nacp = stream->Read(); + const auto nacp = stream->read(); std::string title_name = nacp.GetApplicationTitle(SystemLanguage::AmericanEnglish).name; std::ranges::replace(title_name, ' ', '_'); @@ -262,8 +263,8 @@ void HomebrewLoader::LoadProcess(System& system, kernel::Process* process) { // Main thread auto main_thread = new HomebrewThread(system, process, mapped_path); - const auto main_thread_handle_id = process->SetMainThread(main_thread); - main_thread->SetSelfHandle(main_thread_handle_id); + const auto main_thread_handle = process->SetMainThread(main_thread); + main_thread->SetSelfHandle(main_thread_handle); } namespace { @@ -291,7 +292,7 @@ void HomebrewLoader::TryLoadAssetSection(filesystem::IFile* asset_file) { auto stream = asset_file->Open(filesystem::FileOpenFlags::Read); // Header - const auto header = stream->Read(); + const auto header = stream->read(); // TODO: is this the correct way to check if the asset section is present? if (header.magic != make_magic4('A', 'S', 'E', 'T')) { LOG_WARN(Loader, "Asset section not found"); diff --git a/src/core/horizon/loader/loader.cpp b/src/core/horizon/loader/loader.cpp index 7c5fe9497..845ad15ab 100644 --- a/src/core/horizon/loader/loader.cpp +++ b/src/core/horizon/loader/loader.cpp @@ -19,8 +19,8 @@ namespace { uchar4* LoadImage(filesystem::IFile* file, u32& out_width, u32& out_height) { auto stream = file->Open(filesystem::FileOpenFlags::Read); - std::vector raw_data(stream->GetSize()); - stream->ReadToSpan(std::span(raw_data)); + std::vector raw_data(stream->getSize()); + stream->readToSpan(std::span(raw_data)); delete stream; @@ -45,8 +45,8 @@ uchar4* LoadGIF(filesystem::IFile* file, u32& out_width, u32& out_height, u32& out_frame_count) { auto stream = file->Open(filesystem::FileOpenFlags::Read); - std::vector raw_data(stream->GetSize()); - stream->ReadToSpan(std::span(raw_data)); + std::vector raw_data(stream->getSize()); + stream->readToSpan(std::span(raw_data)); delete stream; @@ -131,11 +131,11 @@ horizon::services::ns::ApplicationControlProperty* ILoader::LoadNacp() { auto stream = nacp_file->Open(filesystem::FileOpenFlags::Read); - ASSERT(stream->GetSize() == + ASSERT(stream->getSize() == sizeof(horizon::services::ns::ApplicationControlProperty), - Loader, "Invalid NACP file size 0x{:x}", stream->GetSize()); + Loader, "Invalid NACP file size 0x{:x}", stream->getSize()); auto nacp = new horizon::services::ns::ApplicationControlProperty(); - stream->ReadToRef(*nacp); + stream->readToRef(*nacp); delete stream; diff --git a/src/core/horizon/loader/loader.hpp b/src/core/horizon/loader/loader.hpp index 3f15b3e32..421986a96 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/nca_loader.cpp b/src/core/horizon/loader/nca_loader.cpp index bfac201ab..52e6029cb 100644 --- a/src/core/horizon/loader/nca_loader.cpp +++ b/src/core/horizon/loader/nca_loader.cpp @@ -38,7 +38,7 @@ NcaLoader::NcaLoader(filesystem::ContentArchive content_archive_) auto stream = file->Open(filesystem::FileOpenFlags::Read); - const auto meta = stream->Read(); + const auto meta = stream->read(); delete stream; diff --git a/src/core/horizon/loader/npdm.hpp b/src/core/horizon/loader/npdm.hpp index c5fb4e156..7b746a0a1 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 ec1c16ce2..cb875d28e 100644 --- a/src/core/horizon/loader/nro_loader.cpp +++ b/src/core/horizon/loader/nro_loader.cpp @@ -47,7 +47,7 @@ NroLoader::NroLoader(filesystem::IFile* file_, const bool is_entry_point_) auto stream = file->Open(filesystem::FileOpenFlags::Read); // Header - const auto header = stream->Read(); + const auto header = stream->read(); // Validate ASSERT(header.magic == make_magic4('N', 'R', 'O', '0'), Loader, @@ -69,15 +69,17 @@ void NroLoader::LoadProcess(System& system, kernel::Process* process) { // Create executable memory // 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)}; + .size = GetExecutableSize() + 0x1000, // HACK: one extra page + .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); - stream->SeekTo(0); - stream->ReadToSpan(std::span(reinterpret_cast(executable_ptr), size)); + stream->seekTo(0); + stream->readToSpan(std::span(reinterpret_cast(executable_ptr), size)); // Debug symbols // TODO diff --git a/src/core/horizon/loader/nso_loader.cpp b/src/core/horizon/loader/nso_loader.cpp index 7e73c0002..054ca99f5 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; @@ -49,24 +48,24 @@ struct NsoHeader { u32 data_hash[0x8]; }; -void read_segment(io::IStream* stream, uptr executable_mem_ptr, +void read_segment(ztd::io::IStream* stream, uptr executable_mem_ptr, const Segment& segment, const u64 segment_file_size, bool is_compressed) { // Skip - stream->SeekTo(segment.file_offset); + stream->seekTo(segment.file_offset); u64 file_size = (is_compressed ? segment_file_size : segment.size); if (is_compressed) { // 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)); + stream->readToSpan(std::span(file)); + ztd::compress::decompressLz4( + file, std::span(reinterpret_cast(executable_mem_ptr + + segment.memory_offset), + segment.size)); } else { - stream->ReadToSpan(std::span( + stream->readToSpan(std::span( reinterpret_cast(executable_mem_ptr + segment.memory_offset), file_size)); } @@ -90,7 +89,7 @@ NsoLoader::NsoLoader(filesystem::IFile* file_, const std::string_view name_, auto stream = file->Open(filesystem::FileOpenFlags::Read); // Header - const auto header = stream->Read(); + const auto header = stream->read(); ASSERT(header.magic == make_magic4('N', 'S', 'O', '0'), Loader, "Invalid NSO magic"); @@ -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,13 +224,13 @@ 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); + const auto main_thread_handle = process->SetMainThread(main_thread); main_thread->SetEntryPoint(base + text_offset); main_thread->SetArg(0, 0x0); - main_thread->SetArg(1, main_thread_handle_id); + main_thread->SetArg(1, main_thread_handle.GetRaw()); } } diff --git a/src/core/horizon/loader/nx_loader.cpp b/src/core/horizon/loader/nx_loader.cpp index 6ed25eebf..2e4988d2b 100644 --- a/src/core/horizon/loader/nx_loader.cpp +++ b/src/core/horizon/loader/nx_loader.cpp @@ -89,8 +89,8 @@ void NxLoader::ParseInfo() { auto stream = file->Open(filesystem::FileOpenFlags::Read); std::string content; - content.resize(stream->GetSize()); - stream->ReadToSpan(std::span(content)); + content.resize(stream->getSize()); + stream->readToSpan(std::span(content)); const auto info = toml::parse_str(content); title_id = toml::find(info, "title_id"); @@ -107,7 +107,7 @@ void NxLoader::ParseNpdm() { auto stream = file->Open(filesystem::FileOpenFlags::Read); - const auto meta = stream->Read(); + const auto meta = stream->read(); delete stream; diff --git a/src/core/horizon/loader/plugins/plugin.cpp b/src/core/horizon/loader/plugins/plugin.cpp index b6917d192..3a7bdb762 100644 --- a/src/core/horizon/loader/plugins/plugin.cpp +++ b/src/core/horizon/loader/plugins/plugin.cpp @@ -6,19 +6,27 @@ namespace hydra::horizon::loader::plugins { namespace { -class StreamAdapter : public io::IStream { +class StreamAdapter : public ztd::io::IStream { public: - StreamAdapter(Plugin& extension_, void* handle_) + StreamAdapter(Plugin& extension_, void* handle_) noexcept : plugin{extension_}, handle{handle_} {} - ~StreamAdapter() override { plugin.StreamDestroy(handle); } + ~StreamAdapter() noexcept override { plugin.StreamDestroy(handle); } - u64 GetSeek() const override { return plugin.StreamGetSeek(handle); } - void SeekTo(u64 seek) override { plugin.StreamSeekTo(handle, seek); } - void SeekBy(u64 offset) override { plugin.StreamSeekBy(handle, offset); } + u64 getSeek() const noexcept override { + return plugin.StreamGetSeek(handle); + } + void seekTo(u64 seek) noexcept override { + plugin.StreamSeekTo(handle, seek); + } + void seekBy(u64 offset) noexcept override { + plugin.StreamSeekBy(handle, offset); + } - u64 GetSize() const override { return plugin.StreamGetSize(handle); } + u64 getSize() const noexcept override { + return plugin.StreamGetSize(handle); + } - void ReadRaw(std::span buffer) override { + void readRaw(std::span buffer) noexcept override { plugin.StreamReadRaw(handle, buffer); } @@ -33,7 +41,7 @@ class FileAdapter : public filesystem::IFile { : plugin{extension_}, handle{handle_} {} ~FileAdapter() override { plugin.FileDestroy(handle); } - io::IStream* Open(filesystem::FileOpenFlags flags) override { + ztd::io::IStream* Open(filesystem::FileOpenFlags flags) override { (void)flags; return new StreamAdapter(plugin, plugin.FileOpen(handle)); } @@ -176,8 +184,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 b2502bbd9..de6525fdc 100644 --- a/src/core/horizon/loader/plugins/plugin.hpp +++ b/src/core/horizon/loader/plugins/plugin.hpp @@ -50,22 +50,23 @@ class Plugin { Plugin() = default; ~Plugin(); - 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, - other.destroy_context, create_loader_from_file, - other.create_loader_from_file, loader_destroy, - other.loader_destroy, file_destroy, other.file_destroy, - file_open, other.file_open, file_get_size, other.file_get_size, - stream_destroy, other.stream_destroy, stream_get_seek, - other.stream_get_seek, stream_seek_to, other.stream_seek_to, - stream_seek_by, other.stream_seek_by, stream_get_size, - other.stream_get_size, stream_read_raw, other.stream_read_raw, - name, other.name, display_version, other.display_version, - supported_formats, std::move(other.supported_formats), - option_configs, std::move(other.option_configs), context, - std::exchange(other.context, nullptr)); + ZTD_MAKE_NON_COPYABLE(Plugin); + ZTD_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, + other.destroy_context, create_loader_from_file, + other.create_loader_from_file, loader_destroy, + other.loader_destroy, file_destroy, other.file_destroy, + file_open, other.file_open, file_get_size, + other.file_get_size, stream_destroy, other.stream_destroy, + stream_get_seek, other.stream_get_seek, stream_seek_to, + other.stream_seek_to, stream_seek_by, other.stream_seek_by, + stream_get_size, other.stream_get_size, stream_read_raw, + other.stream_read_raw, name, other.name, display_version, + other.display_version, supported_formats, + std::move(other.supported_formats), option_configs, + std::move(other.option_configs), context, + std::exchange(other.context, nullptr)); std::optional Load(std::string_view path); diff --git a/src/core/horizon/os.cpp b/src/core/horizon/os.cpp index 04c58a44a..9b3be18a1 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/account/account_service.cpp b/src/core/horizon/services/account/account_service.cpp index abe0b67ea..962d9f9c4 100644 --- a/src/core/horizon/services/account/account_service.cpp +++ b/src/core/horizon/services/account/account_service.cpp @@ -23,16 +23,16 @@ result_t IAccountService::ListAllUsers(System* system, OutBuffer out_buffer) { // Clear buffer - std::memset(out_buffer.stream->GetPtr(), 0, out_buffer.stream->GetSize()); + std::memset(out_buffer.stream->getPtr(), 0, out_buffer.stream->getSize()); // Write user IDs for (const auto user_id : system->GetOS().GetUserManager().GetUserIDs()) { // Check if we cen fit the entry in the buffer - if (out_buffer.stream->GetSeek() + sizeof(uuid_t) > - out_buffer.stream->GetSize()) + if (out_buffer.stream->getSeek() + sizeof(uuid_t) > + out_buffer.stream->getSize()) continue; - out_buffer.stream->Write(user_id); + out_buffer.stream->write(user_id); } return RESULT_SUCCESS; @@ -46,16 +46,16 @@ IAccountService::ListOpenUsers(System* system, LOG_FUNC_STUBBED(Services); // Clear buffer - std::memset(out_buffer.stream->GetPtr(), 0, out_buffer.stream->GetSize()); + std::memset(out_buffer.stream->getPtr(), 0, out_buffer.stream->getSize()); // Write user IDs for (const auto user_id : system->GetOS().GetUserManager().GetUserIDs()) { // Check if we cen fit the entry in the buffer - if (out_buffer.stream->GetSeek() + sizeof(uuid_t) > - out_buffer.stream->GetSize()) + if (out_buffer.stream->getSeek() + sizeof(uuid_t) > + out_buffer.stream->getSize()) continue; - out_buffer.stream->Write(user_id); + out_buffer.stream->write(user_id); } // memset((void*)out_buffer.writer->GetBase(), 0, // out_buffer.writer->GetSize()); diff --git a/src/core/horizon/services/account/internal/user_manager.cpp b/src/core/horizon/services/account/internal/user_manager.cpp index d4ec16f38..fdf6de64f 100644 --- a/src/core/horizon/services/account/internal/user_manager.cpp +++ b/src/core/horizon/services/account/internal/user_manager.cpp @@ -38,12 +38,12 @@ void jpg_to_memory(void* context, void* data, int len) { UserManager::UserManager() { // Create user directory - std::filesystem::create_directories(GetUserPath()); + std::filesystem::create_directories(GetUsersPath()); // Deserialize all users - if (std::filesystem::exists(GetUserPath())) { + if (std::filesystem::exists(GetUsersPath())) { for (const auto& dir_entry : - std::filesystem::directory_iterator{GetUserPath()}) { + std::filesystem::directory_iterator{GetUsersPath()}) { auto filename = dir_entry.path().filename(); auto extension = filename.extension().string(); @@ -52,7 +52,7 @@ UserManager::UserManager() { auto user_id_str = filename.stem().string(); if (user_id_str.size() != 32) { - LOG_WARN(Horizon, "Invalid user ID {}", user_id_str); + LOG_WARN(Services, "Invalid user ID {}", user_id_str); return; } @@ -194,7 +194,7 @@ void UserManager::LoadAvatarImageAsJpeg(std::string_view path, uchar3 bg_color, } void UserManager::Serialize(uuid_t user_id) { - LOG_INFO(Horizon, "Serializing user with ID {:032x}", user_id); + LOG_INFO(Services, "Serializing user with ID {:032x}", user_id); auto& user_pair = GetPair(user_id); const auto& user = user_pair.first; @@ -202,75 +202,82 @@ void UserManager::Serialize(uuid_t user_id) { return; // Serialize - // TODO: std::ofstream - std::fstream ofs(fmt::format("{}/{:032x}.husr", GetUserPath(), user_id)); - { - io::IostreamStream stream(ofs); - - // Header - HusrHeader header{}; - stream.Write(header); - - // Data - stream.Write(user.base); - stream.Write(user.data); - stream.Write(user.avatar_bg_color); - stream.Write(static_cast(user.avatar_path.size())); - stream.WriteSpan(std::span(user.avatar_path)); - } - ofs.close(); + const auto path = GetUserPath(user_id); + ZTD_ASSIGN_OR( + auto file, + ztd::fs::openFileAbsolute(path, ztd::fs::File::OpenFlags::Write), { + LOG_ERROR(Services, "Failed to write user at path {}", path); + return; + }); + ztd::io::FileStream stream(file); + + // Header + HusrHeader header{}; + stream.write(header); + + // Data + stream.write(user.base); + stream.write(user.data); + stream.write(user.avatar_bg_color); + stream.write(static_cast(user.avatar_path.size())); + stream.writeSpan(std::span(user.avatar_path)); user_pair.second = GetTimestamp(); } void UserManager::Deserialize(uuid_t user_id) { - LOG_INFO(Horizon, "Deserializing user with ID {:032x}", user_id); + LOG_INFO(Services, "Deserializing user with ID {:032x}", user_id); auto it = users.find(user_id); if (it != users.end()) { auto& user_pair = it->second; if (!user_pair.first.EditedSince(user_pair.second)) - LOG_WARN(Horizon, "Overwriting user {:032x}", user_id); + LOG_WARN(Services, "Overwriting user {:032x}", user_id); } // Deserialize - // TODO: std::ifstream - std::fstream ifs{fmt::format("{}/{:032x}.husr", GetUserPath(), user_id)}; - io::IostreamStream stream(ifs); + const auto path = GetUserPath(user_id); + ZTD_ASSIGN_OR( + auto file, + ztd::fs::openFileAbsolute(path, ztd::fs::File::OpenFlags::Read), { + LOG_ERROR(Services, "Failed to read user at path {}", path); + return; + }); + ztd::io::FileStream stream(file); // Header - const auto header = stream.Read(); + const auto header = stream.read(); // Validate - ASSERT(header.magic == HUSR_MAGIC, Horizon, + ASSERT(header.magic == HUSR_MAGIC, Services, "Invalid HUSR magic 0x{:08x} for user {:032x}", header.magic, user_id); if (header.version < 2) { - LOG_WARN(Horizon, + LOG_WARN(Services, "Unsupported HUSR version {} for user {:032x}, skipping", header.version, user_id); return; } if (header.version > CURRENT_HUSR_VERSION) { - LOG_WARN(Horizon, + LOG_WARN(Services, "Unsupported HUSR version {} for user {:032x}, skipping", header.version, user_id); return; } - ASSERT(header.header_size == sizeof(HusrHeader), Horizon, + ASSERT(header.header_size == sizeof(HusrHeader), Services, "Invalid HUSR header size 0x{:x} for user {:032x}", header.header_size, user_id); // Data - const auto base = stream.Read(); - const auto data = stream.Read(); - const auto avatar_bg_color = stream.Read(); + const auto base = stream.read(); + const auto data = stream.read(); + const auto avatar_bg_color = stream.read(); std::string avatar_path; { - const auto size = stream.Read(); + const auto size = stream.read(); // TODO: do more cleanly for (u32 i = 0; i < size; i++) - avatar_path += stream.Read(); + avatar_path += stream.read(); } User user(base, data, avatar_bg_color, avatar_path); @@ -283,8 +290,8 @@ void UserManager::PreloadAvatar(Avatar& avatar, bool is_compressed) { auto stream = avatar.file->Open(filesystem::FileOpenFlags::Read); - std::vector raw(stream->GetSize()); - stream->ReadToSpan(std::span(raw)); + std::vector raw(stream->getSize()); + stream->readToSpan(std::span(raw)); delete stream; diff --git a/src/core/horizon/services/account/internal/user_manager.hpp b/src/core/horizon/services/account/internal/user_manager.hpp index 7fa56b818..8c527853a 100644 --- a/src/core/horizon/services/account/internal/user_manager.hpp +++ b/src/core/horizon/services/account/internal/user_manager.hpp @@ -59,10 +59,14 @@ class UserManager { return it->second; } - static std::string GetUserPath() { + static std::string GetUsersPath() { return fmt::format("{}/user", CONFIG_INSTANCE.GetAppDataPath()); } + static std::string GetUserPath(uuid_t user_id) { + return fmt::format("{}/{:032x}.husr", GetUsersPath(), user_id); + } + void Serialize(uuid_t user_id); void Deserialize(uuid_t user_id); diff --git a/src/core/horizon/services/account/profile.cpp b/src/core/horizon/services/account/profile.cpp index 590ebe959..c82538446 100644 --- a/src/core/horizon/services/account/profile.cpp +++ b/src/core/horizon/services/account/profile.cpp @@ -12,7 +12,7 @@ IProfile::Get(System* system, ProfileBase* out_base, OutBuffer out_user_data_buffer) { const auto& user = system->GetOS().GetUserManager().GetUser(user_id); *out_base = user.GetBase(); - out_user_data_buffer.stream->Write(user.GetData()); + out_user_data_buffer.stream->write(user.GetData()); return RESULT_SUCCESS; } @@ -44,7 +44,7 @@ result_t IProfile::LoadImage(System* system, system->GetOS().GetUserManager().LoadAvatarImageAsJpeg( user.GetAvatarPath(), user.GetAvatarBgColor(), data); - out_buffer.stream->WriteSpan(std::span(data)); + out_buffer.stream->writeSpan(std::span(data)); *out_size = static_cast(data.size()); return RESULT_SUCCESS; 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 9e7d8ec92..76f2a01ee 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/am/self_controller.cpp b/src/core/horizon/services/am/self_controller.cpp index 7005b6a59..99f2f3645 100644 --- a/src/core/horizon/services/am/self_controller.cpp +++ b/src/core/horizon/services/am/self_controller.cpp @@ -17,8 +17,8 @@ DEFINE_SERVICE_COMMAND_TABLE( SetWirelessPriorityMode, 91, GetAccumulatedSuspendedTickChangedEvent) ISelfController::ISelfController() - : library_applet_launchable_event{new kernel::Event( - true, "Library applet launchable event")}, + : library_applet_launchable_event{ + new kernel::Event(true, "Library applet launchable event")}, accumulated_suspended_tick_changed_event{new kernel::Event( false, "Accumulated suspended tick changed event")} {} @@ -47,9 +47,12 @@ result_t ISelfController::GetLibraryAppletLaunchableEvent( result_t ISelfController::CreateManagedDisplayLayer(System* system, kernel::Process* process, u64* out_layer_id) { - u32 binder_id = system->GetOS().GetDisplayDriver().CreateBinder(); - *out_layer_id = - system->GetOS().GetDisplayDriver().CreateLayer(process, binder_id); + const auto binder_handle = + system->GetOS().GetDisplayDriver().CreateBinder(); + *out_layer_id = system->GetOS() + .GetDisplayDriver() + .CreateLayer(process, binder_handle) + .GetRaw(); return RESULT_SUCCESS; } @@ -62,12 +65,17 @@ result_t ISelfController::IsSystemBufferSharingEnabled() { result_t ISelfController::CreateManagedDisplaySeparableLayer( System* system, kernel::Process* process, u64* out_display_layer_id, u64* out_recording_layer_id) { - u32 binder_id = system->GetOS().GetDisplayDriver().CreateBinder(); - *out_display_layer_id = - system->GetOS().GetDisplayDriver().CreateLayer(process, binder_id); + const auto binder_handle = + system->GetOS().GetDisplayDriver().CreateBinder(); + *out_display_layer_id = system->GetOS() + .GetDisplayDriver() + .CreateLayer(process, binder_handle) + .GetRaw(); // TODO: what is a recording layer? - *out_recording_layer_id = - system->GetOS().GetDisplayDriver().CreateLayer(process, binder_id); + *out_recording_layer_id = system->GetOS() + .GetDisplayDriver() + .CreateLayer(process, binder_handle) + .GetRaw(); return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/am/storage_accessor.cpp b/src/core/horizon/services/am/storage_accessor.cpp index f42ade92a..3554b456b 100644 --- a/src/core/horizon/services/am/storage_accessor.cpp +++ b/src/core/horizon/services/am/storage_accessor.cpp @@ -16,7 +16,7 @@ result_t IStorageAccessor::Write(i64 offset, // TODO: correct? const u64 size = data.size() - static_cast(offset); - const auto span = buffer.stream->ReadSpan(size); + const auto span = buffer.stream->readSpan(size); std::ranges::copy(span, data.data() + offset); return RESULT_SUCCESS; } @@ -28,7 +28,7 @@ result_t IStorageAccessor::Read(i64 offset, // TODO: correct? const u64 size = data.size() - static_cast(offset); - out_buffer.stream->WriteSpan( + out_buffer.stream->writeSpan( std::span(data.data() + offset, size)); return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/audio/audio_device.cpp b/src/core/horizon/services/audio/audio_device.cpp index 861102689..f7f835b64 100644 --- a/src/core/horizon/services/audio/audio_device.cpp +++ b/src/core/horizon/services/audio/audio_device.cpp @@ -78,18 +78,18 @@ result_t IAudioDevice::GetActiveAudioDeviceNameAuto( } result_t IAudioDevice::ListAudioDeviceNameImpl( - i32* out_count, std::optional out_stream) { + i32* out_count, std::optional out_stream) { LOG_FUNC_STUBBED(Services); // HACK *out_count = 1; - out_stream->Write({"Hydra audio device"}); + out_stream->write({"Hydra audio device"}); return RESULT_SUCCESS; } result_t IAudioDevice::SetAudioDeviceOutputVolumeImpl( - f32 volume, std::optional in_name_stream) { - const auto device_name_raw = in_name_stream->ReadPtr(); + f32 volume, std::optional in_name_stream) { + const auto device_name_raw = in_name_stream->readPtr(); const std::string device_name(device_name_raw->name); LOG_FUNC_WITH_ARGS_STUBBED(Services, "name: {}, volume: {}", device_name, volume); @@ -98,8 +98,8 @@ result_t IAudioDevice::SetAudioDeviceOutputVolumeImpl( } result_t IAudioDevice::GetAudioDeviceOutputVolumeImpl( - std::optional in_name_stream, f32* out_volume) { - const auto device_name_raw = in_name_stream->ReadPtr(); + std::optional in_name_stream, f32* out_volume) { + const auto device_name_raw = in_name_stream->readPtr(); const std::string device_name(device_name_raw->name); LOG_FUNC_WITH_ARGS_STUBBED(Services, "name: {}", device_name); @@ -109,11 +109,11 @@ result_t IAudioDevice::GetAudioDeviceOutputVolumeImpl( } result_t IAudioDevice::GetActiveAudioDeviceNameImpl( - std::optional out_stream) { + std::optional out_stream) { LOG_FUNC_STUBBED(Services); // HACK - out_stream->Write({"Hydra audio device"}); + out_stream->write({"Hydra audio device"}); return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/audio/audio_device.hpp b/src/core/horizon/services/audio/audio_device.hpp index 42c7da834..c09155bdc 100644 --- a/src/core/horizon/services/audio/audio_device.hpp +++ b/src/core/horizon/services/audio/audio_device.hpp @@ -48,13 +48,13 @@ class IAudioDevice : public IService { // Impl result_t ListAudioDeviceNameImpl(i32* out_count, - std::optional out_stream); + std::optional out_stream); result_t SetAudioDeviceOutputVolumeImpl( - f32 volume, std::optional in_name_stream); + f32 volume, std::optional in_name_stream); result_t GetAudioDeviceOutputVolumeImpl( - std::optional in_name_stream, f32* out_volume); - result_t - GetActiveAudioDeviceNameImpl(std::optional out_stream); + std::optional in_name_stream, f32* out_volume); + result_t GetActiveAudioDeviceNameImpl( + std::optional out_stream); }; } // namespace hydra::horizon::services::audio diff --git a/src/core/horizon/services/audio/audio_out.cpp b/src/core/horizon/services/audio/audio_out.cpp index 352b8b756..14ae24ebb 100644 --- a/src/core/horizon/services/audio/audio_out.cpp +++ b/src/core/horizon/services/audio/audio_out.cpp @@ -77,8 +77,8 @@ result_t IAudioOut::GetReleasedAudioOutBuffersAuto( result_t IAudioOut::AppendAudioOutBufferImpl( kernel::Process* process, u64 buffer_client_ptr, - std::optional in_buffer_stream) { - const auto buffer = in_buffer_stream->Read(); + std::optional in_buffer_stream) { + const auto buffer = in_buffer_stream->read(); // TODO: correct? const auto ptr = reinterpret_cast( process->GetMmu()->UnmapAddr(buffer.sample_buffer_ptr)); @@ -89,16 +89,16 @@ result_t IAudioOut::AppendAudioOutBufferImpl( } result_t IAudioOut::GetReleasedAudioOutBuffersImpl( - u32* out_count, std::optional out_buffers_stream) { + u32* out_count, std::optional out_buffers_stream) { std::unique_lock lock(buffer_mutex); *out_count = static_cast(released_buffers.size()); if (released_buffers.empty()) { - out_buffers_stream->Write(0); + out_buffers_stream->write(0); } else { for (const auto client_ptr : released_buffers) - out_buffers_stream->Write(client_ptr); + out_buffers_stream->write(client_ptr); released_buffers.clear(); } diff --git a/src/core/horizon/services/audio/audio_out.hpp b/src/core/horizon/services/audio/audio_out.hpp index 0c3d6c405..982dc7f91 100644 --- a/src/core/horizon/services/audio/audio_out.hpp +++ b/src/core/horizon/services/audio/audio_out.hpp @@ -52,11 +52,12 @@ class IAudioOut : public IService { u32* out_count, OutBuffer out_buffers_buffer); // Impl - result_t - AppendAudioOutBufferImpl(kernel::Process* process, u64 buffer_client_ptr, - std::optional in_buffer_stream); + result_t AppendAudioOutBufferImpl( + kernel::Process* process, u64 buffer_client_ptr, + std::optional in_buffer_stream); result_t GetReleasedAudioOutBuffersImpl( - u32* out_count, std::optional out_buffers_stream); + u32* out_count, + std::optional out_buffers_stream); }; } // namespace hydra::horizon::services::audio diff --git a/src/core/horizon/services/audio/audio_out_manager.cpp b/src/core/horizon/services/audio/audio_out_manager.cpp index 89e74273f..2d1d63bbf 100644 --- a/src/core/horizon/services/audio/audio_out_manager.cpp +++ b/src/core/horizon/services/audio/audio_out_manager.cpp @@ -45,7 +45,7 @@ result_t IAudioOutManager::OpenAudioOutAuto( } result_t IAudioOutManager::ListAudioOutsImpl( - u32* out_count, std::optional out_stream) { + u32* out_count, std::optional out_stream) { (void)out_stream; LOG_FUNC_STUBBED(Services); @@ -57,13 +57,14 @@ result_t IAudioOutManager::ListAudioOutsImpl( result_t IAudioOutManager::OpenAudioOutImpl( RequestContext* ctx, u32 sample_rate, u16 channel_count, u64 aruid, - std::optional in_device_name_stream, u32* out_sample_rate, - u32* out_channel_count, PcmFormat* out_format, AudioOutState* out_state, - std::optional out_device_name_stream) { + std::optional in_device_name_stream, + u32* out_sample_rate, u32* out_channel_count, PcmFormat* out_format, + AudioOutState* out_state, + std::optional out_device_name_stream) { (void)aruid; [[maybe_unused]] const auto device_name_in = - in_device_name_stream->ReadNullTerminatedString(); + in_device_name_stream->readNullTerminatedString(); LOG_DEBUG(Services, "Sample rate: {}, channel count: {}, device name: {}", sample_rate, channel_count, device_name_in); @@ -84,7 +85,7 @@ result_t IAudioOutManager::OpenAudioOutImpl( // TODO: is this somehow connected to device name in? std::string device_name_out = "Hydra audio device"; - out_device_name_stream->WriteNullTerminatedString(device_name_out); + out_device_name_stream->writeNullTerminatedString(device_name_out); AddService(*ctx, new IAudioOut(ctx->system, format, sample_rate, channel_count)); diff --git a/src/core/horizon/services/audio/audio_out_manager.hpp b/src/core/horizon/services/audio/audio_out_manager.hpp index 488e7af0a..e74db54f0 100644 --- a/src/core/horizon/services/audio/audio_out_manager.hpp +++ b/src/core/horizon/services/audio/audio_out_manager.hpp @@ -34,14 +34,13 @@ class IAudioOutManager : public IService { // Impl result_t ListAudioOutsImpl(u32* out_count, - std::optional out_stream); - result_t - OpenAudioOutImpl(RequestContext* ctx, u32 sample_rate, u16 channel_count, - u64 aruid, - std::optional in_device_name_stream, - u32* out_sample_rate, u32* out_channel_count, - PcmFormat* out_format, AudioOutState* out_state, - std::optional out_device_name_stream); + std::optional out_stream); + result_t OpenAudioOutImpl( + RequestContext* ctx, u32 sample_rate, u16 channel_count, u64 aruid, + std::optional in_device_name_stream, + u32* out_sample_rate, u32* out_channel_count, PcmFormat* out_format, + AudioOutState* out_state, + std::optional out_device_name_stream); }; } // namespace hydra::horizon::services::audio diff --git a/src/core/horizon/services/audio/audio_renderer.cpp b/src/core/horizon/services/audio/audio_renderer.cpp index a681c007c..9dad645d9 100644 --- a/src/core/horizon/services/audio/audio_renderer.cpp +++ b/src/core/horizon/services/audio/audio_renderer.cpp @@ -206,27 +206,27 @@ result_t IAudioRenderer::RequestUpdateAuto( } result_t IAudioRenderer::RequestUpdateImpl( - std::optional in_stream, - std::optional out_stream, - std::optional out_perf_stream) { + std::optional in_stream, + std::optional out_stream, + std::optional out_perf_stream) { ONCE(LOG_FUNC_STUBBED(Services)); // Header - const auto in_header = in_stream->Read(); + const auto in_header = in_stream->read(); // TODO: correct? - auto header = out_stream->WriteReturningPtr(); + auto header = out_stream->writeReturningPtr(); header->revision = in_header.revision; // make_magic4('R', 'E', 'V', '4'); header->total_size = sizeof(UpdateDataHeader); - in_stream->SeekBy(in_header.behavior_size); + in_stream->seekBy(in_header.behavior_size); // Mempools u32 mempool_count = (params.effect_count + params.voice_count * 4); header->mempools_size = mempool_count * sizeof(MemPoolInfoOut); header->total_size += header->mempools_size; for (u32 i = 0; i < mempool_count; i++) { - const auto mempool_in = in_stream->Read(); + const auto mempool_in = in_stream->read(); MemPoolInfoOut mempool{}; switch (mempool_in.state) { @@ -242,14 +242,14 @@ result_t IAudioRenderer::RequestUpdateImpl( mempool.new_state = MemPoolState::Released; // mempool_in.state; break; } - out_stream->Write(mempool); + out_stream->write(mempool); } // Voices header->voices_size = params.voice_count * sizeof(VoiceInfoOut); header->total_size += header->voices_size; for (u32 i = 0; i < params.voice_count; i++) { - const auto voice_in = in_stream->Read(); + const auto voice_in = in_stream->read(); VoiceInfoOut& voice = voices[i]; if (voice_in.is_new) { @@ -275,7 +275,7 @@ result_t IAudioRenderer::RequestUpdateImpl( } else { ONCE(LOG_NOT_IMPLEMENTED(Services, "Voice")); } - out_stream->Write(voice); + out_stream->write(voice); } // Channels @@ -290,7 +290,7 @@ result_t IAudioRenderer::RequestUpdateImpl( } else { header->effects_size = params.effect_count * sizeof(EffectInfoOutV1); for (u32 i = 0; i < params.effect_count; i++) { - out_stream->Write({ + out_stream->write({ .state = EffectState::Enabled, }); } @@ -301,7 +301,7 @@ result_t IAudioRenderer::RequestUpdateImpl( header->sinks_size = params.sink_count * sizeof(SinkInfoOut); header->total_size += header->sinks_size; for (u32 i = 0; i < params.sink_count; i++) { - out_stream->Write({ + out_stream->write({ .last_written_offset = 0, }); } @@ -309,7 +309,7 @@ result_t IAudioRenderer::RequestUpdateImpl( // Behavior header->behavior_size = sizeof(BehaviorInfoOut); header->total_size += header->behavior_size; - out_stream->Write({ + out_stream->write({ .error_info_count = 0, }); @@ -318,7 +318,7 @@ result_t IAudioRenderer::RequestUpdateImpl( if (false) { header->render_info_size = sizeof(RenderInfoOut); header->total_size += header->render_info_size; - out_stream->Write({ + out_stream->write({ .elapsed_frame_count = 0, }); } @@ -328,7 +328,7 @@ result_t IAudioRenderer::RequestUpdateImpl( header->total_size += header->performance_manager_size; // HACK if (out_perf_stream) { - out_perf_stream->Write({ + out_perf_stream->write({ .history_size = 0, }); } diff --git a/src/core/horizon/services/audio/audio_renderer.hpp b/src/core/horizon/services/audio/audio_renderer.hpp index 613d33822..edcce3b67 100644 --- a/src/core/horizon/services/audio/audio_renderer.hpp +++ b/src/core/horizon/services/audio/audio_renderer.hpp @@ -47,9 +47,10 @@ class IAudioRenderer : public IService { OutBuffer out_perf_buffer); // Impl - result_t RequestUpdateImpl(std::optional in_stream, - std::optional out_stream, - std::optional out_perf_stream); + result_t + RequestUpdateImpl(std::optional in_stream, + std::optional out_stream, + std::optional out_perf_stream); }; } // namespace hydra::horizon::services::audio diff --git a/src/core/horizon/services/codec/hardware_opus_decoder.cpp b/src/core/horizon/services/codec/hardware_opus_decoder.cpp index 555b43aa6..042e2cb9b 100644 --- a/src/core/horizon/services/codec/hardware_opus_decoder.cpp +++ b/src/core/horizon/services/codec/hardware_opus_decoder.cpp @@ -14,9 +14,9 @@ result_t IHardwareOpusDecoder::DecodeInterleavedOld( } result_t IHardwareOpusDecoder::DecodeInterleavedImpl( - std::optional in_opus_stream, i32* out_decoded_data_size, - i32* out_decoded_sample_count, - std::optional out_pcm_stream) { + std::optional in_opus_stream, + i32* out_decoded_data_size, i32* out_decoded_sample_count, + std::optional out_pcm_stream) { (void)in_opus_stream; (void)out_pcm_stream; ONCE(LOG_FUNC_STUBBED(Services)); diff --git a/src/core/horizon/services/codec/hardware_opus_decoder.hpp b/src/core/horizon/services/codec/hardware_opus_decoder.hpp index d7d003403..3cb362a21 100644 --- a/src/core/horizon/services/codec/hardware_opus_decoder.hpp +++ b/src/core/horizon/services/codec/hardware_opus_decoder.hpp @@ -19,10 +19,10 @@ class IHardwareOpusDecoder : public IService { // Impl result_t - DecodeInterleavedImpl(std::optional in_opus_stream, + DecodeInterleavedImpl(std::optional in_opus_stream, i32* out_decoded_data_size, i32* out_decoded_sample_count, - std::optional out_pcm_stream); + std::optional out_pcm_stream); }; } // namespace hydra::horizon::services::codec diff --git a/src/core/horizon/services/const.hpp b/src/core/horizon/services/const.hpp index aa955655a..321d2913f 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 */ \ @@ -50,10 +50,10 @@ class InBuffer { public: static constexpr BufferAttr attr = attr_; - std::optional stream; + std::optional stream; InBuffer() : stream{std::nullopt} {} - InBuffer(std::optional stream_) + InBuffer(std::optional stream_) : stream{std::move(stream_)} {} bool IsValid() const { return stream.has_value(); } @@ -64,10 +64,10 @@ class OutBuffer { public: static constexpr BufferAttr attr = attr_; - std::optional stream; + std::optional stream; OutBuffer() : stream{std::nullopt} {} - OutBuffer(std::optional stream_) + OutBuffer(std::optional stream_) : stream{std::move(stream_)} {} bool IsValid() const { return stream.has_value(); } @@ -83,13 +83,13 @@ class InHandle { public: static constexpr HandleAttr attr = attr_; - InHandle() : handle_id{INVALID_HANDLE_ID} {} - InHandle(handle_id_t handle_id_) : handle_id{handle_id_} {} + InHandle() : handle{INVALID_HANDLE} {} + InHandle(Handle handle_) : handle{handle_} {} - operator handle_id_t() const { return handle_id; } + operator Handle() const { return handle; } private: - handle_id_t handle_id; + Handle handle; }; template @@ -97,18 +97,18 @@ class OutHandle { public: static constexpr HandleAttr attr = attr_; - OutHandle() : handle_id{nullptr} {} - OutHandle(handle_id_t* handle_id_) : handle_id{handle_id_} {} + OutHandle() : handle{nullptr} {} + OutHandle(Handle* handle_) : handle{handle_} {} - operator handle_id_t&() { return *handle_id; } + operator Handle&() { return *handle; } - OutHandle& operator=(handle_id_t other) { - *handle_id = other; + OutHandle& operator=(Handle other) { + *handle = other; return *this; } private: - handle_id_t* handle_id; + Handle* handle; }; enum class ArgumentType { @@ -218,7 +218,7 @@ void read_arg(RequestContext& context, Class& instance, arg_index + 1>(context, instance, args); return; } else if constexpr (traits::type == ArgumentType::InData) { - arg = context.streams.in_stream.Read(); + arg = context.streams.in_stream.read(); // Next read_arg(); + .writeReturningPtr(); // Next read_arg(context, instance, args); return; } else if constexpr (traits::type == ArgumentType::InBuffer) { - std::optional stream; + std::optional stream; if constexpr (Arg::attr == BufferAttr::AutoSelect) { if (in_buffer_index < context.streams.send_buffers_streams.size()) @@ -258,7 +258,7 @@ void read_arg(RequestContext& context, Class& instance, out_buffer_index, arg_index + 1>(context, instance, args); return; } else if constexpr (traits::type == ArgumentType::OutBuffer) { - std::optional stream; + std::optional stream; if constexpr (Arg::attr == BufferAttr::AutoSelect) { if (out_buffer_index < context.streams.recv_buffers_streams.size()) @@ -284,36 +284,34 @@ void read_arg(RequestContext& context, Class& instance, args); return; } else if constexpr (traits::type == ArgumentType::InHandle) { - handle_id_t handle_id; + Handle handle; if constexpr (Arg::attr == HandleAttr::Copy) { - handle_id = - context.streams.in_copy_handles_stream.Read(); + handle = context.streams.in_copy_handles_stream.read(); } else if constexpr (Arg::attr == HandleAttr::Move) { - handle_id = - context.streams.in_move_handles_stream.Read(); + handle = context.streams.in_move_handles_stream.read(); } else { LOG_FATAL(Services, "Invalid in handle args"); } - arg = Arg(handle_id); + arg = Arg(handle); // Next read_arg(context, instance, args); return; } else if constexpr (traits::type == ArgumentType::OutHandle) { - handle_id_t* handle_id; + Handle* handle; if constexpr (Arg::attr == HandleAttr::Copy) { - handle_id = context.streams.out_copy_handles_stream - .WriteReturningPtr(); + handle = context.streams.out_copy_handles_stream + .writeReturningPtr(); } else if constexpr (Arg::attr == HandleAttr::Move) { - handle_id = context.streams.out_move_handles_stream - .WriteReturningPtr(); + handle = context.streams.out_move_handles_stream + .writeReturningPtr(); } else { LOG_FATAL(Services, "Invalid out handle args"); } - arg = Arg(handle_id); + arg = Arg(handle); // Next read_argRead(); - arg = instance.GetService(context, service_handle_id); + auto service_handle = + context.streams.in_objects_stream->read(); + arg = instance.GetService(context, service_handle); ASSERT_DEBUG(arg, Services, "Invalid service"); // Next diff --git a/src/core/horizon/services/fssrv/const.hpp b/src/core/horizon/services/fssrv/const.hpp index 485eb2356..933d06c35 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/directory.cpp b/src/core/horizon/services/fssrv/directory.cpp index 33dd24f5c..9d3033d24 100644 --- a/src/core/horizon/services/fssrv/directory.cpp +++ b/src/core/horizon/services/fssrv/directory.cpp @@ -29,8 +29,8 @@ result_t IDirectory::Read(u64* out_entry_count, u32 i = 0; for (const auto& [path, entry] : directory->GetEntries()) { // Check if the stream has enough space to write the entry - if (out_entries.stream->GetSeek() + sizeof(FsDirectoryEntry) > - out_entries.stream->GetSize()) + if (out_entries.stream->getSeek() + sizeof(FsDirectoryEntry) > + out_entries.stream->getSize()) break; // TODO: find a better way to index @@ -56,13 +56,13 @@ result_t IDirectory::Read(u64* out_entry_count, else e.file_size = 0; - out_entries.stream->Write(e); + out_entries.stream->write(e); entry_index++; i++; } - *out_entry_count = out_entries.stream->GetSeek() / sizeof(FsDirectoryEntry); + *out_entry_count = out_entries.stream->getSeek() / sizeof(FsDirectoryEntry); return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/fssrv/file.cpp b/src/core/horizon/services/fssrv/file.cpp index a700db519..60fdf4249 100644 --- a/src/core/horizon/services/fssrv/file.cpp +++ b/src/core/horizon/services/fssrv/file.cpp @@ -21,15 +21,15 @@ result_t IFile::Read(Aligned option, u64 offset, u64 size, LOG_DEBUG(Services, "Offset: 0x{:08x}, size: 0x{:08x}", offset, size); - const auto max_size = stream->GetSize() - offset; + const auto max_size = stream->getSize() - offset; if (size > max_size) { LOG_WARN(Services, "Reading {} bytes, but maximum readable size is {}", size, max_size); size = max_size; } - stream->SeekTo(offset); - stream->ReadToSpan(out_buffer.stream->WriteReturningSpan(size)); + stream->seekTo(offset); + stream->readToSpan(out_buffer.stream->writeReturningSpan(size)); *out_written_size = size; return RESULT_SUCCESS; @@ -42,8 +42,8 @@ result_t IFile::Write(Aligned option, u64 offset, u64 size, LOG_DEBUG(Services, "Offset: 0x{:08x}, size: 0x{:08x}", offset, size); - stream->SeekTo(offset); - stream->WriteSpan(in_buffer.stream->ReadSpan(size)); + stream->seekTo(offset); + stream->writeSpan(in_buffer.stream->readSpan(size)); return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/fssrv/file.hpp b/src/core/horizon/services/fssrv/file.hpp index fcedbba3c..7a3bb6e0e 100644 --- a/src/core/horizon/services/fssrv/file.hpp +++ b/src/core/horizon/services/fssrv/file.hpp @@ -12,7 +12,7 @@ class IFile : public IService { private: filesystem::IFile* file; - io::IStream* stream; + ztd::io::IStream* stream; result_t RequestImpl([[maybe_unused]] RequestContext& context, u32 id) override; diff --git a/src/core/horizon/services/fssrv/filesystem.cpp b/src/core/horizon/services/fssrv/filesystem.cpp index 6905d6538..ce52a4d50 100644 --- a/src/core/horizon/services/fssrv/filesystem.cpp +++ b/src/core/horizon/services/fssrv/filesystem.cpp @@ -20,7 +20,7 @@ DEFINE_SERVICE_COMMAND_TABLE(IFileSystem, 0, CreateFile, 1, DeleteFile, 2, [[maybe_unused]] const auto path_var = \ mount + \ std::string( \ - in_##path_var##_buffer.stream->ReadNullTerminatedString()); \ + in_##path_var##_buffer.stream->readNullTerminatedString()); \ LOG_DEBUG(Services, debug_name ": {}", path); #define READ_PATH() READ_PATH_IMPL(path, "Path") diff --git a/src/core/horizon/services/fssrv/filesystem.hpp b/src/core/horizon/services/fssrv/filesystem.hpp index 8ab9410af..d59c886f5 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.cpp b/src/core/horizon/services/fssrv/filesystem_proxy.cpp index 558ddfbce..159d61975 100644 --- a/src/core/horizon/services/fssrv/filesystem_proxy.cpp +++ b/src/core/horizon/services/fssrv/filesystem_proxy.cpp @@ -53,7 +53,7 @@ result_t IFileSystemProxy::OpenFileSystem( (void)type; // TODO: correct? - const auto mount = path_buffer.stream->ReadNullTerminatedString(); + const auto mount = path_buffer.stream->readNullTerminatedString(); LOG_DEBUG(Services, "Mount: {}", mount); AddService(*ctx, new IFileSystem(mount)); @@ -69,7 +69,7 @@ result_t IFileSystemProxy::OpenFileSystemWithIdObsolete( (void)program_id; // TODO: correct? - const auto mount = path_buffer.stream->ReadNullTerminatedString(); + const auto mount = path_buffer.stream->readNullTerminatedString(); LOG_DEBUG(Services, "Mount: {}", mount); AddService(*ctx, new IFileSystem(mount)); @@ -82,7 +82,7 @@ result_t IFileSystemProxy::OpenBisFileSystem( InBuffer unknown_buffer) { const auto unknown = unknown_buffer.stream - ->ReadNullTerminatedString(); // TODO: what is this for? + ->readNullTerminatedString(); // TODO: what is this for? LOG_FUNC_WITH_ARGS_STUBBED(Services, "partition ID: {}, unknown: {}", partition_id, unknown); @@ -122,7 +122,7 @@ result_t IFileSystemProxy::ReadSaveDataFileSystemExtraDataBySaveDataSpaceId( // TODO: why is the stream NULL? if (out_buffer.stream) { // HACK - out_buffer.stream->Write({}); + out_buffer.stream->write({}); } return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/fssrv/filesystem_proxy.hpp b/src/core/horizon/services/fssrv/filesystem_proxy.hpp index 648a4f4eb..c4e774195 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/fssrv/save_data_info_reader.cpp b/src/core/horizon/services/fssrv/save_data_info_reader.cpp index 7174719b0..40f787fb6 100644 --- a/src/core/horizon/services/fssrv/save_data_info_reader.cpp +++ b/src/core/horizon/services/fssrv/save_data_info_reader.cpp @@ -29,13 +29,13 @@ result_t ISaveDataInfoReader::ReadSaveDataInfo( auto stream = out_entry_buffer.stream; for (u32 i = entry_index; i < sizeof_array(entries); i++) { - if (stream->GetSeek() + sizeof(SaveDataInfo) > stream->GetSize()) + if (stream->getSeek() + sizeof(SaveDataInfo) > stream->getSize()) break; - stream->Write(entries[i]); + stream->write(entries[i]); } - *out_entry_count = stream->GetSeek() / sizeof(SaveDataInfo); + *out_entry_count = stream->getSeek() / sizeof(SaveDataInfo); return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/fssrv/storage.cpp b/src/core/horizon/services/fssrv/storage.cpp index a7492ca4e..d25d101fd 100644 --- a/src/core/horizon/services/fssrv/storage.cpp +++ b/src/core/horizon/services/fssrv/storage.cpp @@ -16,7 +16,7 @@ result_t IStorage::Read(u64 offset, u64 size, OutBuffer out_buffer) { LOG_DEBUG(Services, "Offset: 0x{:08x}, size: 0x{:08x}", offset, size); - const auto max_size = stream->GetSize() - offset; + const auto max_size = stream->getSize() - offset; if (size > max_size) { LOG_WARN(Services, "Reading {} bytes, but maximum readable size is {}", size, max_size); @@ -27,8 +27,8 @@ result_t IStorage::Read(u64 offset, u64 size, if (!out_buffer.stream) return RESULT_SUCCESS; - stream->SeekTo(offset); - stream->ReadToSpan(out_buffer.stream->WriteReturningSpan(size)); + stream->seekTo(offset); + stream->readToSpan(out_buffer.stream->writeReturningSpan(size)); return RESULT_SUCCESS; } @@ -37,8 +37,8 @@ result_t IStorage::Write(u64 offset, u64 size, InBuffer in_buffer) { LOG_DEBUG(Services, "Offset: 0x{:08x}, size: 0x{:08x}", offset, size); - stream->SeekTo(offset); - stream->WriteSpan(in_buffer.stream->ReadSpan(size)); + stream->seekTo(offset); + stream->writeSpan(in_buffer.stream->readSpan(size)); return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/fssrv/storage.hpp b/src/core/horizon/services/fssrv/storage.hpp index 075d8b611..09ef90611 100644 --- a/src/core/horizon/services/fssrv/storage.hpp +++ b/src/core/horizon/services/fssrv/storage.hpp @@ -26,7 +26,7 @@ class IStorage : public IService { private: filesystem::IFile* file; - io::IStream* stream; + ztd::io::IStream* stream; }; } // namespace hydra::horizon::services::fssrv diff --git a/src/core/horizon/services/hid/const.hpp b/src/core/horizon/services/hid/const.hpp index f85f397e3..7b2383f6c 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/hid/hid_server.cpp b/src/core/horizon/services/hid/hid_server.cpp index 0d7dceca3..c1156d2a1 100644 --- a/src/core/horizon/services/hid/hid_server.cpp +++ b/src/core/horizon/services/hid/hid_server.cpp @@ -51,10 +51,10 @@ IHidServer::GetSupportedNpadStyleSet(System* system, result_t IHidServer::SetSupportedNpadIdType( System* system, kernel::AppletResourceUserId aruid, InBuffer in_types_buffer) { - while (in_types_buffer.stream->GetSeek() < - in_types_buffer.stream->GetSize()) { + while (in_types_buffer.stream->getSeek() < + in_types_buffer.stream->getSize()) { const auto index = - internal::ToNpadIndex(in_types_buffer.stream->Read()); + internal::ToNpadIndex(in_types_buffer.stream->read()); APPLET_RESOURCE(aruid).SetNpadSupported(index, true); } return RESULT_SUCCESS; diff --git a/src/core/horizon/services/hosbinder/hos_binder_driver.cpp b/src/core/horizon/services/hosbinder/hos_binder_driver.cpp index 0c6eb201f..0c89ea52a 100644 --- a/src/core/horizon/services/hosbinder/hos_binder_driver.cpp +++ b/src/core/horizon/services/hosbinder/hos_binder_driver.cpp @@ -129,8 +129,8 @@ result_t IHOSBinderDriver::TransactParcelAuto( // TODO: flags void IHOSBinderDriver::TransactParcelImpl( System& system, i32 binder_id, TransactCode code, u32 flags, - std::optional in_stream, - std::optional out_stream) { + std::optional in_stream, + std::optional out_stream) { (void)flags; ParcelReader parcel_reader(in_stream.value()); diff --git a/src/core/horizon/services/hosbinder/hos_binder_driver.hpp b/src/core/horizon/services/hosbinder/hos_binder_driver.hpp index 456d67cff..723b7ca68 100644 --- a/src/core/horizon/services/hosbinder/hos_binder_driver.hpp +++ b/src/core/horizon/services/hosbinder/hos_binder_driver.hpp @@ -55,8 +55,8 @@ class IHOSBinderDriver : public IService { void TransactParcelImpl(System& system, i32 binder_id, TransactCode code, u32 flags, - std::optional in_stream, - std::optional out_stream); + std::optional in_stream, + std::optional out_stream); }; } // namespace hydra::horizon::services::hosbinder diff --git a/src/core/horizon/services/hosbinder/parcel.hpp b/src/core/horizon/services/hosbinder/parcel.hpp index 9b9a7e232..ba3407d75 100644 --- a/src/core/horizon/services/hosbinder/parcel.hpp +++ b/src/core/horizon/services/hosbinder/parcel.hpp @@ -25,18 +25,18 @@ struct ParcelFlattenedBinder { class ParcelReader { public: - ParcelReader(io::MemoryStream stream_) : stream{std::move(stream_)} { + ParcelReader(ztd::io::MemoryStream stream_) : stream{std::move(stream_)} { auto header = Read(); - stream.SeekTo(header.data_offset); + stream.seekTo(header.data_offset); } template std::span ReadSpan(usize count) { - const auto span = stream.ReadSpan(count); + const auto span = stream.readSpan(count); // Align usize size = count * sizeof(T); - stream.SeekBy(align(size, static_cast(4)) - size); + stream.seekBy(align(size, static_cast(4)) - size); return span; } @@ -94,13 +94,13 @@ class ParcelReader { } private: - io::MemoryStream stream; + ztd::io::MemoryStream stream; }; class ParcelWriter { public: - ParcelWriter(io::MemoryStream stream_) : stream{std::move(stream_)} { - header = stream.WriteReturningPtr({ + ParcelWriter(ztd::io::MemoryStream stream_) : stream{std::move(stream_)} { + header = stream.writeReturningPtr({ .data_size = 0x0, .data_offset = sizeof(ParcelHeader), .objects_size = 0x0, @@ -110,11 +110,11 @@ class ParcelWriter { void Finish() { header->data_size = - static_cast(stream.GetSeek() - header->data_offset); + static_cast(stream.getSeek() - header->data_offset); header->objects_size = static_cast(objects.size() * sizeof(u32)); header->objects_offset = header->data_offset + header->data_size; - stream.SeekTo(header->objects_offset); - stream.WriteSpan(std::span(objects)); + stream.seekTo(header->objects_offset); + stream.writeSpan(std::span(objects)); } template @@ -131,11 +131,11 @@ class ParcelWriter { template std::span WriteReturningSpan(usize count) { - auto span = stream.WriteReturningSpan(count); + auto span = stream.writeReturningSpan(count); // Align usize size = count * sizeof(T); - stream.SeekBy(align(size, static_cast(4)) - size); + stream.seekBy(align(size, static_cast(4)) - size); return span; } @@ -195,7 +195,7 @@ class ParcelWriter { } private: - io::MemoryStream stream; + ztd::io::MemoryStream stream; ParcelHeader* header; std::vector objects; diff --git a/src/core/horizon/services/lm/logger.cpp b/src/core/horizon/services/lm/logger.cpp index ac96c37ff..3a10dba4a 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, @@ -47,14 +47,14 @@ enum class LogDataChunkKey { }; // From Ryujinx -bool TryReadUleb128(io::MemoryStream& stream, u32& result) { +bool TryReadUleb128(ztd::io::MemoryStream& stream, u32& result) { result = 0; int count = 0; u8 encoded; do { // TODO: check if enough space - encoded = stream.Read(); + encoded = stream.read(); result += static_cast(encoded & 0x7F) << (7 * count); @@ -81,16 +81,17 @@ 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? - const auto header = stream.Read(); + ZTD_ASSIGN_OR_RETURN_VALUE( + auto stream, buffer.stream, + RESULT_SUCCESS); // TODO: return error on failure? + const auto header = stream.read(); // From Ryujinx [[maybe_unused]] bool is_head_packet = any(header.flags & PacketFlags::Head); bool is_tail_packet = any(header.flags & PacketFlags::Tail); - while (stream.GetSeek() - sizeof(LogPacketHeader) < + while (stream.getSeek() - sizeof(LogPacketHeader) < header.payload_size) { // TODO: correct? u32 key; u32 size; @@ -98,7 +99,7 @@ result_t ILogger::Log(InBuffer buffer) { return MAKE_RESULT( Svc, kernel::Error::InvalidCombination); // TODO: module - const auto data = stream.ReadSpan(size); + const auto data = stream.readSpan(size); #define GET_DATA(type) *reinterpret_cast(data.data()) #define GET_STRING() \ @@ -106,7 +107,7 @@ result_t ILogger::Log(InBuffer buffer) { switch (static_cast(key)) { case LogDataChunkKey::Begin: - stream.SeekBy(size); + stream.seekBy(size); continue; case LogDataChunkKey::End: break; diff --git a/src/core/horizon/services/nifm/general_service.cpp b/src/core/horizon/services/nifm/general_service.cpp index b51324ea0..d5c6bc1f8 100644 --- a/src/core/horizon/services/nifm/general_service.cpp +++ b/src/core/horizon/services/nifm/general_service.cpp @@ -69,7 +69,7 @@ result_t IGeneralService::GetCurrentNetworkProfile( LOG_NOT_IMPLEMENTED(Services, "GetCurrentNetworkProfile"); // HACK - out_buffer.stream->Write( + out_buffer.stream->write( {.ip_setting_data = { .ip_address_setting = diff --git a/src/core/horizon/services/nsd/manager.cpp b/src/core/horizon/services/nsd/manager.cpp index b09376abf..c54774104 100644 --- a/src/core/horizon/services/nsd/manager.cpp +++ b/src/core/horizon/services/nsd/manager.cpp @@ -7,7 +7,7 @@ DEFINE_SERVICE_COMMAND_TABLE(IManager, 11, GetEnvironmentIdentifier) result_t IManager::GetEnvironmentIdentifier( OutBuffer out_buffer) { // TODO: correct? - out_buffer.stream->WriteNullTerminatedString("Ip1"); + out_buffer.stream->writeNullTerminatedString("Ip1"); return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/nvdrv/ioctl/channel_base.hpp b/src/core/horizon/services/nvdrv/ioctl/channel_base.hpp index 5c1c44506..d1c415b10 100644 --- a/src/core/horizon/services/nvdrv/ioctl/channel_base.hpp +++ b/src/core/horizon/services/nvdrv/ioctl/channel_base.hpp @@ -6,12 +6,12 @@ namespace hydra::horizon::services::nvdrv::ioctl { struct MapCmdBufferHandle { - handle_id_t in_map_handle_id; + Handle in_map_handle; u32 out_phys_addr; }; struct UnmapCmdBufferHandle { - handle_id_t in_map_handle_id; + Handle in_map_handle; u32 _reserved_x4; }; @@ -97,9 +97,9 @@ class ChannelBase : public FdBase { } // namespace hydra::horizon::services::nvdrv::ioctl ENABLE_STRUCT_FORMATTING( - hydra::horizon::services::nvdrv::ioctl::MapCmdBufferHandle, - in_map_handle_id, "", "in map handle") + hydra::horizon::services::nvdrv::ioctl::MapCmdBufferHandle, in_map_handle, + "", "in map handle") ENABLE_STRUCT_FORMATTING( - hydra::horizon::services::nvdrv::ioctl::UnmapCmdBufferHandle, - in_map_handle_id, "", "in map handle") + hydra::horizon::services::nvdrv::ioctl::UnmapCmdBufferHandle, in_map_handle, + "", "in map handle") diff --git a/src/core/horizon/services/nvdrv/ioctl/const.hpp b/src/core/horizon/services/nvdrv/ioctl/const.hpp index b8be2da83..e2e18c6cf 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); \ @@ -54,10 +54,10 @@ namespace hydra::horizon::services::nvdrv::ioctl { struct IoctlContext { System& system; kernel::Process* process; - std::optional in_stream; - std::optional in_buffer_stream; - std::optional out_stream; - std::optional out_buffer_stream; + std::optional in_stream; + std::optional in_buffer_stream; + std::optional out_stream; + std::optional out_buffer_stream; }; template @@ -177,9 +177,9 @@ void read_arg(IoctlContext& context, CommandArguments& args) { return; } else if constexpr (traits::type == ArgumentType::In) { ASSERT_DEBUG(context.in_stream, Services, "No input stream"); - arg = context.in_stream->Read(); + arg = context.in_stream->read(); if (context.out_stream) - context.out_stream->SeekBy(sizeof(Arg)); + context.out_stream->seekBy(sizeof(Arg)); // Next read_arg(context, args); @@ -187,9 +187,9 @@ void read_arg(IoctlContext& context, CommandArguments& args) { } else if constexpr (traits::type == ArgumentType::Out) { ASSERT_DEBUG(context.out_stream, Services, "No output stream"); arg = context.out_stream - ->WriteReturningPtr(); + ->writeReturningPtr(); if (context.in_stream) - context.in_stream->SeekBy(sizeof(typename traits::BaseType)); + context.in_stream->seekBy(sizeof(typename traits::BaseType)); // Next read_arg(context, args); @@ -197,9 +197,9 @@ void read_arg(IoctlContext& context, CommandArguments& args) { } else if constexpr (traits::type == ArgumentType::InOut) { ASSERT_DEBUG(context.in_stream, Services, "No input stream"); ASSERT_DEBUG(context.out_stream, Services, "No output stream"); - arg.in = context.in_stream->Read(); + arg.in = context.in_stream->read(); arg.out = - context.out_stream->WriteReturningPtr(); + context.out_stream->writeReturningPtr(); // Next read_arg(context, args); @@ -208,15 +208,15 @@ void read_arg(IoctlContext& context, CommandArguments& args) { ASSERT_DEBUG(context.in_stream, Services, "No input stream"); ASSERT_DEBUG(context.out_stream, Services, "No output stream"); arg.data = context.out_stream - ->WriteReturningPtr(); - *arg.data = context.in_stream->Read(); + ->writeReturningPtr(); + *arg.data = context.in_stream->read(); // Next read_arg(context, args); return; } else /*if constexpr (traits::type == ArgumentType::InArray)*/ { ASSERT_DEBUG(context.in_stream, Services, "No input stream"); - arg = context.in_stream->ReadPtr(); + arg = context.in_stream->readPtr(); // Next static_assert(arg_index == 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 617b37ee1..a304dac43 100644 --- a/src/core/horizon/services/nvdrv/ioctl/nvhost_as_gpu.cpp +++ b/src/core/horizon/services/nvdrv/ioctl/nvhost_as_gpu.cpp @@ -50,7 +50,7 @@ NvResult NvHostAsGpu::UnmapBuffer(gpu_vaddr_t addr) { NvResult NvHostAsGpu::MapBufferEX(System* system, kernel::Process* process, MapBufferFlags flags, hw::tegra_x1::gpu::NvKind kind, - handle_id_t nvmap_handle_id, + Handle nvmap_handle, [[maybe_unused]] u32 reserved, u64 buffer_offset, u64 mapping_size, InOutSingle inout_addr) { @@ -63,18 +63,22 @@ NvResult NvHostAsGpu::MapBufferEX(System* system, kernel::Process* process, return NvResult::Success; } - const auto& map = system->GetGpu().GetMap(nvmap_handle_id); + ZTD_ASSIGN_OR( + const auto map, system->GetGpu().GetMap(nvmap_handle), ZTD_PASS({ + LOG_WARN(Services, "Invalid nvmap handle {}", nvmap_handle); + return NvResult::BadParameter; /* TODO: correct? */ + })); 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 b2e7d65a4..d30159318 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; @@ -55,9 +55,9 @@ class NvHostAsGpu : public FdBase { NvResult UnmapBuffer(gpu_vaddr_t addr); NvResult MapBufferEX(System* system, kernel::Process* process, MapBufferFlags flags, hw::tegra_x1::gpu::NvKind kind, - handle_id_t nvmap_handle_id, - [[maybe_unused]] u32 reserved, u64 buffer_offset, - u64 mapping_size, InOutSingle inout_addr); + Handle nvmap_handle, [[maybe_unused]] u32 reserved, + u64 buffer_offset, u64 mapping_size, + InOutSingle inout_addr); NvResult GetVaRegions(gpu_vaddr_t buffer_addr, InOutSingle inout_buffer_size, [[maybe_unused]] u32 reserved, diff --git a/src/core/horizon/services/nvdrv/ioctl/nvhost_ctrl_gpu.hpp b/src/core/horizon/services/nvdrv/ioctl/nvhost_ctrl_gpu.hpp index 193e3ba3e..c6f485297 100644 --- a/src/core/horizon/services/nvdrv/ioctl/nvhost_ctrl_gpu.hpp +++ b/src/core/horizon/services/nvdrv/ioctl/nvhost_ctrl_gpu.hpp @@ -98,7 +98,7 @@ class NvHostCtrlGpu : public FdBase { GpuCharacteristics out_characteristics; const auto res = GetCharacteristics(inout_buffer_size, buffer_addr, &out_characteristics); - ctx->out_buffer_stream->Write(out_characteristics); + ctx->out_buffer_stream->write(out_characteristics); return res; } NvResult GetTpcMasks3(IoctlContext* ctx, u32 mask_buffer_size, @@ -106,7 +106,7 @@ class NvHostCtrlGpu : public FdBase { u64 out_mask_buffer; const auto res = GetTpcMasks(mask_buffer_size, reserved, &out_mask_buffer); - ctx->out_buffer_stream->Write(out_mask_buffer); + ctx->out_buffer_stream->write(out_mask_buffer); return res; } }; diff --git a/src/core/horizon/services/nvdrv/ioctl/nvhost_gpu.hpp b/src/core/horizon/services/nvdrv/ioctl/nvhost_gpu.hpp index 525ff7bad..c27a26c5c 100644 --- a/src/core/horizon/services/nvdrv/ioctl/nvhost_gpu.hpp +++ b/src/core/horizon/services/nvdrv/ioctl/nvhost_gpu.hpp @@ -53,7 +53,7 @@ class NvHostGpu : public ChannelBase { return SubmitGpfifo( system, process, gpfifo, num_entries, inout_flags_and_detailed_error, inout_fence, - ctx->in_buffer_stream->ReadPtr()); + ctx->in_buffer_stream->readPtr()); } }; diff --git a/src/core/horizon/services/nvdrv/ioctl/nvmap.cpp b/src/core/horizon/services/nvdrv/ioctl/nvmap.cpp index a43aa3c0b..b4d24585e 100644 --- a/src/core/horizon/services/nvdrv/ioctl/nvmap.cpp +++ b/src/core/horizon/services/nvdrv/ioctl/nvmap.cpp @@ -9,47 +9,47 @@ DEFINE_IOCTL_TABLE(NvMap, FromId, 0x04, Alloc, 0x05, Free, 0x09, Param, 0x0e, GetId)) -NvResult NvMap::Create(System* system, u32 size, handle_id_t* out_handle_id) { - *out_handle_id = system->GetGpu().CreateMap(size); +NvResult NvMap::Create(System* system, u32 size, Handle* out_handle) { + *out_handle = system->GetGpu().CreateMap(size).GetRaw(); return NvResult::Success; } -NvResult NvMap::FromId(u32 id, handle_id_t* out_handle_id) { +NvResult NvMap::FromId(u32 id, Handle* out_handle) { // Handle and ID are the same - *out_handle_id = id; + *out_handle = id; return NvResult::Success; } // TODO: heap mask, kind -NvResult NvMap::Alloc(System* system, handle_id_t handle_id, u32 heap_mask, - u32 flags, InOutSingle inout_alignment, - Aligned kind, gpu_vaddr_t addr) { +NvResult NvMap::Alloc(System* system, Handle handle, u32 heap_mask, u32 flags, + InOutSingle inout_alignment, Aligned kind, + gpu_vaddr_t addr) { (void)heap_mask; (void)kind; // TODO: flags? - system->GetGpu().AllocateMap(handle_id, addr, flags == 1); + system->GetGpu().AllocateMap(handle, addr, flags == 1); inout_alignment = hw::tegra_x1::gpu::GPU_PAGE_SIZE; // TODO: correct? return NvResult::Success; } -NvResult NvMap::Free(System* system, Aligned handle_id, +NvResult NvMap::Free(System* system, Aligned handle, gpu_vaddr_t* out_addr, u64* out_size, u32* out_flags) { - auto map = system->GetGpu().GetMap(handle_id); - system->GetGpu().FreeMap(handle_id); + auto map = system->GetGpu().GetMap(handle).value(); + system->GetGpu().FreeMap(handle); - *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); +NvResult NvMap::Param(System* system, Handle handle, NvMapParamType type, + u32* out_value) { + auto map = system->GetGpu().GetMap(handle).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? @@ -74,9 +74,9 @@ NvResult NvMap::Param(System* system, handle_id_t handle_id, return NvResult::Success; } -NvResult NvMap::GetId(u32* out_id, handle_id_t handle_id) { +NvResult NvMap::GetId(u32* out_id, Handle handle) { // Handle and ID are the same - *out_id = handle_id; + *out_id = handle.GetRaw(); return NvResult::Success; } diff --git a/src/core/horizon/services/nvdrv/ioctl/nvmap.hpp b/src/core/horizon/services/nvdrv/ioctl/nvmap.hpp index 9f6bcd3b1..766ddbd1d 100644 --- a/src/core/horizon/services/nvdrv/ioctl/nvmap.hpp +++ b/src/core/horizon/services/nvdrv/ioctl/nvmap.hpp @@ -20,16 +20,16 @@ class NvMap : public FdBase { private: // Ioctls - NvResult Create(System* system, u32 size, handle_id_t* out_handle_id); - NvResult FromId(u32 id, handle_id_t* out_handle_id); - NvResult Alloc(System* system, handle_id_t handle_id, u32 heap_mask, - u32 flags, InOutSingle inout_alignment, - Aligned kind, gpu_vaddr_t addr); - NvResult Free(System* system, Aligned handle_id, + NvResult Create(System* system, u32 size, Handle* out_handle); + NvResult FromId(u32 id, Handle* out_handle); + NvResult Alloc(System* system, Handle handle, u32 heap_mask, u32 flags, + InOutSingle inout_alignment, Aligned kind, + gpu_vaddr_t addr); + NvResult Free(System* system, Aligned handle, gpu_vaddr_t* out_addr, u64* out_size, u32* out_flags); - NvResult Param(System* system, handle_id_t handle_id, NvMapParamType type, + NvResult Param(System* system, Handle handle, NvMapParamType type, u32* out_value); - NvResult GetId(u32* out_id, handle_id_t handle_id); + NvResult GetId(u32* out_id, Handle handle); }; } // namespace hydra::horizon::services::nvdrv::ioctl diff --git a/src/core/horizon/services/nvdrv/nvdrv_services.cpp b/src/core/horizon/services/nvdrv/nvdrv_services.cpp index e02cdaeac..b4fea4a0f 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, @@ -26,58 +24,69 @@ 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(); + auto path = path_buffer.stream->readNullTerminatedString(); + Handle fd_handle; if (path == "/dev/nvhost-ctrl") { - fd_pool.Get(fd_id) = new ioctl::NvHostCtrl(); + fd_handle = + fd_pool.Insert(std::make_unique()).value(); } else if (path == "/dev/nvmap") { - fd_pool.Get(fd_id) = new ioctl::NvMap(); + fd_handle = fd_pool.Insert(std::make_unique()).value(); } else if (path == "/dev/nvhost-as-gpu") { - fd_pool.Get(fd_id) = new ioctl::NvHostAsGpu(); + fd_handle = + fd_pool.Insert(std::make_unique()).value(); } else if (path == "/dev/nvhost-ctrl-gpu") { - fd_pool.Get(fd_id) = new ioctl::NvHostCtrlGpu(); + fd_handle = + fd_pool.Insert(std::make_unique()).value(); } else if (path == "/dev/nvhost-gpu") { - fd_pool.Get(fd_id) = new ioctl::NvHostGpu(); + fd_handle = + fd_pool.Insert(std::make_unique()).value(); } else if (path == "/dev/nvhost-nvdec") { - fd_pool.Get(fd_id) = new ioctl::NvHostNvDec(); + fd_handle = + fd_pool.Insert(std::make_unique()).value(); } else if (path == "/dev/nvsched-ctrl") { - fd_pool.Get(fd_id) = new ioctl::NvSchedCtrl(); + fd_handle = + fd_pool.Insert(std::make_unique()).value(); } else if (path == "/dev/nvdisp-ctrl") { - fd_pool.Get(fd_id) = new ioctl::NvDispCtrl(); + fd_handle = + fd_pool.Insert(std::make_unique()).value(); } else if (path == "/dev/nvdisp-disp0") { - fd_pool.Get(fd_id) = new ioctl::NvDispDisp(0); + fd_handle = + fd_pool.Insert(std::make_unique(0)).value(); } else if (path == "/dev/nvdisp-disp1") { - fd_pool.Get(fd_id) = new ioctl::NvDispDisp(1); + fd_handle = + fd_pool.Insert(std::make_unique(1)).value(); } else if (path == "/dev/nvhost-vic") { - fd_pool.Get(fd_id) = new ioctl::NvHostVic(); + fd_handle = + fd_pool.Insert(std::make_unique()).value(); } else if (path == "/dev/nvhost-nvjpg") { - fd_pool.Get(fd_id) = new ioctl::NvHostNvJpg(); + fd_handle = + fd_pool.Insert(std::make_unique()).value(); } else { LOG_WARN(Services, "Unknown path \"{}\"", path); *out_error = MAKE_RESULT(Svc, 0); // TODO return MAKE_RESULT(Svc, 0); // TODO } - *out_fd_id = fd_id; + *out_fd_id = fd_handle.GetRaw(); *out_error = 0; return RESULT_SUCCESS; } result_t INvDrvServices::Ioctl(System* system, kernel::Process* process, - handle_id_t fd_id, u32 code, + Handle fd_handle, u32 code, InBuffer in_buffer, NvResult* out_result, OutBuffer out_buffer) { - return IoctlImpl(&ioctl::FdBase::Ioctl, *system, process, fd_id, code, + return IoctlImpl(&ioctl::FdBase::Ioctl, *system, process, fd_handle, code, in_buffer.stream, std::nullopt, out_buffer.stream, std::nullopt, out_result); } -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); +result_t INvDrvServices::Close(u32 fd_handle, u32* out_err) { + if (!fd_pool.Free(fd_handle)) { + // TODO: what to do? + return MAKE_RESULT(Svc, 4); + } *out_err = 0; return RESULT_SUCCESS; @@ -94,14 +103,15 @@ result_t INvDrvServices::Initialize(u32 transfer_mem_size, return RESULT_SUCCESS; } -result_t INvDrvServices::QueryEvent(kernel::Process* process, handle_id_t fd_id, +result_t INvDrvServices::QueryEvent(kernel::Process* process, Handle fd_handle, 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_handle), + 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; @@ -116,23 +126,23 @@ result_t INvDrvServices::QueryEvent(kernel::Process* process, handle_id_t fd_id, } result_t INvDrvServices::Ioctl2(System* system, kernel::Process* process, - handle_id_t fd_id, u32 code, + Handle fd_handle, u32 code, InBuffer in_buffer1, InBuffer in_buffer2, NvResult* out_result, OutBuffer out_buffer) { - return IoctlImpl(&ioctl::FdBase::Ioctl2, *system, process, fd_id, code, + return IoctlImpl(&ioctl::FdBase::Ioctl2, *system, process, fd_handle, code, in_buffer1.stream, in_buffer2.stream, out_buffer.stream, std::nullopt, out_result); } result_t INvDrvServices::Ioctl3(System* system, kernel::Process* process, - handle_id_t fd_id, u32 code, + Handle fd_handle, u32 code, InBuffer in_buffer, NvResult* out_result, OutBuffer out_buffer1, OutBuffer out_buffer2) { - return IoctlImpl(&ioctl::FdBase::Ioctl3, *system, process, fd_id, code, + return IoctlImpl(&ioctl::FdBase::Ioctl3, *system, process, fd_handle, code, in_buffer.stream, std::nullopt, out_buffer1.stream, out_buffer2.stream, out_result); } @@ -140,12 +150,14 @@ result_t INvDrvServices::Ioctl3(System* system, kernel::Process* process, result_t INvDrvServices::IoctlImpl( NvResult (ioctl::FdBase::*func)(ioctl::IoctlContext& context, u32 type, u32 nr), - System& system, kernel::Process* process, handle_id_t fd_id, u32 code, - std::optional in_stream, - std::optional in_buffer_stream, - std::optional out_stream, - std::optional out_buffer_stream, NvResult* out_result) { - auto fd = fd_pool.Get(fd_id); + System& system, kernel::Process* process, Handle fd_handle, u32 code, + std::optional in_stream, + std::optional in_buffer_stream, + std::optional out_stream, + std::optional out_buffer_stream, + NvResult* out_result) { + ZTD_ASSIGN_OR_RETURN_VALUE(auto fd, fd_pool.Get(fd_handle), + MAKE_RESULT(Svc, 4)); // TODO: result // Dispatch u32 type = (code >> 8) & 0xff; @@ -159,7 +171,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 51bfd885f..8d4d53184 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,27 +15,27 @@ class INvDrvServices : public IService { private: // TODO: what should be the max number of fds? - static StaticPool fd_pool; + StaticHandlePool, MAX_FD_COUNT> fd_pool; // Commands result_t Open(InBuffer path_buffer, u32* out_fd_id, u32* out_error); - result_t Ioctl(System* system, kernel::Process* process, handle_id_t fd_id, + result_t Ioctl(System* system, kernel::Process* process, Handle fd_id, u32 code, InBuffer in_buffer, NvResult* out_result, OutBuffer out_buffer); result_t Close(u32 fd_id, u32* out_err); result_t Initialize(u32 transfer_mem_size, NvResult* out_result); - result_t QueryEvent(kernel::Process* process, handle_id_t fd_id, - u32 event_id, NvResult* out_result, + result_t QueryEvent(kernel::Process* process, Handle fd_id, u32 event_id, + NvResult* out_result, OutHandle out_handle); STUB_REQUEST_COMMAND(SetAruid); - result_t Ioctl2(System* system, kernel::Process* process, handle_id_t fd_id, + result_t Ioctl2(System* system, kernel::Process* process, Handle fd_id, u32 code, InBuffer in_buffer1, InBuffer in_buffer2, NvResult* out_result, OutBuffer out_buffer); - result_t Ioctl3(System* system, kernel::Process* process, handle_id_t fd_id, + result_t Ioctl3(System* system, kernel::Process* process, Handle fd_id, u32 code, InBuffer in_buffer, NvResult* out_result, OutBuffer out_buffer1, @@ -49,11 +45,11 @@ class INvDrvServices : public IService { result_t IoctlImpl(NvResult (ioctl::FdBase::*func)(ioctl::IoctlContext& context, u32 type, u32 nr), - System& system, kernel::Process* process, handle_id_t fd_id, - u32 code, std::optional in_stream, - std::optional in_buffer_stream, - std::optional out_stream, - std::optional out_buffer_stream, + System& system, kernel::Process* process, Handle fd_id, u32 code, + std::optional in_stream, + std::optional in_buffer_stream, + std::optional out_stream, + std::optional out_buffer_stream, NvResult* out_result); }; diff --git a/src/core/horizon/services/pl/const.hpp b/src/core/horizon/services/pl/const.hpp index 3df2ccc31..7e00437b8 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/pl/internal/shared_font_manager.cpp b/src/core/horizon/services/pl/internal/shared_font_manager.cpp index d589527d5..c102e271a 100644 --- a/src/core/horizon/services/pl/internal/shared_font_manager.cpp +++ b/src/core/horizon/services/pl/internal/shared_font_manager.cpp @@ -79,19 +79,20 @@ filesystem::IFile* GetSharedFontFile(filesystem::Filesystem& filesystem, constexpr u32 BFTTF_MAGIC = 0x18029a7f; constexpr u32 FONT_KEY = 0x06186249; -result_t DecryptBFTTF(io::IStream* in_stream, io::IStream* out_stream) { +result_t DecryptBFTTF(ztd::io::IStream* in_stream, + ztd::io::IStream* out_stream) { #define KEY_XOR(x) (x ^ FONT_KEY) - const auto magic = KEY_XOR(in_stream->Read()); + const auto magic = KEY_XOR(in_stream->read()); if (magic != BFTTF_MAGIC) { LOG_ERROR(Services, "Invalid BFTTF magic"); return MAKE_RESULT(Svc, 100); // TODO } - in_stream->SeekBy(4); + in_stream->seekBy(4); - for (u32 i = 0; i < (in_stream->GetSize() - 8) / sizeof(u32); i++) - out_stream->Write(KEY_XOR(in_stream->Read())); + for (u32 i = 0; i < (in_stream->getSize() - 8) / sizeof(u32); i++) + out_stream->write(KEY_XOR(in_stream->read())); #undef KEY_XOR @@ -120,7 +121,7 @@ void SharedFontManager::LoadFont(const SharedFontType type) { // Load auto stream = file->Open(filesystem::FileOpenFlags::Read); - io::MemoryStream out_stream(std::span( + ztd::io::MemoryStream out_stream(std::span( reinterpret_cast(shared_memory->GetPtr()) + shared_memory_offset, SHARED_MEMORY_SIZE - shared_memory_offset)); const auto res = DecryptBFTTF(stream, &out_stream); diff --git a/src/core/horizon/services/pl/shared_font_manager.cpp b/src/core/horizon/services/pl/shared_font_manager.cpp index 89b6ffbe0..c1a963e97 100644 --- a/src/core/horizon/services/pl/shared_font_manager.cpp +++ b/src/core/horizon/services/pl/shared_font_manager.cpp @@ -58,9 +58,9 @@ result_t ISharedFontManager::GetSharedFontInOrderOfPriority( type <= SharedFontType::NintendoExtended; type++) { const auto& state = system->GetOS().GetSharedFontManager().GetState(type); - out_types_buffer.stream->Write(type); - out_offsets_buffer.stream->Write(state.shared_memory_offset); - out_sizes_buffer.stream->Write(static_cast(state.size)); + out_types_buffer.stream->write(type); + out_offsets_buffer.stream->write(state.shared_memory_offset); + out_sizes_buffer.stream->write(static_cast(state.size)); (*out_loaded)++; (*out_count)++; diff --git a/src/core/horizon/services/psm/psm_session.cpp b/src/core/horizon/services/psm/psm_session.cpp index 3b64231d9..98231b809 100644 --- a/src/core/horizon/services/psm/psm_session.cpp +++ b/src/core/horizon/services/psm/psm_session.cpp @@ -15,15 +15,15 @@ DEFINE_SERVICE_COMMAND_TABLE(IPsmSession, 0, BindStateChangeEvent, 1, result_t IPsmSession::BindStateChangeEvent(kernel::Process* process, OutHandle out_handle) { - event_handle_id = process->AddHandle( + event_handle = process->AddHandle( new kernel::Event(false, "IPsmSession state change event")); - out_handle = event_handle_id; + out_handle = event_handle; return RESULT_SUCCESS; } result_t IPsmSession::UnbindStateChangeEvent(kernel::Process* process) { - process->FreeHandle(event_handle_id); - event_handle_id = INVALID_HANDLE_ID; + process->FreeHandle(event_handle); + event_handle = INVALID_HANDLE; return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/psm/psm_session.hpp b/src/core/horizon/services/psm/psm_session.hpp index da8efaa0d..9c825eecf 100644 --- a/src/core/horizon/services/psm/psm_session.hpp +++ b/src/core/horizon/services/psm/psm_session.hpp @@ -10,8 +10,8 @@ class IPsmSession : public IService { u32 id) override; private: - handle_id_t event_handle_id{ - INVALID_HANDLE_ID}; // TODO: storing the handle ID is definitely wrong + Handle event_handle{ + INVALID_HANDLE}; // TODO: storing the handle ID is definitely wrong bool signal_on_charger_type_change{false}; bool signal_on_power_supply_change{false}; diff --git a/src/core/horizon/services/ro/detail/ro_interface.cpp b/src/core/horizon/services/ro/detail/ro_interface.cpp index 7f25e8998..fbc50a5f3 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 320c2b1ac..2c7ce5748 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.cpp b/src/core/horizon/services/service.cpp index 73ae84aca..7dd64cab4 100644 --- a/src/core/horizon/services/service.cpp +++ b/src/core/horizon/services/service.cpp @@ -81,11 +81,11 @@ void IService::HandleRequest(System& system, kernel::Process* caller_process, if (should_respond) { // HIPC header #define GET_ARRAY_SIZE(stream) \ - static_cast(align(streams.stream.GetSeek(), 4ull) / sizeof(u32)) + static_cast(align(streams.stream.getSeek(), 4ull) / sizeof(u32)) #define WRITE_ARRAY(stream, ptr) \ if (ptr) { \ - memcpy(ptr, streams.stream.GetPtr(), streams.stream.GetSeek()); \ + memcpy(ptr, streams.stream.getPtr(), streams.stream.getSeek()); \ } kernel::hipc::Metadata meta{ @@ -107,10 +107,10 @@ void IService::HandleRequest(System& system, kernel::Process* caller_process, // works? data_start = AlignPtr(data_start, 0x10); WRITE_ARRAY(out_stream, data_start); - if (streams.out_objects_stream.GetSeek() != 0) { + if (streams.out_objects_stream.getSeek() != 0) { memcpy(data_start + GET_ARRAY_SIZE(out_stream) * sizeof(u32), - streams.out_objects_stream.GetPtr(), - streams.out_objects_stream.GetSeek()); + streams.out_objects_stream.getPtr(), + streams.out_objects_stream.getSeek()); } WRITE_ARRAY(out_copy_handles_stream, response.copy_handles); WRITE_ARRAY(out_move_handles_stream, response.move_handles); @@ -127,8 +127,8 @@ void IService::AddService(RequestContext& context, IService* service) { service->is_domain = true; service->parent = parent; - const auto handle_id = AddSubservice(service); - context.streams.out_objects_stream.Write(handle_id); + const auto handle = AddSubservice(service); + context.streams.out_objects_stream.write(handle); } else { // Create new session auto server_session = new kernel::hipc::ServerSession(); @@ -139,18 +139,17 @@ void IService::AddService(RequestContext& context, IService* service) { server->RegisterSession(server_session, service); // Register client side - const auto handle_id = - context.process->AddHandleNoRetain(client_session); - context.streams.out_move_handles_stream.Write(handle_id); + const auto handle = context.process->AddHandleNoRetain(client_session); + context.streams.out_move_handles_stream.write(handle); } } -IService* IService::GetService(RequestContext& context, handle_id_t handle_id) { +IService* IService::GetService(RequestContext& context, Handle handle) { if (is_domain) { - return GetSubservice(handle_id); + return GetSubservice(handle); } else { return server->GetServiceForSession( - context.process->GetHandle(handle_id) + context.process->GetHandle(handle) ->GetParent() ->GetServerSide()); } @@ -165,16 +164,16 @@ void IService::Request(RequestContext& context) { if (is_domain) { // Domain in auto cmif_in = context.streams.in_stream - .Read(); + .read(); // LOG_DEBUG(Services, "Object ID: 0x{:08x}", cmif_in.object_id); auto subservice = GetSubservice(cmif_in.object_id); if (cmif_in.num_in_objects != 0) { - auto objects = context.streams.in_stream.GetPtr() + - context.streams.in_stream.GetSeek() + + auto objects = context.streams.in_stream.getPtr() + + context.streams.in_stream.getSeek() + cmif_in.data_size; - context.streams.in_objects_stream.emplace(std::span( - objects, cmif_in.num_in_objects * sizeof(handle_id_t))); + context.streams.in_objects_stream.emplace( + std::span(objects, cmif_in.num_in_objects * sizeof(Handle))); } kernel::hipc::cmif::write_domain_out_header(context.streams.out_stream); @@ -199,7 +198,7 @@ void IService::Request(RequestContext& context) { void IService::CmifRequest(RequestContext& context) { auto cmif_in = - context.streams.in_stream.Read(); + context.streams.in_stream.read(); ASSERT_DEBUG(cmif_in.magic == kernel::hipc::cmif::IN_HEADER_MAGIC, Services, "Invalid CMIF in magic 0x{:08x}", cmif_in.magic); @@ -210,7 +209,7 @@ void IService::CmifRequest(RequestContext& context) { void IService::Control(RequestContext& context) { auto cmif_in = - context.streams.in_stream.Read(); + context.streams.in_stream.read(); ASSERT_DEBUG(cmif_in.magic == kernel::hipc::cmif::IN_HEADER_MAGIC, Kernel, "Invalid CMIF in magic 0x{:08x}", cmif_in.magic); @@ -224,8 +223,8 @@ void IService::Control(RequestContext& context) { case kernel::hipc::cmif::ControlCommandType::ConvertCurrentObjectToDomain: { is_domain = true; subservice_pool.emplace(); - const auto handle_id = AddSubservice(this->Retain()); - context.streams.out_stream.Write(handle_id); + const auto handle = AddSubservice(this->Retain()); + context.streams.out_stream.write(handle); *result = RESULT_SUCCESS; break; } @@ -235,7 +234,7 @@ void IService::Control(RequestContext& context) { break; case kernel::hipc::cmif::ControlCommandType::QueryPointerBufferSize: // TODO: let the server specify this - context.streams.out_stream.Write( + context.streams.out_stream.write( 0x8000); // The highest known pointer buffer // size (used by nvservices) *result = RESULT_SUCCESS; @@ -261,15 +260,15 @@ void IService::Clone(RequestContext& context) { server->RegisterSession(server_session, this); // Register client side - const auto handle_id = context.process->AddHandleNoRetain(client_session); - context.streams.out_move_handles_stream.Write(handle_id); + const auto handle = context.process->AddHandleNoRetain(client_session); + context.streams.out_move_handles_stream.write(handle); } void IService::TipcRequest(RequestContext& context, const u32 command_id) { ASSERT_DEBUG(!is_domain, Kernel, "TIPC is not supported for domain services"); const auto result = RequestImpl(context, command_id); - context.streams.out_stream.Write(result); + context.streams.out_stream.write(result); } } // namespace hydra::horizon::services diff --git a/src/core/horizon/services/service.hpp b/src/core/horizon/services/service.hpp index fb6c44696..a103a8eb7 100644 --- a/src/core/horizon/services/service.hpp +++ b/src/core/horizon/services/service.hpp @@ -1,5 +1,6 @@ #pragma once +#include "core/horizon/handle_pool.hpp" #include "core/horizon/kernel/hipc/const.hpp" namespace hydra { @@ -28,13 +29,13 @@ 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); void AddService(RequestContext& context, IService* service); - IService* GetService(RequestContext& context, handle_id_t handle_id); + IService* GetService(RequestContext& context, Handle handle); // Reference counting IService* Retain() { @@ -49,20 +50,21 @@ class IService { protected: virtual result_t RequestImpl(RequestContext& context, u32 id) = 0; - u32 AddSubservice(IService* service) { + Handle AddSubservice(IService* service) { if (service == nullptr) - return INVALID_HANDLE_ID; + return INVALID_HANDLE; - return parent->subservice_pool->Insert(service); + return parent->subservice_pool->Insert(service).value(); } - void FreeSubservice(handle_id_t handle_id) { - parent->subservice_pool->Get(handle_id)->Release(); - parent->subservice_pool->Free(handle_id); + void FreeSubservice(Handle handle) { + parent->subservice_pool->Get(handle).value()->Release(); + ASSERT_DEBUG(parent->subservice_pool->Free(handle), Services, + "Failed to free subservice"); } - IService* GetSubservice(handle_id_t handle_id) const { - return parent->subservice_pool->Get(handle_id); + IService* GetSubservice(Handle handle) const { + return parent->subservice_pool->Get(handle).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/settings_server.cpp b/src/core/horizon/services/settings/settings_server.cpp index 27d4d30fb..bc96d678e 100644 --- a/src/core/horizon/services/settings/settings_server.cpp +++ b/src/core/horizon/services/settings/settings_server.cpp @@ -16,7 +16,7 @@ result_t ISettingsServer::GetLanguageCode(LanguageCode* out_language_code) { result_t ISettingsServer::GetAvailableLanguageCodes( i32* out_count, OutBuffer out_buffer) { - out_buffer.stream->WriteSpan( + out_buffer.stream->writeSpan( std::span(available_languages, sizeof_array(available_languages))); *out_count = sizeof_array(available_languages); return RESULT_SUCCESS; @@ -35,7 +35,7 @@ result_t ISettingsServer::GetRegionCode(RegionCode* out_code) { result_t ISettingsServer::GetAvailableLanguageCodes2( i32* out_count, OutBuffer out_buffer) { - out_buffer.stream->WriteSpan( + out_buffer.stream->writeSpan( std::span(available_languages, sizeof_array(available_languages))); *out_count = sizeof_array(available_languages); return RESULT_SUCCESS; @@ -47,7 +47,7 @@ ISettingsServer::GetDeviceNickName(OutBuffer out_buffer) { std::memset(nickname.name, 0, sizeof_array(nickname.name)); std::memcpy(nickname.name, CONFIG_INSTANCE.GetDeviceNickname().data(), CONFIG_INSTANCE.GetDeviceNickname().size()); - out_buffer.stream->Write(nickname); + out_buffer.stream->write(nickname); return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/settings/system_settings_server.cpp b/src/core/horizon/services/settings/system_settings_server.cpp index 9c3902a97..07372099a 100644 --- a/src/core/horizon/services/settings/system_settings_server.cpp +++ b/src/core/horizon/services/settings/system_settings_server.cpp @@ -20,13 +20,13 @@ result_t ISystemSettingsServer::GetFirmwareVersion( firmware_version.revision_major = 0; firmware_version.revision_minor = 0; - out_buffer.stream->Write(firmware_version); + out_buffer.stream->write(firmware_version); return RESULT_SUCCESS; } result_t ISystemSettingsServer::GetFirmwareVersion2( OutBuffer out_buffer) { - out_buffer.stream->Write(FIRMWARE_VERSION); + out_buffer.stream->write(FIRMWARE_VERSION); return RESULT_SUCCESS; } @@ -39,8 +39,8 @@ result_t ISystemSettingsServer::GetColorSetId(ColorSetId* out_id) { result_t ISystemSettingsServer::GetSettingsItemValueSize( InBuffer in_name_buffer, InBuffer in_item_key_buffer, u64* out_size) { - auto name = in_name_buffer.stream->ReadNullTerminatedString(); - auto item_key = in_item_key_buffer.stream->ReadNullTerminatedString(); + auto name = in_name_buffer.stream->readNullTerminatedString(); + auto item_key = in_item_key_buffer.stream->readNullTerminatedString(); const auto* value = GetSettingsValue(name, item_key); if (value == nullptr) { // TODO: error @@ -66,8 +66,8 @@ result_t ISystemSettingsServer::GetSettingsItemValue( InBuffer in_name_buffer, InBuffer in_item_key_buffer, u64* out_size, OutBuffer out_buffer) { - auto name = in_name_buffer.stream->ReadNullTerminatedString(); - auto item_key = in_item_key_buffer.stream->ReadNullTerminatedString(); + auto name = in_name_buffer.stream->readNullTerminatedString(); + auto item_key = in_item_key_buffer.stream->readNullTerminatedString(); const auto* value = GetSettingsValue(name, item_key); if (value == nullptr) { // TODO: error @@ -76,15 +76,15 @@ result_t ISystemSettingsServer::GetSettingsItemValue( switch (value->type) { case settings::SettingDataType::String: - out_buffer.stream->WriteSpan(std::span(value->s)); + out_buffer.stream->writeSpan(std::span(value->s)); *out_size = value->s.size(); break; case settings::SettingDataType::Integer: - out_buffer.stream->Write(value->i); + out_buffer.stream->write(value->i); *out_size = sizeof(value->i); break; case settings::SettingDataType::Boolean: - out_buffer.stream->Write(value->b); + out_buffer.stream->write(value->b); *out_size = sizeof(value->b); break; } @@ -125,7 +125,7 @@ result_t ISystemSettingsServer::GetDebugModeFlag(bool* out_flag) { result_t ISystemSettingsServer::GetDeviceNickName( OutBuffer out_buffer) { // TODO: make this configurable - out_buffer.stream->Write({ + out_buffer.stream->write({ .name = "Hydra device", }); return RESULT_SUCCESS; diff --git a/src/core/horizon/services/settings/system_settings_server.hpp b/src/core/horizon/services/settings/system_settings_server.hpp index 80f9a8db9..8dc6bd15e 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/horizon/services/spl/random_interface.cpp b/src/core/horizon/services/spl/random_interface.cpp index 4825c86aa..a09d00409 100644 --- a/src/core/horizon/services/spl/random_interface.cpp +++ b/src/core/horizon/services/spl/random_interface.cpp @@ -7,8 +7,8 @@ DEFINE_SERVICE_COMMAND_TABLE(IRandomInterface, 0, GenerateRandomBytes) result_t IRandomInterface::GenerateRandomBytes( OutBuffer out_buffer) { // TODO: use a proper random number generator - for (u32 i = 0; i < out_buffer.stream->GetSize(); i++) - out_buffer.stream->Write(static_cast(rand() % 256)); + for (u32 i = 0; i < out_buffer.stream->getSize(); i++) + out_buffer.stream->write(static_cast(rand() % 256)); return RESULT_SUCCESS; } diff --git a/src/core/horizon/services/timesrv/internal/time_zone_manager.cpp b/src/core/horizon/services/timesrv/internal/time_zone_manager.cpp index ece1609ec..5925ef1ba 100644 --- a/src/core/horizon/services/timesrv/internal/time_zone_manager.cpp +++ b/src/core/horizon/services/timesrv/internal/time_zone_manager.cpp @@ -44,8 +44,8 @@ TimeZoneManager::TimeZoneManager(filesystem::Filesystem& filesystem_) const auto stream = list_file->Open(filesystem::FileOpenFlags::Read); char buffer[256]; u32 str_size = 0; - while (stream->GetRemainingSize() != 0u) { - const auto c = stream->Read(); + while (stream->getRemainingSize() != 0u) { + const auto c = stream->read(); switch (c) { case '\n': { std::string_view str(buffer, str_size); diff --git a/src/core/horizon/services/timesrv/internal/tzif.cpp b/src/core/horizon/services/timesrv/internal/tzif.cpp index 86bf39600..cab9daedc 100644 --- a/src/core/horizon/services/timesrv/internal/tzif.cpp +++ b/src/core/horizon/services/timesrv/internal/tzif.cpp @@ -53,12 +53,12 @@ bool TimeTypeEquals(const TimeZoneRule& rule, u8 a_index, u8 b_index) { } // namespace // From Ryujinx -void ParseTimeZoneBinary(io::IStream* stream, TimeZoneRule& out_rule) { - const auto header = stream->Read(); +void ParseTimeZoneBinary(ztd::io::IStream* stream, TimeZoneRule& out_rule) { + const auto header = stream->read(); ASSERT(header.magic == make_magic4('T', 'Z', 'i', 'f'), Services, "Invalid TZif magic {:#x}", header.magic); - u32 data_size = static_cast(stream->GetRemainingSize()); + u32 data_size = static_cast(stream->getRemainingSize()); u32 ttis_gmt_count = Decode(header.ttis_gmt_count); u32 ttis_std_count = Decode(header.ttis_std_count); @@ -86,7 +86,7 @@ void ParseTimeZoneBinary(io::IStream* stream, TimeZoneRule& out_rule) { time_count = 0; for (u32 i = 0; i < out_rule.time_count; i++) { - const auto at = Decode(stream->Read()); + const auto at = Decode(stream->read()); out_rule.type_indices[i] = 1; if (time_count != 0 && at <= out_rule.ats[time_count - 1]) { @@ -102,7 +102,7 @@ void ParseTimeZoneBinary(io::IStream* stream, TimeZoneRule& out_rule) { time_count = 0; for (u32 i = 0; i < out_rule.time_count; i++) { - const auto type_index = stream->Read(); + const auto type_index = stream->read(); ASSERT(type_index < out_rule.type_count, Services, "Invalid type index ({} >= {})", type_index, out_rule.type_count); @@ -115,29 +115,29 @@ void ParseTimeZoneBinary(io::IStream* stream, TimeZoneRule& out_rule) { for (u32 i = 0; i < out_rule.type_count; i++) { TimeTypeInfo& type_info = out_rule.type_infos[i]; - type_info.gmt_offset = Decode(stream->Read()); + type_info.gmt_offset = Decode(stream->read()); - const auto is_day_saving_time = stream->Read(); + const auto is_day_saving_time = stream->read(); ASSERT(is_day_saving_time < 2, Services, "Invalid is day saving time boolean {}", is_day_saving_time); type_info.is_day_saving_time = (is_day_saving_time != 0); - u32 abbreviation_list_index = stream->Read(); + u32 abbreviation_list_index = stream->read(); ASSERT(abbreviation_list_index < TimeZoneRule::MAX_CHAR_COUNT, Services, "Invalid abbreviation list index {}", abbreviation_list_index); type_info.abbreviation_list_index = abbreviation_list_index; } - stream->ReadToSpan(std::span(out_rule.chars, out_rule.char_count)); + stream->readToSpan(std::span(out_rule.chars, out_rule.char_count)); out_rule.chars[out_rule.char_count] = '\0'; for (u32 i = 0; i < out_rule.type_count; i++) { if (ttis_std_count == 0) { out_rule.type_infos[i].is_standard_time_daylight = false; } else { - const auto is_standard_time_daylight = stream->Read(); + const auto is_standard_time_daylight = stream->read(); ASSERT(is_standard_time_daylight < 2, Services, "Invalid is standard time daylight boolean {}", is_standard_time_daylight); @@ -151,19 +151,19 @@ void ParseTimeZoneBinary(io::IStream* stream, TimeZoneRule& out_rule) { if (ttis_std_count == 0) { out_rule.type_infos[i].is_gmt = false; } else { - const auto is_gmt = stream->Read(); + const auto is_gmt = stream->read(); ASSERT(is_gmt < 2, Services, "Invalid is GMT boolean {}", is_gmt); out_rule.type_infos[i].is_gmt = (is_gmt != 0); } } - u32 name_len = static_cast(stream->GetRemainingSize()); + u32 name_len = static_cast(stream->getRemainingSize()); ASSERT(name_len <= (TimeZoneRule::MAX_NAME_LEN + 1), Services, "Invalid name length {}", name_len); char tmp_name[TimeZoneRule::MAX_NAME_LEN + 1]; - stream->ReadToSpan(std::span(tmp_name, name_len)); + stream->readToSpan(std::span(tmp_name, name_len)); if (name_len > 2 && tmp_name[0] == '\n' && tmp_name[name_len - 1] == '\n' && out_rule.type_count + 2 <= TimeZoneRule::MAX_TYPE_COUNT) { diff --git a/src/core/horizon/services/timesrv/internal/tzif.hpp b/src/core/horizon/services/timesrv/internal/tzif.hpp index 57ba3b484..6d1dacb48 100644 --- a/src/core/horizon/services/timesrv/internal/tzif.hpp +++ b/src/core/horizon/services/timesrv/internal/tzif.hpp @@ -4,6 +4,6 @@ namespace hydra::horizon::services::timesrv::internal { -void ParseTimeZoneBinary(io::IStream* stream, TimeZoneRule& out_rule); +void ParseTimeZoneBinary(ztd::io::IStream* stream, TimeZoneRule& out_rule); } // namespace hydra::horizon::services::timesrv::internal diff --git a/src/core/horizon/services/timesrv/time_zone_service.cpp b/src/core/horizon/services/timesrv/time_zone_service.cpp index 91ca746cd..bb7706f49 100644 --- a/src/core/horizon/services/timesrv/time_zone_service.cpp +++ b/src/core/horizon/services/timesrv/time_zone_service.cpp @@ -27,7 +27,7 @@ result_t ITimeZoneService::LoadTimeZoneRule( ctx->system.GetOS().GetTimeManager().GetTimeZoneManager().LoadRule( location_name.name, rule); - out_rule_buffer.stream->Write(rule); + out_rule_buffer.stream->write(rule); return RESULT_SUCCESS; } @@ -36,7 +36,7 @@ ITimeZoneService::ToCalendarTime(i64 posix_time, InBuffer in_rule_buffer, ToCalendarTimeWithMyRuleOut* out) { return ToCalendarTimeImpl(posix_time, - in_rule_buffer.stream->Read(), + in_rule_buffer.stream->read(), out->time, out->additional_info); } @@ -54,10 +54,10 @@ result_t ITimeZoneService::ToPosixTime( i32* out_count, OutBuffer out_buffer) { i64 time; const auto res = ToPosixTimeImpl( - calendar_time, in_rule_buffer.stream->Read(), time); + calendar_time, in_rule_buffer.stream->read(), time); - out_buffer.stream->Write(time); - *out_count = static_cast(out_buffer.stream->GetSeek() / sizeof(i64)); + out_buffer.stream->write(time); + *out_count = static_cast(out_buffer.stream->getSeek() / sizeof(i64)); return res; } @@ -70,8 +70,8 @@ result_t ITimeZoneService::ToPosixTimeWithMyRule( ctx->system.GetOS().GetTimeManager().GetTimeZoneManager().GetMyRule(), time); - out_buffer.stream->Write(time); - *out_count = static_cast(out_buffer.stream->GetSeek() / sizeof(i64)); + out_buffer.stream->write(time); + *out_count = static_cast(out_buffer.stream->getSeek() / sizeof(i64)); return res; } diff --git a/src/core/horizon/services/visrv/application_display_service.cpp b/src/core/horizon/services/visrv/application_display_service.cpp index 30d25f42a..203836e49 100644 --- a/src/core/horizon/services/visrv/application_display_service.cpp +++ b/src/core/horizon/services/visrv/application_display_service.cpp @@ -47,7 +47,7 @@ result_t IApplicationDisplayService::GetRelayService(RequestContext* ctx, "GetRelayService cannot be a domain service"); auto client_session = client_port->Connect(); const auto handle = ctx->process->AddHandle(client_session); - ctx->streams.out_move_handles_stream.Write(handle); + ctx->streams.out_move_handles_stream.write(handle); return RESULT_SUCCESS; } @@ -78,7 +78,7 @@ result_t IApplicationDisplayService::ListDisplays( System* system, u64* out_count, OutBuffer out_display_infos_buffer) { const auto res = system->GetOS().GetDisplayResolution(); - out_display_infos_buffer.stream->Write({ + out_display_infos_buffer.stream->write({ .name = "Default", .has_layer_limit = true, .layer_count_max = 1, @@ -92,19 +92,21 @@ result_t IApplicationDisplayService::ListDisplays( result_t IApplicationDisplayService::OpenDisplay(System* system, DisplayName display_name, u64* out_display_id) { - auto display_id = system->GetOS().GetDisplayDriver().GetDisplayIDFromName( - display_name.name); - auto& display = system->GetOS().GetDisplayDriver().GetDisplay(display_id); + const auto display_handle = + system->GetOS().GetDisplayDriver().GetDisplayIDFromName( + display_name.name); + auto& display = + system->GetOS().GetDisplayDriver().GetDisplay(display_handle); display.Open(); - *out_display_id = display_id; + *out_display_id = display_handle.GetRaw(); return RESULT_SUCCESS; } result_t IApplicationDisplayService::CloseDisplay(System* system, u64 display_id) { auto& display = system->GetOS().GetDisplayDriver().GetDisplay( - static_cast(display_id)); + static_cast(display_id)); display.Close(); return RESULT_SUCCESS; } @@ -114,7 +116,7 @@ result_t IApplicationDisplayService::GetDisplayResolution(System* system, i64* out_width, i64* out_height) { auto& display = system->GetOS().GetDisplayDriver().GetDisplay( - static_cast(display_id)); + static_cast(display_id)); (void)display; // TODO: use the display @@ -141,7 +143,7 @@ result_t IApplicationDisplayService::OpenLayer( // Parcel hosbinder::ParcelWriter parcel_writer(parcel_buffer.stream.value()); - parcel_writer.WriteObject(layer.GetBinderID(), "dispdrv"_u64); + parcel_writer.WriteObject(layer.GetBinderHandle().GetRaw(), "dispdrv"_u64); parcel_writer.Finish(); *out_native_window_size = parcel_writer.GetWrittenSize(); @@ -180,7 +182,7 @@ result_t IApplicationDisplayService::GetDisplayVsyncEvent( System* system, kernel::Process* process, u64 display_id, OutHandle out_handle) { auto& display = system->GetOS().GetDisplayDriver().GetDisplay( - static_cast(display_id)); + static_cast(display_id)); out_handle = process->AddHandle(display.GetVSyncEvent()); return RESULT_SUCCESS; diff --git a/src/core/horizon/services/visrv/display_service_base.cpp b/src/core/horizon/services/visrv/display_service_base.cpp index 6641d7508..471e49100 100644 --- a/src/core/horizon/services/visrv/display_service_base.cpp +++ b/src/core/horizon/services/visrv/display_service_base.cpp @@ -8,20 +8,22 @@ namespace hydra::horizon::services::visrv { result_t DisplayServiceBase::CreateStrayLayerImpl( System& system, kernel::Process* process, u32 flags, u64 display_id, u64* out_layer_id, u64* out_native_window_size, - std::optional out_parcel_stream) { + std::optional out_parcel_stream) { (void)flags; (void)display_id; - u32 binder_id = system.GetOS().GetDisplayDriver().CreateBinder(); + const auto binder_handle = system.GetOS().GetDisplayDriver().CreateBinder(); // TODO: what's the display for? // auto& display = system.GetOS().GetDisplayDriver().GetDisplay(display_id); - *out_layer_id = - system.GetOS().GetDisplayDriver().CreateLayer(process, binder_id); + *out_layer_id = system.GetOS() + .GetDisplayDriver() + .CreateLayer(process, binder_handle) + .GetRaw(); // Parcel hosbinder::ParcelWriter parcel_writer(out_parcel_stream.value()); - parcel_writer.WriteObject(binder_id, "dispdrv"_u64); + parcel_writer.WriteObject(binder_handle.GetRaw(), "dispdrv"_u64); parcel_writer.Finish(); *out_native_window_size = parcel_writer.GetWrittenSize(); diff --git a/src/core/horizon/services/visrv/display_service_base.hpp b/src/core/horizon/services/visrv/display_service_base.hpp index 178695119..890293549 100644 --- a/src/core/horizon/services/visrv/display_service_base.hpp +++ b/src/core/horizon/services/visrv/display_service_base.hpp @@ -7,11 +7,10 @@ namespace hydra::horizon::services::visrv { class DisplayServiceBase : public IService { protected: - result_t - CreateStrayLayerImpl(System& system, kernel::Process* process, u32 flags, - u64 display_id, u64* out_layer_id, - u64* out_native_window_size, - std::optional out_parcel_stream); + result_t CreateStrayLayerImpl( + System& system, kernel::Process* process, u32 flags, u64 display_id, + u64* out_layer_id, u64* out_native_window_size, + std::optional out_parcel_stream); result_t SetLayerVisibilityImpl(u64 layer_id, bool visible); }; diff --git a/src/core/horizon/services/visrv/manager_display_service.cpp b/src/core/horizon/services/visrv/manager_display_service.cpp index b83d56a1c..eebdb388a 100644 --- a/src/core/horizon/services/visrv/manager_display_service.cpp +++ b/src/core/horizon/services/visrv/manager_display_service.cpp @@ -18,13 +18,16 @@ result_t IManagerDisplayService::CreateManagedLayer(System* system, (void)display_id; (void)aruid; - u32 binder_id = system->GetOS().GetDisplayDriver().CreateBinder(); + const auto binder_handle = + system->GetOS().GetDisplayDriver().CreateBinder(); // TODO: what's the display for? // auto& display = // system->GetOS().GetDisplayDriver().GetDisplay(display_id); - *out_layer_id = - system->GetOS().GetDisplayDriver().CreateLayer(process, binder_id); + *out_layer_id = system->GetOS() + .GetDisplayDriver() + .CreateLayer(process, binder_handle) + .GetRaw(); return RESULT_SUCCESS; } diff --git a/src/core/hw/tegra_x1/cpu/dynarmic/mmu.cpp b/src/core/hw/tegra_x1/cpu/dynarmic/mmu.cpp index 1801218b3..d86637dac 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 37d00461c..d9fe653ad 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 8d30e297d..94ac1617e 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 d3fabd813..ea913a6d9 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 bf4cc660a..6327c1d8a 100644 --- a/src/core/hw/tegra_x1/cpu/hypervisor/cpu.cpp +++ b/src/core/hw/tegra_x1/cpu/hypervisor/cpu.cpp @@ -64,7 +64,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}, @@ -83,11 +83,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 712d88d6f..f5e4e526a 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 82da90f7c..7c07c3b95 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 b4be522ef..cc6208c95 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 37d8b7c33..cbe31833a 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 b4873b7c2..6da376014 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 308b6bbc0..0e7d8b5af 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 9aea32a66..22f32c6fa 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 8dff6bc2c..5b76d080e 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 d21443120..7f292852e 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 559c5b5ef..52e11a5f4 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 0db22115e..db4b36fb6 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 282e0d531..9f7136df6 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 9d893c5f5..d6124f7df 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 05bccc76b..3aacc2719 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 fbdf65730..5bead8d4a 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 bcfd8b598..00a878532 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 ae0af09f4..5e7e87143 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 731cdbf4c..db20f72a1 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 f0a8977dd..6fd808b11 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"); @@ -35,10 +35,10 @@ struct SetObjectArg { } // namespace -Gpu::Gpu() +Gpu::Gpu() noexcept : 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 de5015518..43757a59a 100644 --- a/src/core/hw/tegra_x1/gpu/gpu.hpp +++ b/src/core/hw/tegra_x1/gpu/gpu.hpp @@ -9,6 +9,9 @@ #include "core/hw/tegra_x1/gpu/pfifo.hpp" #include "core/hw/tegra_x1/gpu/renderer/renderer.hpp" +// TODO: remove dependency +#include "core/horizon/handle_pool.hpp" + namespace hydra::hw::tegra_x1::cpu { class IMmu; } @@ -34,33 +37,29 @@ inline thread_local renderer::ICommandBuffer* tls_crnt_command_buffer = nullptr; class Gpu { public: - Gpu(); + Gpu() noexcept; + ~Gpu() noexcept = default; + + ZTD_MAKE_NON_COPYABLE(Gpu); + ZTD_MAKE_NON_MOVABLE(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; - } + Handle CreateMap(u64 size) { return memory_maps.Insert(0, size).value(); } - 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; + void AllocateMap(Handle handle, uptr addr, bool write) { + // TODO: error? + ZTD_ASSIGN_OR_RETURN(auto memory_map, memory_maps.Get(handle)); + memory_map->addr = addr; + memory_map->write = write; } - void FreeMap(handle_id_t handle_id) { memory_maps.Free(handle_id); } + void FreeMap(Handle handle) { + ASSERT_DEBUG(memory_maps.Free(handle), Gpu, "Failed to free map {}", + handle); + } - MemoryMap& GetMap(handle_id_t handle_id) { - return memory_maps.Get(handle_id); + std::optional GetMap(Handle handle) { + return memory_maps.Get(handle); } // Engines @@ -105,7 +104,9 @@ class Gpu { std::unique_ptr renderer; // Memory - DynamicPool memory_maps; + // TODO: move to nvmap + // TODO: dynamic pool? + horizon::StaticHandlePool 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 efe0e2b06..111798dbd 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 0c2b4b219..b2c32f840 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 6b994c0fa..34b825e5a 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 e12638fac..5c7e1992e 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 7461d8d93..4496f0117 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 48b8355bd..8aff58534 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 b9944ccb4..0d6ab86c1 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 5974eb829..dc8c6d525 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 a3688b16d..5670ca865 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 dc99c62d9..9cf248f62 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 d9aa1983f..e67f34e1c 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 2e55be3b0..556b55a21 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 78a05af2d..16781a3fe 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 dd9957dd2..c58426f19 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 c817f5872..c495670b6 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 463ac363c..5b56b9e03 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 830f8cb57..a4f9c710d 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 64f710b96..a796fd400 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 0bb5f00a9..83f400fe2 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 4789d017b..29f20d4c2 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 7d516f888..bd4da621e 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 5a9f35dbf..8300d9418 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 67a86f074..44b89d2d2 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 5d459fee1..fd714a1cf 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 ec6ea3ca1..494fd534d 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 a01e4a29b..ea410b4f6 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/shader_cache.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/shader_cache.cpp @@ -12,7 +12,7 @@ ShaderBase* ShaderCache::Create(const GuestShaderDescriptor& descriptor) { host_descriptor.type = engines::to_renderer_shader_type(descriptor.stage); // Decompile - io::MemoryStream code_stream( + ztd::io::MemoryStream code_stream( std::span(reinterpret_cast(descriptor.code_ptr), 0x1000)); // TODO: size shader_decomp::Decompile(code_stream, host_descriptor.type, @@ -24,28 +24,28 @@ 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 - io::MemoryStream code_stream( + ztd::io::MemoryStream code_stream( std::span(reinterpret_cast(descriptor.code_ptr), 0x1000)); // TODO: size - code_stream.SeekBy(80); // Header + code_stream.seekBy(80); // Header for (u32 i = 0; i < 8; i++) { - hash.Add(code_stream.Read()); - code_stream.SeekBy(17); + hash.add(code_stream.read()); + code_stream.seekBy(17); } // Vertex state 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 9225883f9..1669a52d6 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 24ed18b0b..94f593615 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 7ae6ac5bb..487df3ed0 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, ...) \ @@ -42,7 +43,7 @@ namespace hydra::hw::tegra_x1::gpu::renderer::shader_decomp::decoder { struct DecoderContext { const DecompilerContext& decomp_context; - io::IStream* code_stream; + ztd::io::IStream* code_stream; ir::Builder& builder; }; diff --git a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/decoder.cpp b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/decoder.cpp index 895070ca9..c26c88cd5 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/decoder.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/decoder.cpp @@ -31,7 +31,7 @@ void Decoder::Decode() { void Decoder::ParseNextInstruction() { const u32 pc = GetPC(); - const auto inst = context.code_stream->Read(); + const auto inst = context.code_stream->read(); if ((pc % 4) == 0) // Sched return; diff --git a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/decoder.hpp b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/decoder.hpp index f14d4466c..0767a6a29 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/decoder.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decoder/decoder.hpp @@ -34,10 +34,10 @@ class Decoder { // Helpers void Jump(u32 target) const { - context.code_stream->SeekTo(target * sizeof(instruction_t)); + context.code_stream->seekTo(target * sizeof(instruction_t)); } u32 GetPC() const { - return static_cast(context.code_stream->GetSeek() / + return static_cast(context.code_stream->getSeek() / sizeof(instruction_t)); } diff --git a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decompiler.cpp b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decompiler.cpp index d4eb3cf93..ed5402453 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decompiler.cpp +++ b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decompiler.cpp @@ -81,13 +81,13 @@ struct ShaderHeader { }; #pragma pack(pop) -void Decompile(io::MemoryStream& code_stream, const ShaderType type, +void Decompile(ztd::io::MemoryStream& code_stream, const ShaderType type, const GuestShaderState& state, ShaderBackend& out_backend, std::vector& out_code, ResourceMapping& out_resource_mapping) { // Header // TODO: don't read in case of compute shaders - const auto header = code_stream.Read(); + const auto header = code_stream.read(); // HACK: just for testing ASSERT_DEBUG(header.version == 3, ShaderDecompiler, "Invalid shader version {}", header.version); @@ -111,7 +111,7 @@ void Decompile(io::MemoryStream& code_stream, const ShaderType type, ir::Module modul; { ir::Builder builder(modul); - io::StreamView stream(&code_stream, code_stream.GetSeek()); + ztd::io::StreamView stream(&code_stream, code_stream.getSeek()); decoder::Decoder decoder({.decomp_context = context, .code_stream = &stream, .builder = builder}); diff --git a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decompiler.hpp b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decompiler.hpp index 29f143f95..a759653f9 100644 --- a/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decompiler.hpp +++ b/src/core/hw/tegra_x1/gpu/renderer/shader_decompiler/decompiler.hpp @@ -11,7 +11,7 @@ namespace hydra::hw::tegra_x1::gpu::renderer::shader_decomp { class ObserverBase; class BuilderBase; -void Decompile(io::MemoryStream& code_stream, const ShaderType type, +void Decompile(ztd::io::MemoryStream& code_stream, const ShaderType type, const GuestShaderState& state, ShaderBackend& out_backend, std::vector& out_code, ResourceMapping& out_resource_mapping); diff --git a/src/core/hw/tegra_x1/gpu/renderer/texture.hpp b/src/core/hw/tegra_x1/gpu/renderer/texture.hpp index b8981b66b..b64f0566d 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 8f6995f40..a049635d8 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 ac693f053..c3533c924 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 ecb625274..1b42bb232 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 454951356..bcebed705 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 8693fbf86..6e4b4b016 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 7b3671dbe..92202205b 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 5f578c999..a1738f7bc 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 20a473df9..7d9b9e560 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 55b42726f..8aef3a09e 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 d941a6758..ef04eeed3 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 000000000..45221ec6b --- /dev/null +++ b/src/ztd/.clang-tidy @@ -0,0 +1,36 @@ +Checks: > + bugprone-*, + cppcoreguidelines-*, + modernize-*, + performance-*, + readability-*, + + -bugprone-easily-swappable-parameters, + -bugprone-exception-escape, + -bugprone-unchecked-optional-access, + -bugprone-derived-method-shadowing-base-method, + -bugprone-branch-clone, + -bugprone-signed-bitwise, + -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 000000000..eff6609be --- /dev/null +++ b/src/ztd/CMakeLists.txt @@ -0,0 +1,106 @@ +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/fs/directory.cpp + src/ztd/fs/directory.hpp + src/ztd/fs/error.hpp + src/ztd/fs/file.cpp + src/ztd/fs/file.hpp + src/ztd/hash/xxhash32.hpp + src/ztd/io/continuous_stream.hpp + src/ztd/io/file_stream.hpp + src/ztd/io/memory_stream.hpp + src/ztd/io/sparse_stream.hpp + src/ztd/io/stream.hpp + src/ztd/io/stream_view.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/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/static_pool.hpp + src/ztd/builtin.hpp + src/ztd/linked_list.hpp + src/ztd/platform.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/ztd/src/ztd/builtin.hpp b/src/ztd/src/ztd/builtin.hpp new file mode 100644 index 000000000..812d118e5 --- /dev/null +++ b/src/ztd/src/ztd/builtin.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "ztd/platform.hpp" + +namespace ztd::inline builtin { + +[[noreturn]] inline void unreachable() { +#if defined(ZTD_COMPILER_CLANG) && !defined(ZTD_COMPILER_GCC) + __builtin_unreachable(); +#elifdef ZTD_COMPILER_MSVC + __assume(false); +#else +#error "'unreachable' not defined for this compiler" +#endif +} + +} // namespace ztd::inline builtin 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 479214c4d..2f958295f 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 000000000..737227424 --- /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/ztd/src/ztd/fs/directory.cpp b/src/ztd/src/ztd/fs/directory.cpp new file mode 100644 index 000000000..0c247c915 --- /dev/null +++ b/src/ztd/src/ztd/fs/directory.cpp @@ -0,0 +1,68 @@ +#include "ztd/fs/directory.hpp" + +namespace ztd::fs { + +auto Directory::openDirectory(const std::string& rel_path, + OpenFlags flags) const noexcept + -> std::expected { + const auto fd = openat(handle, rel_path.c_str(), getPosixOpenFlags(flags)); + if (fd == -1) + return std::unexpected(getPosixError()); + + return {fd}; +} + +auto Directory::openFile(const std::string& rel_path, + File::OpenFlags flags) const noexcept + -> std::expected { + const auto fd = + openat(handle, rel_path.c_str(), File::getPosixOpenFlags(flags)); + if (fd == -1) + return std::unexpected(getPosixError()); + + return {fd}; +} + +auto Directory::createFile(const std::string& rel_path, + File::CreateFlags flags) const noexcept + -> std::expected { + const auto fd = + openat(handle, rel_path.c_str(), File::getPosixCreateFlags(flags), + 0644); // TODO: what should the permissions be? + if (fd == -1) + return std::unexpected(getPosixError()); + + return {fd}; +} + +auto Directory::getPosixOpenFlags(OpenFlags flags) noexcept -> i32 { + // TODO: O_PATH? + i32 res = O_DIRECTORY | O_RDONLY | O_CLOEXEC; + if (any(flags & OpenFlags::DontFollowSymlinks)) { + res |= O_NOFOLLOW; + } + + return res; +} + +auto openDirectoryAbsolute(const std::string& path, + Directory::OpenFlags flags) noexcept + -> std::expected { + // TODO: verify the path is absolute? + return cwd().openDirectory(path, flags); +} + +auto openFileAbsolute(const std::string& path, File::OpenFlags flags) noexcept + -> std::expected { + // TODO: verify the path is absolute? + return cwd().openFile(path, flags); +} + +auto createFileAbsolute(const std::string& path, + File::CreateFlags flags) noexcept + -> std::expected { + // TODO: verify the path is absolute? + return cwd().createFile(path, flags); +} + +} // namespace ztd::fs diff --git a/src/ztd/src/ztd/fs/directory.hpp b/src/ztd/src/ztd/fs/directory.hpp new file mode 100644 index 000000000..3cfa84012 --- /dev/null +++ b/src/ztd/src/ztd/fs/directory.hpp @@ -0,0 +1,66 @@ +#pragma once + +#include "ztd/fs/file.hpp" + +namespace ztd::fs { + +class Directory { + public: + enum class OpenFlags : u8 { + None = 0, + DontFollowSymlinks = ZTD_BIT(0), + }; + + Directory(i32 handle_) noexcept : handle{handle_} {} + ~Directory() noexcept { + if (handle >= 0) + close(handle); + } + + ZTD_MAKE_NON_COPYABLE(Directory); + ZTD_MAKE_MOVABLE(Directory, handle, std::exchange(other.handle, -1)); + + // TODO: allow std::string_view + [[nodiscard]] auto openDirectory(const std::string& rel_path, + OpenFlags flags) const noexcept + -> std::expected; + + // TODO: allow std::string_view + [[nodiscard]] auto openFile(const std::string& rel_path, + File::OpenFlags flags) const noexcept + -> std::expected; + + // TODO: allow std::string_view + [[nodiscard]] auto createFile(const std::string& rel_path, + File::CreateFlags flags) const noexcept + -> std::expected; + + [[nodiscard]] auto getHandle() const noexcept -> i32 { return handle; } + + private: + i32 handle; + + // Helpers + static auto getPosixOpenFlags(OpenFlags flags) noexcept -> i32; +}; + +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(Directory::OpenFlags); + +[[nodiscard]] constexpr auto cwd() noexcept -> Directory { return {AT_FDCWD}; } + +// TODO: allow std::string_view +[[nodiscard]] auto openDirectoryAbsolute(const std::string& path, + Directory::OpenFlags flags) noexcept + -> std::expected; + +// TODO: allow std::string_view +[[nodiscard]] auto openFileAbsolute(const std::string& path, + File::OpenFlags flags) noexcept + -> std::expected; + +// TODO: allow std::string_view +[[nodiscard]] auto createFileAbsolute(const std::string& path, + File::CreateFlags flags) noexcept + -> std::expected; + +} // namespace ztd::fs diff --git a/src/ztd/src/ztd/fs/error.hpp b/src/ztd/src/ztd/fs/error.hpp new file mode 100644 index 000000000..c98399da8 --- /dev/null +++ b/src/ztd/src/ztd/fs/error.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include +#include +#include + +#include "ztd/builtin.hpp" +#include "ztd/type_aliases.hpp" + +namespace ztd::fs::inline internal { + +enum class Error : u8 { + NotFound, + NotADir, + AlreadyExists, + AccessDenied, + PermissionDenied, + SymLinkLoop, + ProcessFdQuotaExceeded, + SystemFdQuotaExceeded, + // NoDevice, + SystemResources, + // DeviceBusy, +}; + +inline auto getPosixError() noexcept -> Error { + switch (errno) { + case EACCES: + return Error::AccessDenied; + case EROFS: + return Error::AccessDenied; // TODO: correct? + case EPERM: + return Error::PermissionDenied; + case ENOENT: + return Error::NotFound; + case ENOTDIR: + return Error::NotADir; + case EISDIR: + return Error::AccessDenied; // TODO: correct? + case ENAMETOOLONG: + unreachable(); // Prevented by the caller + case ELOOP: + return Error::SymLinkLoop; + case EMFILE: + return Error::ProcessFdQuotaExceeded; + case ENFILE: + return Error::SystemFdQuotaExceeded; + case ENOSPC: + case EDQUOT: + return Error::SystemResources; + case EEXIST: + return Error::AlreadyExists; + default: + // TODO: panic + unreachable(); + } +} + +} // namespace ztd::fs::inline internal diff --git a/src/ztd/src/ztd/fs/file.cpp b/src/ztd/src/ztd/fs/file.cpp new file mode 100644 index 000000000..e1bcc7f81 --- /dev/null +++ b/src/ztd/src/ztd/fs/file.cpp @@ -0,0 +1,47 @@ +#include "ztd/fs/file.hpp" + +namespace ztd::fs { + +auto File::getPosixOpenFlags(OpenFlags flags) noexcept -> i32 { + i32 res = 0; + + // Access mode + if (any(flags & (OpenFlags::Read | OpenFlags::Write))) { + res |= O_RDWR; + } else if (any(flags & OpenFlags::Read)) { + res |= O_RDONLY; + } else if (any(flags & OpenFlags::Write)) { + res |= O_WRONLY; + } + + // Behavior + if (any(flags & OpenFlags::Append)) { + res |= O_APPEND; + } + + return res; +} + +auto File::getPosixCreateFlags(CreateFlags flags) noexcept -> i32 { + i32 res = O_CREAT; + + // Access mode + if (any(flags & CreateFlags::Read)) { + res |= O_RDWR; + } else { + res |= O_WRONLY; + } + + // Behavior + if (any(flags & CreateFlags::Exclusive)) { + res |= O_EXCL; + } + + if (any(flags & CreateFlags::Truncate)) { + res |= O_TRUNC; + } + + return res; +} + +} // namespace ztd::fs diff --git a/src/ztd/src/ztd/fs/file.hpp b/src/ztd/src/ztd/fs/file.hpp new file mode 100644 index 000000000..ff791102e --- /dev/null +++ b/src/ztd/src/ztd/fs/file.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include +#include + +#include "ztd/fs/error.hpp" +#include "ztd/macros/constructor_helper.hpp" +#include "ztd/macros/enum_helper.hpp" + +namespace ztd::fs { + +class File { + friend class Directory; + + public: + enum class OpenFlags : u8 { + None = 0, + Read = ZTD_BIT(0), + Write = ZTD_BIT(1), + Append = ZTD_BIT(2), + }; + + enum class CreateFlags : u8 { + None = 0, + Read = ZTD_BIT(0), + Append = ZTD_BIT(1), + Exclusive = ZTD_BIT(2), + Truncate = ZTD_BIT(3), + }; + + File() noexcept = default; + File(i32 handle_) noexcept : handle{handle_} {} + ~File() noexcept { + if (handle >= 0) + close(handle); + } + + ZTD_MAKE_NON_COPYABLE(File); + ZTD_MAKE_MOVABLE(File, handle, std::exchange(other.handle, -1)); + + [[nodiscard]] auto getHandle() const noexcept -> i32 { return handle; } + + private: + i32 handle{-1}; + + // Helpers + static auto getPosixOpenFlags(OpenFlags flags) noexcept -> i32; + static auto getPosixCreateFlags(CreateFlags flags) noexcept -> i32; +}; + +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(File::OpenFlags); +ZTD_ENABLE_ENUM_BITWISE_OPERATORS(File::CreateFlags); + +} // namespace ztd::fs 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 ffe15cb3e..50074fd1c 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/io/continuous_stream.hpp b/src/ztd/src/ztd/io/continuous_stream.hpp new file mode 100644 index 000000000..08952a739 --- /dev/null +++ b/src/ztd/src/ztd/io/continuous_stream.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include "ztd/io/stream.hpp" + +namespace ztd::io { + +class IContinuousStream : public IStream { + public: + IContinuousStream() noexcept = default; + ~IContinuousStream() noexcept override = default; + + ZTD_MAKE_DEFAULT_COPYABLE(IContinuousStream); + ZTD_MAKE_DEFAULT_MOVABLE(IContinuousStream); + + [[nodiscard]] auto getSeek() const noexcept -> u64 override { return seek; } + auto seekTo(u64 seek_) noexcept -> void override { seek = seek_; } + auto seekBy(u64 offset) noexcept -> void override { seek += offset; } + + protected: + auto readRaw(std::span buffer) noexcept -> void override { + auto* const ptr = consumePtrRaw(buffer.size()); + std::copy(ptr, ptr + buffer.size(), buffer.data()); + } + + auto writeRaw(std::span buffer) noexcept -> void override { + auto* ptr = consumePtrRaw(buffer.size()); + std::copy(buffer.data(), buffer.data() + buffer.size(), ptr); + } + + [[nodiscard]] auto consumePtrRaw(usize size) noexcept -> u8* override { + auto* const ptr = getPtr() + seek; + seekBy(size); + return ptr; + } + + [[nodiscard]] virtual auto getPtr() noexcept -> u8* = 0; + + private: + u64 seek{0}; +}; + +} // namespace ztd::io diff --git a/src/ztd/src/ztd/io/file_stream.hpp b/src/ztd/src/ztd/io/file_stream.hpp new file mode 100644 index 000000000..c8d57a57e --- /dev/null +++ b/src/ztd/src/ztd/io/file_stream.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include + +#include "ztd/io/stream.hpp" + +namespace ztd::io { + +class FileStream : public IStream { + public: + FileStream(const ztd::fs::File& file_) noexcept : file{file_} {} + + [[nodiscard]] auto getSeek() const noexcept -> u64 override { + return static_cast(lseek(file.getHandle(), 0, SEEK_CUR)); + } + auto seekTo(u64 seek) noexcept -> void override { + lseek(file.getHandle(), static_cast(seek), SEEK_SET); + } + auto seekBy(u64 offset) noexcept -> void override { + lseek(file.getHandle(), static_cast(offset), SEEK_CUR); + } + + [[nodiscard]] auto getSize() const noexcept -> u64 override { + struct stat st{}; + if (fstat(file.getHandle(), &st) == -1) { + // TODO: error + unreachable(); + } else { + return static_cast(st.st_size); + } + } + + auto flush() noexcept -> void override { + if (fsync(file.getHandle()) == -1) { + // TODO: error + unreachable(); + } + } + + auto readRaw(std::span buffer) noexcept -> void override { + // TODO: return size + (void)::read(file.getHandle(), buffer.data(), buffer.size()); + } + + auto writeRaw(std::span buffer) noexcept -> void override { + // TODO: return size + (void)::write(file.getHandle(), buffer.data(), buffer.size()); + } + + private: + const ztd::fs::File& file; +}; + +} // namespace ztd::io diff --git a/src/ztd/src/ztd/io/memory_stream.hpp b/src/ztd/src/ztd/io/memory_stream.hpp new file mode 100644 index 000000000..4aca3c9a7 --- /dev/null +++ b/src/ztd/src/ztd/io/memory_stream.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "ztd/io/continuous_stream.hpp" + +namespace ztd::io { + +class MemoryStream : public IContinuousStream { + public: + MemoryStream(std::span data_) noexcept : data{data_} {} + ~MemoryStream() noexcept override = default; + + ZTD_MAKE_DEFAULT_COPYABLE(MemoryStream); + ZTD_MAKE_DEFAULT_MOVABLE(MemoryStream); + + [[nodiscard]] auto getSize() const noexcept -> u64 override { + return data.size(); + } + [[nodiscard]] auto getPtr() noexcept -> u8* override { return data.data(); } + + private: + std::span data; +}; + +} // namespace ztd::io diff --git a/src/ztd/src/ztd/io/sparse_stream.hpp b/src/ztd/src/ztd/io/sparse_stream.hpp new file mode 100644 index 000000000..2124b2f3f --- /dev/null +++ b/src/ztd/src/ztd/io/sparse_stream.hpp @@ -0,0 +1,120 @@ +#pragma once + +#include + +// TODO: remove dependency on std::vector +#include + +#include "ztd/io/stream.hpp" +#include "ztd/range.hpp" + +namespace ztd::io { + +class SparseStream : public IStream { + public: + struct Entry { + Range range; + IStream* stream; + }; + + // Entries must be sorted by offset + SparseStream(std::vector& entries_, u64 size_) + : entries{entries_}, size{size_} {} + + [[nodiscard]] auto getSeek() const noexcept -> u64 override { return seek; } + auto seekTo(u64 seek_) noexcept -> void override { seek = seek_; } + auto seekBy(u64 offset) noexcept -> void override { seek += offset; } + + [[nodiscard]] auto getSize() const noexcept -> u64 override { return size; } + + auto flush() noexcept -> void override { + // TODO: only flush modified entries + for (auto& entry : entries) + entry.stream->flush(); + } + + auto readRaw(std::span buffer) noexcept -> void override { + while (!buffer.empty()) { + // TODO: check for bounds + + const auto entry = getEntry(seek); + const auto max_read_size = std::min( + entry.range.getEnd() - seek, static_cast(buffer.size())); + if (entry.stream != nullptr) { + entry.stream->seekTo(seek - entry.range.getBegin()); + entry.stream->readRaw(buffer.subspan(0, max_read_size)); + } else { + std::fill(buffer.begin(), + buffer.begin() + static_cast(max_read_size), 0); + } + + seek += max_read_size; + buffer = buffer.subspan(max_read_size); + } + } + + auto writeRaw(std::span buffer) noexcept -> void override { + while (!buffer.empty()) { + // TODO: check for bounds + + const auto entry = getEntry(seek); + const auto max_write_size = std::min( + entry.range.getEnd() - seek, static_cast(buffer.size())); + if (entry.stream != nullptr) { + entry.stream->seekTo(seek - entry.range.getBegin()); + entry.stream->writeRaw(buffer.subspan(0, max_write_size)); + } + + seek += max_write_size; + buffer = buffer.subspan(max_write_size); + } + } + + private: + std::vector& entries; + u64 size; + + u64 seek{0}; + std::optional cached_entry{std::nullopt}; + + // Helpers + [[nodiscard]] auto getEntry(u64 offset) noexcept -> Entry { + // First, check if the entry has been cached + if (cached_entry.has_value()) { + const auto entry = cached_entry.value(); + if (entry.range.contains(offset)) + return entry; + } + + // Find the entry that contains the offset + auto next_it = std::ranges::upper_bound( + entries, offset, {}, + [](const Entry& entry) -> u64 { return 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}; + + auto it = std::prev(next_it); + + // Check if entry is past the range + if (!it->range.contains(offset)) { + if (next_it == entries.end()) + return { + .range = {it->range.getEnd(), size - offset}, + .stream = nullptr, + }; + + return { + .range = {it->range.getEnd(), next_it->range.getBegin()}, + .stream = nullptr, + }; + } + + // Cache the entry and return it + cached_entry = *it; + return *it; + } +}; + +} // namespace ztd::io diff --git a/src/ztd/src/ztd/io/stream.hpp b/src/ztd/src/ztd/io/stream.hpp new file mode 100644 index 000000000..e99d103c7 --- /dev/null +++ b/src/ztd/src/ztd/io/stream.hpp @@ -0,0 +1,147 @@ +#pragma once + +#include "ztd/builtin.hpp" +#include "ztd/type_aliases.hpp" + +namespace ztd::io { + +class IStream { + friend class StreamView; + friend class SparseStream; + + public: + IStream() noexcept = default; + virtual ~IStream() noexcept = default; + + ZTD_MAKE_DEFAULT_COPYABLE(IStream); + ZTD_MAKE_DEFAULT_MOVABLE(IStream); + + [[nodiscard]] virtual auto getSeek() const noexcept -> u64 = 0; + virtual void seekTo(u64 seek) { + (void)seek; + // TODO: error + builtin::unreachable(); + } + virtual auto seekBy(u64 offset) noexcept -> void = 0; + + [[nodiscard]] virtual auto getSize() const noexcept -> u64 = 0; + [[nodiscard]] auto getRemainingSize() const noexcept -> u64 { + return getSize() - getSeek(); + } + + virtual auto flush() noexcept -> void {} + + // Read + template + [[nodiscard]] auto read() noexcept -> T { + T result; + readRaw(std::span(reinterpret_cast(&result), sizeof(T))); + return result; + } + + template + auto readToRef(T& result) noexcept -> void { + readRaw(std::span(reinterpret_cast(&result), sizeof(T))); + } + + template + auto readToSpan(std::span buffer) noexcept -> void { + readRaw(std::span(reinterpret_cast(buffer.data()), + buffer.size_bytes())); + } + + template + [[nodiscard]] auto readPtr() noexcept -> const T* { + return reinterpret_cast(consumePtrRaw(sizeof(T))); + } + + template + [[nodiscard]] auto readSpan(usize count = 1) noexcept + -> std::span { + const auto ptr = + reinterpret_cast(consumePtrRaw(count * sizeof(T))); + return std::span(ptr, count); + } + + template + [[nodiscard]] auto readSpanWhole() noexcept -> std::span { + return readSpan((getSize() - getSeek()) / sizeof(T)); + } + + [[nodiscard]] auto readString(usize size) noexcept -> std::string_view { + const auto* const ptr = readPtr(); + return {ptr, size}; + } + + [[nodiscard]] auto readNullTerminatedString() noexcept -> std::string_view { + const char* ptr = readPtr(); + usize size = 0; + while (ptr[size] != '\0') { + seekBy(1); + size++; + } + + return {ptr, size}; + } + + // Write + template + auto write(const T& value) noexcept -> void { + writeRaw(std::span(reinterpret_cast(&value), sizeof(T))); + } + + template + auto writeSpan(std::span span) noexcept -> void { + writeRaw(std::span(reinterpret_cast(span.data()), + span.size_bytes())); + } + + template + [[nodiscard]] auto writeReturningPtr() noexcept -> T* { + return writeReturningSpan(1).data(); + } + + template + [[nodiscard]] auto writeReturningPtr(const T& value) noexcept -> T* { + auto ptr = writeReturningPtr(); + *ptr = value; + return ptr; + } + + template + [[nodiscard]] auto writeReturningSpan(usize count) noexcept + -> std::span { + return std::span( + reinterpret_cast(consumePtrRaw(count * sizeof(T))), count); + } + + auto writeNullTerminatedString(std::string_view str) noexcept -> void { + writeSpan( + std::span(reinterpret_cast(str.data()), str.size())); + write('\0'); + } + + protected: + // TODO: verify size + virtual auto readRaw(std::span buffer) noexcept -> void { + (void)buffer; + // TODO: error + builtin::unreachable(); + } + + // TODO: verify size + virtual auto writeRaw(std::span buffer) noexcept -> void { + (void)buffer; + // TODO: error + builtin::unreachable(); + } + + // TODO: verify size + virtual auto consumePtrRaw(usize size) noexcept -> u8* { + (void)size; + // TODO: error + builtin::unreachable(); + } +}; + +} // namespace ztd::io diff --git a/src/ztd/src/ztd/io/stream_view.hpp b/src/ztd/src/ztd/io/stream_view.hpp new file mode 100644 index 000000000..8102216fc --- /dev/null +++ b/src/ztd/src/ztd/io/stream_view.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include "ztd/io/stream.hpp" + +namespace ztd::io { + +class StreamView : public IStream { + public: + StreamView(IStream* base_, u64 offset_, u64 size_) noexcept + : base{base_}, offset{offset_}, size{size_} { + base->seekTo(offset); + } + StreamView(IStream* base_, u64 offset_) noexcept + : StreamView(base_, offset_, base_->getSize() - offset_) {} + + [[nodiscard]] auto getSeek() const noexcept -> u64 override { + return base->getSeek() - offset; + } + auto seekTo(u64 seek) noexcept -> void override { + base->seekTo(offset + seek); + } + auto seekBy(u64 offset_) noexcept -> void override { + base->seekBy(offset_); + } + + [[nodiscard]] auto getSize() const noexcept -> u64 override { return size; } + + auto flush() noexcept -> void override { base->flush(); } + + auto readRaw(std::span buffer) noexcept -> void override { + base->readRaw(buffer); + } + auto writeRaw(std::span buffer) noexcept -> void override { + base->writeRaw(buffer); + } + [[nodiscard]] auto consumePtrRaw(usize size_) noexcept -> u8* override { + return base->consumePtrRaw(size_); + } + + private: + IStream* base; + u64 offset; + u64 size; +}; + +} // namespace ztd::io diff --git a/src/ztd/src/ztd/linked_list.hpp b/src/ztd/src/ztd/linked_list.hpp new file mode 100644 index 000000000..53e61a9ef --- /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 000000000..9e1f3091c --- /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&) noexcept = 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 ZTD_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 000000000..8c0101a52 --- /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 000000000..e31d2559e --- /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 000000000..dda0b09fb --- /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 000000000..85a4c0adc --- /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 000000000..a22576c11 --- /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) \ + auto ZTD_UNIQUE_SUFFIX(_) = expected; \ + if (!ZTD_UNIQUE_SUFFIX(_).has_value()) \ + fail_statement; \ + var = std::move(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/mem/alignment.hpp b/src/ztd/src/ztd/mem/alignment.hpp new file mode 100644 index 000000000..74230d596 --- /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 000000000..978d95633 --- /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 000000000..6c9a3105b --- /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 000000000..93543acba --- /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 000000000..7317cd545 --- /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 000000000..7b5353839 --- /dev/null +++ b/src/ztd/src/ztd/mem/page.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include "ztd/mem/literals.hpp" +#include "ztd/platform.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 000000000..15f9dcb60 --- /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()); + auto* const 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/static_pool.hpp b/src/ztd/src/ztd/mem/static_pool.hpp new file mode 100644 index 000000000..dd58ca3c2 --- /dev/null +++ b/src/ztd/src/ztd/mem/static_pool.hpp @@ -0,0 +1,149 @@ +#pragma once + +#include "ztd/type_aliases.hpp" + +namespace ztd::mem { + +template +class StaticPool { + public: + StaticPool() noexcept = default; + ~StaticPool() noexcept = default; + + ZTD_MAKE_DEFAULT_COPYABLE(StaticPool); + ZTD_MAKE_DEFAULT_MOVABLE(StaticPool); + + template + auto insert(Args... args) noexcept + -> std::expected { + ZTD_ASSIGN_OR_RETURN_ERROR(const auto index, allocateIndex()); + objects[index].emplace(std::forward(args)...); + return index; + } + + [[nodiscard]] auto free(usize index) noexcept -> bool { + auto& object = objects[index]; + if (object.has_value()) { + object = std::nullopt; + return true; + } else { + return false; + } + } + + [[nodiscard]] auto isValid(usize index) const noexcept -> bool { + return objects[index].has_value(); + } + + auto get(usize index) noexcept -> std::optional + requires std::is_pointer_v + { + return objects[index]; + } + + auto get(usize index) const noexcept -> std::optional + requires std::is_pointer_v + { + return objects[index]; + } + + auto get(usize index) noexcept -> std::optional + requires(!std::is_pointer_v) + { + return objects[index].transform([](T& value) -> T* { return &value; }); + } + + auto get(usize index) const noexcept -> std::optional + requires(!std::is_pointer_v) + { + return objects[index].transform( + [](const T& value) -> const T* { return &value; }); + ; + } + + // Iterating + auto begin() noexcept { return Iterator(this, 0); } + auto end() noexcept { return Iterator(this, crnt); } + + auto begin() const noexcept { return ConstIterator(this, 0); } + auto end() const noexcept { return ConstIterator(this, crnt); } + + auto cbegin() const noexcept { return begin(); } + auto cend() const noexcept { return end(); } + + [[nodiscard]] auto getCapacity() const noexcept -> usize { + return capacity; + } + + private: + std::array, capacity> objects; + usize crnt{0}; + + auto allocateIndex() noexcept -> std::expected { + if (crnt < capacity) { + return crnt++; + } + + for (usize i = 0; i < capacity; i++) { + if (!isValid(i)) { + return i; + } + } + + return std::unexpected(IAllocator::Error::OutOfMemory); + } + + // Iterator + template + struct IteratorBase { + using PoolType = + std::conditional_t; + PoolType* pool; + usize index; + + IteratorBase(PoolType* p, usize i) noexcept : pool(p), index(i) { + while (index < pool->crnt && !pool->isValid(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 < pool->crnt && !pool->isValid(index)); + return *this; + } + + auto operator!=(const IteratorBase& other) const noexcept -> bool { + return index != other.index; + } + }; + + public: + using Iterator = IteratorBase; + using ConstIterator = IteratorBase; +}; + +} // namespace ztd::mem diff --git a/src/ztd/src/ztd/platform.hpp b/src/ztd/src/ztd/platform.hpp new file mode 100644 index 000000000..b3a701610 --- /dev/null +++ b/src/ztd/src/ztd/platform.hpp @@ -0,0 +1,76 @@ +#pragma once + +// Compiler + +#if defined(__clang__) +#define ZTD_COMPILER_CLANG +#elifdef __GNUC__ +#define ZTD_COMPILER_GCC +#elifdef __INTEL_COMPILER +#define ZTD_COMPILER_INTEL_CPP +#elifdef _MSC_VER +#define ZTD_COMPILER_MSVC +#elifdef _MSC_VER +#define ZTD_COMPILER_MSVC +#elif defined(__MINGW32__) || defined(__MINGW64__) +#define ZTD_COMPILER_MINGW +#else +#define ZTD_COMPILER_UNKNOWN +#endif + +// 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/range.hpp b/src/ztd/src/ztd/range.hpp new file mode 100644 index 000000000..f14553b1d --- /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 9166fd10b..7a05f496f 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 000000000..6b298f485 --- /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 000000000..e3665ba24 --- /dev/null +++ b/src/ztd/src/ztd/ztd.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "ztd/compress/lz4.hpp" +#include "ztd/fs/directory.hpp" +#include "ztd/hash/xxhash32.hpp" +#include "ztd/io/file_stream.hpp" +#include "ztd/io/memory_stream.hpp" +#include "ztd/io/sparse_stream.hpp" +#include "ztd/io/stream_view.hpp".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"