Compare commits

..

4 commits

Author SHA1 Message Date
4434e1bb90 Fix reverb effect
All checks were successful
eden-license / license-header (pull_request) Successful in 25s
2025-10-02 00:26:07 +02:00
24e6c62109
[vk, ogl] invalidate pipeline caches from <=0.0.3 (#2637)
Invalidates caches before next upcoming release, this will make transitions smoother especially for users whom do not know how to clear caches. The reasoning behind this is the recent changes to async shaders and other pipeline stuffs that may break compat

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2637
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-02 00:25:41 +02:00
326865cba2
[host1x] Improve FFmpeg error handling (#2643)
This improves the FFmpeg error handling.

Reviewed-on: #2643
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-02 00:15:14 +02:00
76b5d6778e
[common/logging] faster logging by avoiding constructing unused strings/results (and filtering first) (#2603)
basically std::string would be invoked even when the logging was filtered, then destroyed instantly, invoking malloc/free and polluting mem arenas for no good reason

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2603
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-01 23:18:37 +02:00
11 changed files with 70 additions and 61 deletions

View file

@ -39,9 +39,17 @@ namespace Common::Log {
namespace { namespace {
/** /// @brief Trims up to and including the last of ../, ..\, src/, src\ in a string
* Interface for logging backends. /// do not be fooled this isn't generating new strings on .rodata :)
*/ constexpr const char* TrimSourcePath(std::string_view source) {
const auto rfind = [source](const std::string_view match) {
return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size());
};
auto idx = (std::max)({rfind("src/"), rfind("src\\"), rfind("../"), rfind("..\\")});
return source.data() + idx;
}
/// @brief Interface for logging backends.
class Backend { class Backend {
public: public:
virtual ~Backend() = default; virtual ~Backend() = default;
@ -53,9 +61,7 @@ public:
virtual void Flush() = 0; virtual void Flush() = 0;
}; };
/** /// @brief Backend that writes to stderr and with color
* Backend that writes to stderr and with color
*/
class ColorConsoleBackend final : public Backend { class ColorConsoleBackend final : public Backend {
public: public:
explicit ColorConsoleBackend() = default; explicit ColorConsoleBackend() = default;
@ -84,9 +90,7 @@ private:
std::atomic_bool enabled{false}; std::atomic_bool enabled{false};
}; };
/** /// @brief Backend that writes to a file passed into the constructor
* Backend that writes to a file passed into the constructor
*/
class FileBackend final : public Backend { class FileBackend final : public Backend {
public: public:
explicit FileBackend(const std::filesystem::path& filename) { explicit FileBackend(const std::filesystem::path& filename) {
@ -248,13 +252,14 @@ public:
color_console_backend.SetEnabled(enabled); color_console_backend.SetEnabled(enabled);
} }
bool CanPushEntry(Class log_class, Level log_level) const noexcept {
return filter.CheckMessage(log_class, log_level);
}
void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, std::string&& message) { const char* function, std::string&& message) noexcept {
if (!filter.CheckMessage(log_class, log_level)) {
return;
}
message_queue.EmplaceWait( message_queue.EmplaceWait(
CreateEntry(log_class, log_level, filename, line_num, function, std::move(message))); CreateEntry(log_class, log_level, TrimSourcePath(filename), line_num, function, std::move(message)));
} }
private: private:
@ -368,8 +373,9 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, fmt::string_view format, unsigned int line_num, const char* function, fmt::string_view format,
const fmt::format_args& args) { const fmt::format_args& args) {
if (!initialization_in_progress_suppress_logging) { if (!initialization_in_progress_suppress_logging) {
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function, auto& instance = Impl::Instance();
fmt::vformat(format, args)); if (instance.CanPushEntry(log_class, log_level))
instance.PushEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args));
} }
} }
} // namespace Common::Log } // namespace Common::Log

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-FileCopyrightText: 2014 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -9,22 +12,20 @@ namespace Common::Log {
namespace { namespace {
template <typename It> template <typename It>
Level GetLevelByName(const It begin, const It end) { Level GetLevelByName(const It begin, const It end) {
for (u8 i = 0; i < static_cast<u8>(Level::Count); ++i) { for (u32 i = 0; i < u32(Level::Count); ++i) {
const char* level_name = GetLevelName(static_cast<Level>(i)); const char* level_name = GetLevelName(Level(i));
if (Common::ComparePartialString(begin, end, level_name)) { if (Common::ComparePartialString(begin, end, level_name))
return static_cast<Level>(i); return Level(i);
}
} }
return Level::Count; return Level::Count;
} }
template <typename It> template <typename It>
Class GetClassByName(const It begin, const It end) { Class GetClassByName(const It begin, const It end) {
for (u8 i = 0; i < static_cast<u8>(Class::Count); ++i) { for (u32 i = 0; i < u32(Class::Count); ++i) {
const char* level_name = GetLogClassName(static_cast<Class>(i)); const char* level_name = GetLogClassName(Class(i));
if (Common::ComparePartialString(begin, end, level_name)) { if (Common::ComparePartialString(begin, end, level_name))
return static_cast<Class>(i); return Class(i);
}
} }
return Class::Count; return Class::Count;
} }
@ -229,13 +230,12 @@ void Filter::ParseFilterString(std::string_view filter_view) {
} }
bool Filter::CheckMessage(Class log_class, Level level) const { bool Filter::CheckMessage(Class log_class, Level level) const {
return static_cast<u8>(level) >= return u8(level) >= u8(class_levels[std::size_t(log_class)]);
static_cast<u8>(class_levels[static_cast<std::size_t>(log_class)]);
} }
bool Filter::IsDebug() const { bool Filter::IsDebug() const {
return std::any_of(class_levels.begin(), class_levels.end(), [](const Level& l) { return std::any_of(class_levels.begin(), class_levels.end(), [](const Level& l) {
return static_cast<u8>(l) <= static_cast<u8>(Level::Debug); return u8(l) <= u8(Level::Debug);
}); });
} }

View file

@ -16,15 +16,6 @@
namespace Common::Log { namespace Common::Log {
// trims up to and including the last of ../, ..\, src/, src\ in a string
constexpr const char* TrimSourcePath(std::string_view source) {
const auto rfind = [source](const std::string_view match) {
return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size());
};
auto idx = (std::max)({rfind("src/"), rfind("src\\"), rfind("../"), rfind("..\\")});
return source.data() + idx;
}
/// Logs a message to the global logger, using fmt /// Logs a message to the global logger, using fmt
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, fmt::string_view format, unsigned int line_num, const char* function, fmt::string_view format,
@ -42,7 +33,7 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
#ifdef _DEBUG #ifdef _DEBUG
#define LOG_TRACE(log_class, ...) \ #define LOG_TRACE(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#else #else
#define LOG_TRACE(log_class, fmt, ...) (void(0)) #define LOG_TRACE(log_class, fmt, ...) (void(0))
@ -50,21 +41,21 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
#define LOG_DEBUG(log_class, ...) \ #define LOG_DEBUG(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_INFO(log_class, ...) \ #define LOG_INFO(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_WARNING(log_class, ...) \ #define LOG_WARNING(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_ERROR(log_class, ...) \ #define LOG_ERROR(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_CRITICAL(log_class, ...) \ #define LOG_CRITICAL(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)

View file

@ -135,8 +135,8 @@ NvResult nvhost_nvdec_common::GetSyncpoint(IoctlGetSyncpoint& params) {
} }
NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) { NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) {
LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); LOG_DEBUG(Service_NVDRV, "called WAITBASE");
params.value = 0; // Seems to be hard coded at 0 params.value = 0;
return NvResult::Success; return NvResult::Success;
} }

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -286,7 +289,7 @@ Result CheckOpenSSLErrors() {
msg.append(data); msg.append(data);
} }
Common::Log::FmtLogMessage(Common::Log::Class::Service_SSL, Common::Log::Level::Error, Common::Log::FmtLogMessage(Common::Log::Class::Service_SSL, Common::Log::Level::Error,
Common::Log::TrimSourcePath(file), line, func, "OpenSSL: {}", file, line, func, "OpenSSL: {}",
msg); msg);
} }
return ResultInternalError; return ResultInternalError;

View file

@ -38,6 +38,10 @@ void Decoder::Decode() {
// Receive output frames from decoder. // Receive output frames from decoder.
auto frame = decode_api.ReceiveFrame(); auto frame = decode_api.ReceiveFrame();
if (!frame) {
return;
}
if (IsInterlaced()) { if (IsInterlaced()) {
auto [luma_top, luma_bottom, chroma_top, chroma_bottom] = GetInterlacedOffsets(); auto [luma_top, luma_bottom, chroma_top, chroma_bottom] = GetInterlacedOffsets();
auto frame_copy = frame; auto frame_copy = frame;

View file

@ -233,7 +233,7 @@ bool DecoderContext::OpenContext(const Decoder& decoder) {
} }
bool DecoderContext::SendPacket(const Packet& packet) { bool DecoderContext::SendPacket(const Packet& packet) {
if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0 && ret != AVERROR_EOF) { if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) {
LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret)); LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret));
return false; return false;
} }
@ -242,31 +242,31 @@ bool DecoderContext::SendPacket(const Packet& packet) {
} }
std::shared_ptr<Frame> DecoderContext::ReceiveFrame() { std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
auto ReceiveImpl = [&](AVFrame* frame) -> bool { auto ReceiveImpl = [&](AVFrame* frame) -> int {
if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0 && ret != AVERROR_EOF) { const int ret = avcodec_receive_frame(m_codec_context, frame);
if (ret < 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) {
LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret)); LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret));
return false;
} }
return true; return ret;
}; };
std::shared_ptr<Frame> intermediate_frame = std::make_shared<Frame>(); std::shared_ptr<Frame> intermediate_frame = std::make_shared<Frame>();
if (!ReceiveImpl(intermediate_frame->GetFrame())) { if (ReceiveImpl(intermediate_frame->GetFrame()) < 0) {
return {}; return {};
} }
m_temp_frame = std::make_shared<Frame>(); m_final_frame = std::make_shared<Frame>();
if (m_codec_context->hw_device_ctx) { if (m_codec_context->hw_device_ctx) {
m_temp_frame->SetFormat(PreferredGpuFormat); m_final_frame->SetFormat(PreferredGpuFormat);
if (int ret = av_hwframe_transfer_data(m_temp_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) { if (const int ret = av_hwframe_transfer_data(m_final_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) {
LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret)); LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret));
return {}; return {};
} }
} else { } else {
m_temp_frame = std::move(intermediate_frame); m_final_frame = std::move(intermediate_frame);
} }
return std::move(m_temp_frame); return std::move(m_final_frame);
} }
void DecodeApi::Reset() { void DecodeApi::Reset() {

View file

@ -194,7 +194,7 @@ public:
private: private:
const Decoder& m_decoder; const Decoder& m_decoder;
AVCodecContext* m_codec_context{}; AVCodecContext* m_codec_context{};
std::shared_ptr<Frame> m_temp_frame{}; std::shared_ptr<Frame> m_final_frame{};
bool m_decode_order{}; bool m_decode_order{};
}; };

View file

@ -146,6 +146,11 @@ void Vic::Execute() {
} }
auto frame = frame_queue.GetFrame(nvdec_id, luma_offset); auto frame = frame_queue.GetFrame(nvdec_id, luma_offset);
if (!frame) {
continue;
}
if (!frame.get()) { if (!frame.get()) {
LOG_ERROR(HW_GPU, "Vic {} failed to get frame with offset {:#X}", id, luma_offset); LOG_ERROR(HW_GPU, "Vic {} failed to get frame with offset {:#X}", id, luma_offset);
continue; continue;

View file

@ -54,7 +54,7 @@ using VideoCommon::LoadPipelines;
using VideoCommon::SerializePipeline; using VideoCommon::SerializePipeline;
using Context = ShaderContext::Context; using Context = ShaderContext::Context;
constexpr u32 CACHE_VERSION = 10; constexpr u32 CACHE_VERSION = 13;
template <typename Container> template <typename Container>
auto MakeSpan(Container& container) { auto MakeSpan(Container& container) {

View file

@ -55,7 +55,7 @@ using VideoCommon::FileEnvironment;
using VideoCommon::GenericEnvironment; using VideoCommon::GenericEnvironment;
using VideoCommon::GraphicsEnvironment; using VideoCommon::GraphicsEnvironment;
constexpr u32 CACHE_VERSION = 12; constexpr u32 CACHE_VERSION = 13;
constexpr std::array<char, 8> VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'}; constexpr std::array<char, 8> VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'};
template <typename Container> template <typename Container>