diff options
Diffstat (limited to '')
-rw-r--r-- | src/common/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/common/logging/backend.cpp | 112 | ||||
-rw-r--r-- | src/common/logging/filter.cpp | 1 | ||||
-rw-r--r-- | src/common/logging/types.h | 1 | ||||
-rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/core/hle/service/ngct/ngct.cpp | 46 | ||||
-rw-r--r-- | src/core/hle/service/ngct/ngct.h | 20 | ||||
-rw-r--r-- | src/core/hle/service/service.cpp | 2 | ||||
-rw-r--r-- | src/video_core/command_classes/codecs/vp9.cpp | 1 | ||||
-rw-r--r-- | src/video_core/command_classes/codecs/vp9_types.h | 85 |
10 files changed, 103 insertions, 170 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 316c4dedc..57922b51c 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -176,6 +176,3 @@ if (MSVC) else() target_link_libraries(common PRIVATE zstd) endif() -if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND CMAKE_CXX_COMPILER_ID STREQUAL GNU) - target_link_libraries(common PRIVATE backtrace) -endif() diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 6f1d251e1..949384fd3 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -13,14 +13,6 @@ #include <windows.h> // For OutputDebugStringW #endif -#if defined(__linux__) && defined(__GNUG__) && !defined(__clang__) -#define BOOST_STACKTRACE_USE_BACKTRACE -#include <boost/stacktrace.hpp> -#undef BOOST_STACKTRACE_USE_BACKTRACE -#include <signal.h> -#define YUZU_LINUX_GCC_BACKTRACE -#endif - #include "common/fs/file.h" #include "common/fs/fs.h" #include "common/fs/fs_paths.h" @@ -163,14 +155,6 @@ public: bool initialization_in_progress_suppress_logging = true; -#ifdef YUZU_LINUX_GCC_BACKTRACE -[[noreturn]] void SleepForever() { - while (true) { - pause(); - } -} -#endif - /** * Static state as a singleton. */ @@ -242,66 +226,9 @@ private: while (max_logs_to_write-- && message_queue.Pop(entry)) { write_logs(); } - })} { -#ifdef YUZU_LINUX_GCC_BACKTRACE - int waker_pipefd[2]; - int done_printing_pipefd[2]; - if (pipe2(waker_pipefd, O_CLOEXEC) || pipe2(done_printing_pipefd, O_CLOEXEC)) { - abort(); - } - backtrace_thread_waker_fd = waker_pipefd[1]; - backtrace_done_printing_fd = done_printing_pipefd[0]; - std::thread([this, wait_fd = waker_pipefd[0], done_fd = done_printing_pipefd[1]] { - Common::SetCurrentThreadName("yuzu:Crash"); - for (u8 ignore = 0; read(wait_fd, &ignore, 1) != 1;) - ; - const int sig = received_signal; - if (sig <= 0) { - abort(); - } - StopBackendThread(); - const auto signal_entry = - CreateEntry(Class::Log, Level::Critical, "?", 0, "?", - fmt::vformat("Received signal {}", fmt::make_format_args(sig))); - ForEachBackend([&signal_entry](Backend& backend) { - backend.EnableForStacktrace(); - backend.Write(signal_entry); - }); - const auto backtrace = - boost::stacktrace::stacktrace::from_dump(backtrace_storage.data(), 4096); - for (const auto& frame : backtrace.as_vector()) { - auto line = boost::stacktrace::detail::to_string(&frame, 1); - if (line.empty()) { - abort(); - } - line.pop_back(); // Remove newline - const auto frame_entry = - CreateEntry(Class::Log, Level::Critical, "?", 0, "?", line); - ForEachBackend([&frame_entry](Backend& backend) { backend.Write(frame_entry); }); - } - using namespace std::literals; - const auto rip_entry = CreateEntry(Class::Log, Level::Critical, "?", 0, "?", "RIP"s); - ForEachBackend([&rip_entry](Backend& backend) { - backend.Write(rip_entry); - backend.Flush(); - }); - for (const u8 anything = 0; write(done_fd, &anything, 1) != 1;) - ; - // Abort on original thread to help debugging - SleepForever(); - }).detach(); - signal(SIGSEGV, &HandleSignal); - signal(SIGABRT, &HandleSignal); -#endif - } + })} {} ~Impl() { -#ifdef YUZU_LINUX_GCC_BACKTRACE - if (int zero_or_ignore = 0; - !received_signal.compare_exchange_strong(zero_or_ignore, SIGKILL)) { - SleepForever(); - } -#endif StopBackendThread(); } @@ -340,36 +267,6 @@ private: delete ptr; } -#ifdef YUZU_LINUX_GCC_BACKTRACE - [[noreturn]] static void HandleSignal(int sig) { - signal(SIGABRT, SIG_DFL); - signal(SIGSEGV, SIG_DFL); - if (sig <= 0) { - abort(); - } - instance->InstanceHandleSignal(sig); - } - - [[noreturn]] void InstanceHandleSignal(int sig) { - if (int zero_or_ignore = 0; !received_signal.compare_exchange_strong(zero_or_ignore, sig)) { - if (received_signal == SIGKILL) { - abort(); - } - SleepForever(); - } - // Don't restart like boost suggests. We want to append to the log file and not lose dynamic - // symbols. This may segfault if it unwinds outside C/C++ code but we'll just have to fall - // back to core dumps. - boost::stacktrace::safe_dump_to(backtrace_storage.data(), 4096); - std::atomic_thread_fence(std::memory_order_seq_cst); - for (const int anything = 0; write(backtrace_thread_waker_fd, &anything, 1) != 1;) - ; - for (u8 ignore = 0; read(backtrace_done_printing_fd, &ignore, 1) != 1;) - ; - abort(); - } -#endif - static inline std::unique_ptr<Impl, decltype(&Deleter)> instance{nullptr, Deleter}; Filter filter; @@ -380,13 +277,6 @@ private: std::thread backend_thread; MPSCQueue<Entry> message_queue{}; std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; - -#ifdef YUZU_LINUX_GCC_BACKTRACE - std::atomic_int received_signal{0}; - std::array<u8, 4096> backtrace_storage{}; - int backtrace_thread_waker_fd; - int backtrace_done_printing_fd; -#endif }; } // namespace diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index f055f0e11..42744c994 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -111,6 +111,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { SUB(Service, NCM) \ SUB(Service, NFC) \ SUB(Service, NFP) \ + SUB(Service, NGCT) \ SUB(Service, NIFM) \ SUB(Service, NIM) \ SUB(Service, NPNS) \ diff --git a/src/common/logging/types.h b/src/common/logging/types.h index 7ad0334fc..ddf9d27ca 100644 --- a/src/common/logging/types.h +++ b/src/common/logging/types.h @@ -81,6 +81,7 @@ enum class Class : u8 { Service_NCM, ///< The NCM service Service_NFC, ///< The NFC (Near-field communication) service Service_NFP, ///< The NFP service + Service_NGCT, ///< The NGCT (No Good Content for Terra) service Service_NIFM, ///< The NIFM (Network interface) service Service_NIM, ///< The NIM service Service_NPNS, ///< The NPNS service diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f5cf5c16a..87d47e2e5 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -452,6 +452,8 @@ add_library(core STATIC hle/service/nfp/nfp.h hle/service/nfp/nfp_user.cpp hle/service/nfp/nfp_user.h + hle/service/ngct/ngct.cpp + hle/service/ngct/ngct.h hle/service/nifm/nifm.cpp hle/service/nifm/nifm.h hle/service/nim/nim.cpp diff --git a/src/core/hle/service/ngct/ngct.cpp b/src/core/hle/service/ngct/ngct.cpp new file mode 100644 index 000000000..deb3abb28 --- /dev/null +++ b/src/core/hle/service/ngct/ngct.cpp @@ -0,0 +1,46 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included + +#include "common/string_util.h" +#include "core/core.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/service/ngct/ngct.h" +#include "core/hle/service/service.h" + +namespace Service::NGCT { + +class IService final : public ServiceFramework<IService> { +public: + explicit IService(Core::System& system_) : ServiceFramework{system_, "ngct:u"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Match"}, + {1, &IService::Filter, "Filter"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void Filter(Kernel::HLERequestContext& ctx) { + const auto buffer = ctx.ReadBuffer(); + const auto text = Common::StringFromFixedZeroTerminatedBuffer( + reinterpret_cast<const char*>(buffer.data()), buffer.size()); + + LOG_WARNING(Service_NGCT, "(STUBBED) called, text={}", text); + + // Return the same string since we don't censor anything + ctx.WriteBuffer(buffer); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } +}; + +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { + std::make_shared<IService>(system)->InstallAsService(system.ServiceManager()); +} + +} // namespace Service::NGCT diff --git a/src/core/hle/service/ngct/ngct.h b/src/core/hle/service/ngct/ngct.h new file mode 100644 index 000000000..1f2a47b78 --- /dev/null +++ b/src/core/hle/service/ngct/ngct.h @@ -0,0 +1,20 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included + +#pragma once + +namespace Core { +class System; +} + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::NGCT { + +/// Registers all NGCT services with the specified service manager. +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); + +} // namespace Service::NGCT diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index b3e50433b..065133166 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -46,6 +46,7 @@ #include "core/hle/service/ncm/ncm.h" #include "core/hle/service/nfc/nfc.h" #include "core/hle/service/nfp/nfp.h" +#include "core/hle/service/ngct/ngct.h" #include "core/hle/service/nifm/nifm.h" #include "core/hle/service/nim/nim.h" #include "core/hle/service/npns/npns.h" @@ -271,6 +272,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system NCM::InstallInterfaces(*sm, system); NFC::InstallInterfaces(*sm, system); NFP::InstallInterfaces(*sm, system); + NGCT::InstallInterfaces(*sm, system); NIFM::InstallInterfaces(*sm, system); NIM::InstallInterfaces(*sm, system); NPNS::InstallInterfaces(*sm, system); diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp index 70030066a..d7e749485 100644 --- a/src/video_core/command_classes/codecs/vp9.cpp +++ b/src/video_core/command_classes/codecs/vp9.cpp @@ -742,6 +742,7 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() { uncomp_writer.WriteDeltaQ(current_frame_info.uv_dc_delta_q); uncomp_writer.WriteDeltaQ(current_frame_info.uv_ac_delta_q); + ASSERT(!current_frame_info.segment_enabled); uncomp_writer.WriteBit(false); // Segmentation enabled (TODO). const s32 min_tile_cols_log2 = CalcMinLog2TileCols(current_frame_info.frame_size.width); diff --git a/src/video_core/command_classes/codecs/vp9_types.h b/src/video_core/command_classes/codecs/vp9_types.h index 87eafdb03..3b1ed4b3a 100644 --- a/src/video_core/command_classes/codecs/vp9_types.h +++ b/src/video_core/command_classes/codecs/vp9_types.h @@ -22,7 +22,7 @@ struct Vp9FrameDimensions { }; static_assert(sizeof(Vp9FrameDimensions) == 0x8, "Vp9 Vp9FrameDimensions is an invalid size"); -enum FrameFlags : u32 { +enum class FrameFlags : u32 { IsKeyFrame = 1 << 0, LastFrameIsKeyFrame = 1 << 1, FrameSizeChanged = 1 << 2, @@ -30,6 +30,7 @@ enum FrameFlags : u32 { LastShowFrame = 1 << 4, IntraOnly = 1 << 5, }; +DECLARE_ENUM_FLAG_OPERATORS(FrameFlags) enum class TxSize { Tx4x4 = 0, // 4x4 transform @@ -92,44 +93,34 @@ struct Vp9EntropyProbs { static_assert(sizeof(Vp9EntropyProbs) == 0x7B4, "Vp9EntropyProbs is an invalid size"); struct Vp9PictureInfo { - bool is_key_frame; - bool intra_only; - bool last_frame_was_key; - bool frame_size_changed; - bool error_resilient_mode; - bool last_frame_shown; - bool show_frame; + u32 bitstream_size; + std::array<u64, 4> frame_offsets; std::array<s8, 4> ref_frame_sign_bias; s32 base_q_index; s32 y_dc_delta_q; s32 uv_dc_delta_q; s32 uv_ac_delta_q; - bool lossless; s32 transform_mode; - bool allow_high_precision_mv; s32 interp_filter; s32 reference_mode; - s8 comp_fixed_ref; - std::array<s8, 2> comp_var_ref; s32 log2_tile_cols; s32 log2_tile_rows; - bool segment_enabled; - bool segment_map_update; - bool segment_map_temporal_update; - s32 segment_abs_delta; - std::array<u32, 8> segment_feature_enable; - std::array<std::array<s16, 4>, 8> segment_feature_data; - bool mode_ref_delta_enabled; - bool use_prev_in_find_mv_refs; std::array<s8, 4> ref_deltas; std::array<s8, 2> mode_deltas; Vp9EntropyProbs entropy; Vp9FrameDimensions frame_size; u8 first_level; u8 sharpness_level; - u32 bitstream_size; - std::array<u64, 4> frame_offsets; - std::array<bool, 4> refresh_frame; + bool is_key_frame; + bool intra_only; + bool last_frame_was_key; + bool error_resilient_mode; + bool last_frame_shown; + bool show_frame; + bool lossless; + bool allow_high_precision_mv; + bool segment_enabled; + bool mode_ref_delta_enabled; }; struct Vp9FrameContainer { @@ -145,7 +136,7 @@ struct PictureInfo { Vp9FrameDimensions golden_frame_size; ///< 0x50 Vp9FrameDimensions alt_frame_size; ///< 0x58 Vp9FrameDimensions current_frame_size; ///< 0x60 - u32 vp9_flags; ///< 0x68 + FrameFlags vp9_flags; ///< 0x68 std::array<s8, 4> ref_frame_sign_bias; ///< 0x6C u8 first_level; ///< 0x70 u8 sharpness_level; ///< 0x71 @@ -158,60 +149,43 @@ struct PictureInfo { u8 allow_high_precision_mv; ///< 0x78 u8 interp_filter; ///< 0x79 u8 reference_mode; ///< 0x7A - s8 comp_fixed_ref; ///< 0x7B - std::array<s8, 2> comp_var_ref; ///< 0x7C + INSERT_PADDING_BYTES_NOINIT(3); ///< 0x7B u8 log2_tile_cols; ///< 0x7E u8 log2_tile_rows; ///< 0x7F Segmentation segmentation; ///< 0x80 LoopFilter loop_filter; ///< 0xE4 - INSERT_PADDING_BYTES_NOINIT(5); ///< 0xEB - u32 surface_params; ///< 0xF0 - INSERT_PADDING_WORDS_NOINIT(3); ///< 0xF4 + INSERT_PADDING_BYTES_NOINIT(21); ///< 0xEB [[nodiscard]] Vp9PictureInfo Convert() const { return { - .is_key_frame = (vp9_flags & FrameFlags::IsKeyFrame) != 0, - .intra_only = (vp9_flags & FrameFlags::IntraOnly) != 0, - .last_frame_was_key = (vp9_flags & FrameFlags::LastFrameIsKeyFrame) != 0, - .frame_size_changed = (vp9_flags & FrameFlags::FrameSizeChanged) != 0, - .error_resilient_mode = (vp9_flags & FrameFlags::ErrorResilientMode) != 0, - .last_frame_shown = (vp9_flags & FrameFlags::LastShowFrame) != 0, - .show_frame = true, + .bitstream_size = bitstream_size, + .frame_offsets{}, .ref_frame_sign_bias = ref_frame_sign_bias, .base_q_index = base_q_index, .y_dc_delta_q = y_dc_delta_q, .uv_dc_delta_q = uv_dc_delta_q, .uv_ac_delta_q = uv_ac_delta_q, - .lossless = lossless != 0, .transform_mode = tx_mode, - .allow_high_precision_mv = allow_high_precision_mv != 0, .interp_filter = interp_filter, .reference_mode = reference_mode, - .comp_fixed_ref = comp_fixed_ref, - .comp_var_ref = comp_var_ref, .log2_tile_cols = log2_tile_cols, .log2_tile_rows = log2_tile_rows, - .segment_enabled = segmentation.enabled != 0, - .segment_map_update = segmentation.update_map != 0, - .segment_map_temporal_update = segmentation.temporal_update != 0, - .segment_abs_delta = segmentation.abs_delta, - .segment_feature_enable = segmentation.feature_mask, - .segment_feature_data = segmentation.feature_data, - .mode_ref_delta_enabled = loop_filter.mode_ref_delta_enabled != 0, - .use_prev_in_find_mv_refs = !(vp9_flags == (FrameFlags::ErrorResilientMode)) && - !(vp9_flags == (FrameFlags::FrameSizeChanged)) && - !(vp9_flags == (FrameFlags::IntraOnly)) && - (vp9_flags == (FrameFlags::LastShowFrame)) && - !(vp9_flags == (FrameFlags::LastFrameIsKeyFrame)), .ref_deltas = loop_filter.ref_deltas, .mode_deltas = loop_filter.mode_deltas, .entropy{}, .frame_size = current_frame_size, .first_level = first_level, .sharpness_level = sharpness_level, - .bitstream_size = bitstream_size, - .frame_offsets{}, - .refresh_frame{}, + .is_key_frame = True(vp9_flags & FrameFlags::IsKeyFrame), + .intra_only = True(vp9_flags & FrameFlags::IntraOnly), + .last_frame_was_key = True(vp9_flags & FrameFlags::LastFrameIsKeyFrame), + .error_resilient_mode = True(vp9_flags & FrameFlags::ErrorResilientMode), + .last_frame_shown = True(vp9_flags & FrameFlags::LastShowFrame), + .show_frame = true, + .lossless = lossless != 0, + .allow_high_precision_mv = allow_high_precision_mv != 0, + .segment_enabled = segmentation.enabled != 0, + .mode_ref_delta_enabled = loop_filter.mode_ref_delta_enabled != 0, }; } }; @@ -316,7 +290,6 @@ ASSERT_POSITION(last_frame_size, 0x48); ASSERT_POSITION(first_level, 0x70); ASSERT_POSITION(segmentation, 0x80); ASSERT_POSITION(loop_filter, 0xE4); -ASSERT_POSITION(surface_params, 0xF0); #undef ASSERT_POSITION #define ASSERT_POSITION(field_name, position) \ |