Compare commits

..

7 commits

Author SHA1 Message Date
fdcd3ef393 [arm] Add "debugging" cpu accuracy option to replace CPU debug toggle
All checks were successful
eden-license / license-header (pull_request) Successful in 19s
The debug toggle and the CPU accuracy options are mutually exclusive, if debug toggle on => cpu accuracy is ignored, if debug toggle off => cpu accuracy is used. So just add it to cpu accuracy and avoid the extra hassle.

Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-10-02 23:23:53 +02:00
de594c8792
[dynarmic] add safe-opt to skip IR verification (#2613)
Most programs are well behaved and don't cause internal IR issues. Hence, verification can be safely skipped.

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

Reviewed-on: #2613
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-02 23:20:45 +02:00
2d8cb2d457
[file_sys] Properly fix the installation of new updates (#2651)
This removes the workaround and properly fix the installation of new updates.

Reviewed-on: #2651
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-02 22:48:52 +02:00
990a43a48c
[vk] Add missing flush per spec (#2624)
We copy pixels into a CPU-side staging buffer and then ask the GPU to read from it. On some systems those CPU writes aren’t automatically visible to the GPU unless explicitly flushed, so the GPU can sometimes read stale data. By calling buffer.Flush() immediately after writing, we force those CPU changes to become visible to the device, ensuring the GPU sees the latest frame. However, this is an emulator, so sometimes what spec says may not work cause reasons.

Co-authored-by: Ribbit <ribbit@placeholder.com>
Reviewed-on: #2624
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: Ribbit <ribbit@eden-emu.dev>
Co-committed-by: Ribbit <ribbit@eden-emu.dev>
2025-10-02 20:00:34 +02:00
1a5b3fb239
[audio_core] Fix audio reverb effect (#2646)
This fixes the audio reverb effect that was causing loud noise in some games and on some platforms.

Reviewed-on: #2646
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-02 01:30:05 +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
15 changed files with 64 additions and 46 deletions

View file

@ -165,12 +165,6 @@ Result InfoUpdater::UpdateEffectsVersion1(EffectContext& effect_context, const b
reinterpret_cast<EffectInfoBase::OutStatusVersion1*>(output), effect_count};
for (u32 i = 0; i < effect_count; i++) {
#ifdef _WIN32
// There's a bug in Windows where using this effect causes extreme noise. So let's skip it.
if (in_params[i].type == EffectInfoBase::Type::Reverb) {
continue;
}
#endif
auto effect_info{&effect_context.GetInfo(i)};
if (effect_info->GetType() != in_params[i].type) {
effect_info->ForceUnmapBuffers(pool_mapper);
@ -218,12 +212,6 @@ Result InfoUpdater::UpdateEffectsVersion2(EffectContext& effect_context, const b
reinterpret_cast<EffectInfoBase::OutStatusVersion2*>(output), effect_count};
for (u32 i = 0; i < effect_count; i++) {
#ifdef _WIN32
// There's a bug in Windows where using this effect causes extreme noise. So let's skip it.
if (in_params[i].type == EffectInfoBase::Type::Reverb) {
continue;
}
#endif
auto effect_info{&effect_context.GetInfo(i)};
if (effect_info->GetType() != in_params[i].type) {
effect_info->ForceUnmapBuffers(pool_mapper);

View file

@ -191,8 +191,6 @@ static void InitializeReverbEffect(const ReverbInfo::ParameterVersion2& params,
const auto center_delay_time{(5 * delay).to_uint_floor()};
state.center_delay_line.Initialize(center_delay_time, 1.0f);
UpdateReverbEffectParameter(params, state);
for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
std::ranges::fill(state.fdn_delay_lines[i].buffer, 0);
std::ranges::fill(state.decay_delay_lines[i].buffer, 0);

View file

@ -38,9 +38,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca)
reader = std::make_shared<NcaReader>();
if (Result rc = reader->Initialize(file, GetCryptoConfiguration(), GetNcaCompressionConfiguration()); R_FAILED(rc)) {
if (rc != ResultInvalidNcaSignature) {
LOG_ERROR(Loader, "File reader errored out during header read: {:#x}", rc.GetInnerValue());
}
status = Loader::ResultStatus::ErrorBadNCAHeader;
return;
}
@ -85,7 +82,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca)
for (s32 i = 0; i < fs_count; i++) {
NcaFsHeaderReader header_reader;
if (Result rc = fs.OpenStorage(&filesystems[i], &header_reader, i); R_FAILED(rc)) {
LOG_DEBUG(Loader, "File reader errored out during read of section {}: {:#x}", i, rc.GetInnerValue());
status = Loader::ResultStatus::ErrorBadNCAHeader;
return;
}

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-License-Identifier: GPL-2.0-or-later

View file

@ -1049,13 +1049,11 @@ Result NcaFileSystemDriver::CreatePatchMetaStorage(
ASSERT(out_aes_ctr_ex_meta != nullptr);
ASSERT(out_indirect_meta != nullptr);
ASSERT(base_storage != nullptr);
//ASSERT(patch_info.HasAesCtrExTable());
//ASSERT(patch_info.HasIndirectTable());
ASSERT(Common::IsAligned<s64>(patch_info.aes_ctr_ex_size, NcaHeader::XtsBlockSize));
// Validate patch info extents.
R_UNLESS(patch_info.indirect_size > 0, ResultInvalidNcaPatchInfoIndirectSize);
R_UNLESS(patch_info.aes_ctr_ex_size >= 0, ResultInvalidNcaPatchInfoAesCtrExSize);
R_UNLESS(patch_info.aes_ctr_ex_size >= 0 && patch_info.HasAesCtrExTable(), ResultInvalidNcaPatchInfoAesCtrExSize);
R_UNLESS(patch_info.indirect_size > 0 && patch_info.HasIndirectTable(), ResultInvalidNcaPatchInfoIndirectSize);
R_UNLESS(patch_info.indirect_size + patch_info.indirect_offset <= patch_info.aes_ctr_ex_offset,
ResultInvalidNcaPatchInfoAesCtrExOffset);
R_UNLESS(patch_info.aes_ctr_ex_offset + patch_info.aes_ctr_ex_size <=
@ -1333,10 +1331,30 @@ Result NcaFileSystemDriver::CreateIntegrityVerificationStorageImpl(
R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset,
ResultRomNcaInvalidIntegrityLayerInfoOffset);
}
storage_info[level_hash_info.max_layers - 1]
= std::make_shared<OffsetVfsFile>(std::move(base_storage),
layer_info.size,
last_layer_info_offset);
switch (level_hash_info.max_layers - 1) {
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::MasterStorage:
storage_info.SetMasterHashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer1Storage:
storage_info.SetLayer1HashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer2Storage:
storage_info.SetLayer2HashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer3Storage:
storage_info.SetLayer3HashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer4Storage:
storage_info.SetLayer4HashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer5Storage:
storage_info.SetLayer5HashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::DataStorage:
storage_info.SetDataStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
}
// Make the integrity romfs storage.
auto integrity_storage = std::make_shared<IntegrityRomFsStorage>();

View file

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

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
@ -34,6 +37,8 @@ enum class OptimizationFlag : std::uint32_t {
MiscIROpt = 0x00000020,
/// Optimize for code speed rather than for code size (this serves well for tight loops)
CodeSpeed = 0x00000040,
/// Disable verification passes
DisableVerification = 0x00000080,
/// This is an UNSAFE optimization that reduces accuracy of fused multiply-add operations.
/// This unfuses fused instructions to improve performance on host CPUs without FMA support.

View file

@ -1491,9 +1491,9 @@ void Optimize(IR::Block& block, const A32::UserConfig& conf, const Optimization:
Optimization::DeadCodeElimination(block);
}
Optimization::IdentityRemovalPass(block);
//if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
Optimization::VerificationPass(block);
//}
}
}
void Optimize(IR::Block& block, const A64::UserConfig& conf, const Optimization::PolyfillOptions& polyfill_options) {
@ -1511,9 +1511,9 @@ void Optimize(IR::Block& block, const A64::UserConfig& conf, const Optimization:
if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) [[likely]] {
Optimization::A64MergeInterpretBlocksPass(block, conf.callbacks);
}
//if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
Optimization::VerificationPass(block);
//}
}
}
} // namespace Dynarmic::Optimization

View file

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

View file

@ -233,7 +233,7 @@ bool DecoderContext::OpenContext(const Decoder& decoder) {
}
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));
return false;
}
@ -242,31 +242,31 @@ bool DecoderContext::SendPacket(const Packet& packet) {
}
std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
auto ReceiveImpl = [&](AVFrame* frame) -> bool {
if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0 && ret != AVERROR_EOF) {
auto ReceiveImpl = [&](AVFrame* frame) -> int {
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));
return false;
}
return true;
return ret;
};
std::shared_ptr<Frame> intermediate_frame = std::make_shared<Frame>();
if (!ReceiveImpl(intermediate_frame->GetFrame())) {
if (ReceiveImpl(intermediate_frame->GetFrame()) < 0) {
return {};
}
m_temp_frame = std::make_shared<Frame>();
m_final_frame = std::make_shared<Frame>();
if (m_codec_context->hw_device_ctx) {
m_temp_frame->SetFormat(PreferredGpuFormat);
if (int ret = av_hwframe_transfer_data(m_temp_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) {
m_final_frame->SetFormat(PreferredGpuFormat);
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));
return {};
}
} 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() {

View file

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

View file

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

View file

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

View file

@ -280,6 +280,7 @@ void Layer::UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t i
Tegra::Texture::UnswizzleTexture(
mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size),
bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0);
buffer.Flush(); // Ensure host writes are visible before the GPU copy.
}
const VkBufferImageCopy copy{

View file

@ -55,7 +55,7 @@ using VideoCommon::FileEnvironment;
using VideoCommon::GenericEnvironment;
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'};
template <typename Container>