Compare commits

..

4 Commits

Author SHA1 Message Date
lizzie 2f1f9be7a4 [common] remove assert extra newline (#3362)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3362
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: DraVee <dravee@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2026-01-26 17:21:57 +01:00
Maufeat c59d12b0cd [olsc] Rename Unknown27 to GetDataInfoV2 and fix crash on FW19 (#3387)
Thanks to FW19, I know that 27 is GetDataInfoV2. Fixes crash on FW19.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3387
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Maufeat <sahyno1996@gmail.com>
Co-committed-by: Maufeat <sahyno1996@gmail.com>
2026-01-26 16:04:09 +01:00
PavelBARABANOV 4a5bec1cfc [android, feat] add "Fix Bloom Effects" toggle (#3359)
- Toggle partially removes blur in Link's Awakening (LA) and Echoes of Wisdom (EOW) for turnip and stock drivers from A7XX and below.
- Burnout screen blur fix is now controlled by this toggle

Co-authored-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3359
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: DraVee <dravee@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Co-committed-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
2026-01-26 06:59:59 +01:00
MaranBr 4f6195881c [video_core] Fix 1x graphics bugs without performance loss (#3385)
This fixes weird lines at 1x resolution without impacting performance in some titles.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3385
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2026-01-26 03:36:30 +01:00
24 changed files with 72 additions and 76 deletions
@@ -16,6 +16,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
RENDERER_USE_SPEED_LIMIT("use_speed_limit"),
USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
FIX_BLOOM_EFFECTS("fix_bloom_effects"),
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
USE_DOCKED_MODE("use_docked_mode"),
USE_AUTO_STUB("use_auto_stub"),
@@ -719,6 +719,13 @@ abstract class SettingsItem(
descriptionId = R.string.skip_cpu_inner_invalidation_description
)
)
put(
SwitchSetting(
BooleanSetting.FIX_BLOOM_EFFECTS,
titleId = R.string.fix_bloom_effects,
descriptionId = R.string.fix_bloom_effects_description
)
)
put(
SwitchSetting(
BooleanSetting.CPUOPT_UNSAFE_HOST_MMU,
@@ -280,6 +280,7 @@ class SettingsFragmentPresenter(
add(IntSetting.FAST_GPU_TIME.key)
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
add(IntSetting.GPU_UNSWIZZLE_TEXTURE_SIZE.key)
add(IntSetting.GPU_UNSWIZZLE_STREAM_SIZE.key)
@@ -498,6 +498,8 @@
<string name="fast_gpu_time_description">Forces most games to run at their highest native resolution. Use 256 for maximal performance and 512 for maximal graphics fidelity.</string>
<string name="skip_cpu_inner_invalidation">Skip CPU Inner Invalidation</string>
<string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string>
<string name="fix_bloom_effects">Fix Bloom Effects</string>
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno 700), removes bloom in Burnout</string>
<string name="renderer_asynchronous_shaders">Use asynchronous shaders</string>
<string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches.</string>
<string name="gpu_unswizzle_texture_size">GPU Unswizzle Max Texture Size</string>
+7 -6
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project
@@ -16,6 +16,7 @@
void AssertFailSoftImpl();
[[noreturn]] void AssertFatalImpl();
// Prevents errors on old GCC... smh...
#ifdef _MSC_VER
#define YUZU_NO_INLINE __declspec(noinline)
#else
@@ -23,9 +24,9 @@ void AssertFailSoftImpl();
#endif
#define ASSERT_MSG(_a_, ...) \
([&]() YUZU_NO_INLINE { \
([&]() YUZU_NO_INLINE { \
if (!(_a_)) [[unlikely]] { \
LOG_CRITICAL(Debug, __FILE__ ": assert\n" __VA_ARGS__); \
LOG_CRITICAL(Debug, __FILE__ ": assert " __VA_ARGS__); \
AssertFailSoftImpl(); \
} \
}())
@@ -33,7 +34,7 @@ void AssertFailSoftImpl();
#define UNREACHABLE_MSG(...) \
do { \
LOG_CRITICAL(Debug, __FILE__ ": unreachable\n" __VA_ARGS__); \
LOG_CRITICAL(Debug, __FILE__ ": unreachable " __VA_ARGS__); \
AssertFatalImpl(); \
} while (0)
#define UNREACHABLE() UNREACHABLE_MSG("")
@@ -50,10 +51,10 @@ void AssertFailSoftImpl();
} while (0)
#endif
#define UNIMPLEMENTED() ASSERT_MSG(false, "Unimplemented code!")
#define UNIMPLEMENTED() ASSERT(false && "Unimplemented!")
#define UNIMPLEMENTED_MSG(...) ASSERT_MSG(false, __VA_ARGS__)
#define UNIMPLEMENTED_IF(cond) ASSERT_MSG(!(cond), "Unimplemented code!")
#define UNIMPLEMENTED_IF(cond) ASSERT((!(cond)) && "Unimplemented!")
#define UNIMPLEMENTED_IF_MSG(cond, ...) ASSERT_MSG(!(cond), __VA_ARGS__)
// If the assert is ignored, execute _b_
-4
View File
@@ -347,11 +347,7 @@ void TranslateResolutionInfo(ResolutionSetup setup, ResolutionScalingInfo& info)
}
info.up_factor = static_cast<f32>(info.up_scale) / (1U << info.down_shift);
info.down_factor = static_cast<f32>(1U << info.down_shift) / info.up_scale;
#ifdef __ANDROID__
info.active = info.up_scale != 1 || info.down_shift != 0;
#else
info.active = true;
#endif
}
void UpdateRescalingInfo() {
+3
View File
@@ -503,6 +503,9 @@ struct Values {
#endif
"async_presentation", Category::RendererHacks};
SwitchableSetting<bool> fix_bloom_effects{linkage, false, "fix_bloom_effects",
Category::RendererHacks};
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
Category::RendererHacks};
@@ -28,7 +28,7 @@ IRemoteStorageController::IRemoteStorageController(Core::System& system_)
{15, nullptr, "RegisterUploadSaveDataTransferTaskForAutonomyRegistration"},
{16, nullptr, "CreateCleanupToDeleteSaveDataArchiveInfoTask"},
{17, nullptr, "ListDataInfo"},
{18, nullptr, "GetDataInfo"},
{18, D<&IRemoteStorageController::GetDataInfo>, "GetDataInfoV1"},
{19, nullptr, "GetDataInfoCacheUpdateNativeHandleHolder"},
{20, nullptr, "CreateSaveDataArchiveInfoCacheForSaveDataBackupUpdationTask"},
{21, nullptr, "ListSecondarySaves"},
@@ -37,7 +37,7 @@ IRemoteStorageController::IRemoteStorageController(Core::System& system_)
{24, nullptr, "GetSecondarySaveDataInfo"},
{25, nullptr, "RegisterDownloadSaveDataTransferTaskForAutonomyRegistration"},
{26, nullptr, "Unknown26"}, //20.0.0+
{27, D<&IRemoteStorageController::Unknown27>, "Unknown27"}, //20.0.0+
{27, D<&IRemoteStorageController::GetDataInfo>, "GetDataInfoV2"}, //20.0.0+
{28, nullptr, "Unknown28"}, //20.0.0+
{29, nullptr, "Unknown29"}, //21.0.0+
{800, nullptr, "Unknown800"}, //20.0.0+
@@ -67,7 +67,7 @@ Result IRemoteStorageController::GetDataNewnessByApplicationId(Out<u8> out_newne
R_SUCCEED();
}
Result IRemoteStorageController::Unknown27(Out<std::array<u8, 0x38>> out_data, u64 application_id) {
Result IRemoteStorageController::GetDataInfo(Out<std::array<u8, 0x38>> out_data, u64 application_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, application_id={:016X}", application_id);
out_data->fill(0);
R_SUCCEED();
@@ -18,7 +18,7 @@ private:
Result GetSecondarySave(Out<bool> out_has_secondary_save, Out<std::array<u64, 3>> out_unknown,
u64 application_id);
Result GetDataNewnessByApplicationId(Out<u8> out_newness, u64 application_id);
Result Unknown27(Out<std::array<u8, 0x38>> out_data, u64 application_id);
Result GetDataInfo(Out<std::array<u8, 0x38>> out_data, u64 application_id);
};
} // namespace Service::OLSC
@@ -329,6 +329,10 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
barrier_feedback_loops,
tr("Barrier feedback loops"),
tr("Improves rendering of transparency effects in specific games."));
INSERT(Settings,
fix_bloom_effects,
tr("Fix bloom effects"),
tr("Removes bloom in Burnout."));
// Renderer (Extensions)
INSERT(Settings, dyna_state, tr("Extended Dynamic State"),
@@ -1,8 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <boost/container/static_vector.hpp>
#include "common/settings.h"
#include "shader_recompiler/backend/spirv/emit_spirv.h"
#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h"
#include "shader_recompiler/backend/spirv/spirv_emit_context.h"
@@ -471,9 +475,16 @@ Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
Id lod, const IR::Value& offset) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
const ImageOperands operands(ctx, false, true, false, lod, offset);
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
Id result = Emit(&EmitContext::OpImageSparseSampleExplicitLod,
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
#ifdef ANDROID
if (Settings::values.fix_bloom_effects.GetValue()) {
result = ctx.OpVectorTimesScalar(ctx.F32[4], result, ctx.Const(0.98f));
}
#endif
return result;
}
Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -304,9 +304,17 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
Optimization::GlobalMemoryToStorageBufferPass(program, host_info);
Optimization::TexturePass(env, program, host_info);
if (Settings::values.resolution_info.active) {
bool should_rescale =
#ifdef __ANDROID__
Settings::values.resolution_info.active;
#else
true;
#endif
if (should_rescale) {
Optimization::RescalingPass(program);
}
Optimization::DeadCodeEliminationPass(program);
if (Settings::values.renderer_debug) {
Optimization::VerificationPass(program);
+3
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -97,28 +97,8 @@ VkDescriptorSet DescriptorAllocator::Commit() {
return sets[index / SETS_GROW_RATE][index % SETS_GROW_RATE];
}
VkDescriptorSet DescriptorAllocator::CommitWithTracking(u64 current_frame, const void* descriptor_data) {
const size_t index = CommitResource();
const size_t group = index / SETS_GROW_RATE;
const size_t slot = index % SETS_GROW_RATE;
set_states[group][slot].set = sets[group][slot];
set_states[group][slot].last_update_frame = current_frame;
set_states[group][slot].last_data_ptr = descriptor_data;
return set_states[group][slot].set;
}
bool DescriptorAllocator::NeedsUpdate(VkDescriptorSet set, u64 current_frame, const void* descriptor_data) const {
for (const auto& group : set_states)
for (const auto& st : group)
if (st.set == set) // Update if pointer changed or the set hasn't been updated this frame
return st.last_data_ptr != descriptor_data || st.last_update_frame != current_frame;
return true;
}
void DescriptorAllocator::Allocate(size_t begin, size_t end) {
const size_t count = end - begin;
sets.push_back(AllocateDescriptors(count));
set_states.emplace_back(count); // create parallel state storage
sets.push_back(AllocateDescriptors(end - begin));
}
vk::DescriptorSets DescriptorAllocator::AllocateDescriptors(size_t count) {
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -9,7 +6,7 @@
#include <shared_mutex>
#include <span>
#include <vector>
#include "common/common_types.h"
#include "shader_recompiler/shader_info.h"
#include "video_core/renderer_vulkan/vk_resource_pool.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
@@ -47,15 +44,7 @@ public:
DescriptorAllocator(const DescriptorAllocator&) = delete;
VkDescriptorSet Commit();
// commit + remember when/with what we last updated this set
struct DescriptorSetState {
VkDescriptorSet set = VK_NULL_HANDLE;
u64 last_update_frame = 0;
const void* last_data_ptr = nullptr; // fast pointer compare
};
VkDescriptorSet CommitWithTracking(u64 current_frame, const void* descriptor_data);
bool NeedsUpdate(VkDescriptorSet set, u64 current_frame, const void* descriptor_data) const;
private:
explicit DescriptorAllocator(const Device& device_, MasterSemaphore& master_semaphore_,
DescriptorBank& bank_, VkDescriptorSetLayout layout_);
@@ -69,7 +58,6 @@ private:
VkDescriptorSetLayout layout{};
std::vector<vk::DescriptorSets> sets;
std::vector<std::vector<DescriptorSetState>> set_states;
};
class DescriptorPool {
@@ -514,20 +514,7 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling,
const bool update_rescaling{scheduler.UpdateRescaling(is_rescaling)};
const bool bind_pipeline{scheduler.UpdateGraphicsPipeline(this)};
const void* const descriptor_data{guest_descriptor_queue.UpdateData()};
// allocate/bind descriptor set and only update if needed
VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
bool needs_update = false;
if (descriptor_set_layout && !uses_push_descriptor) {
descriptor_set = descriptor_allocator.CommitWithTracking(current_frame_number, descriptor_data);
needs_update = descriptor_allocator.NeedsUpdate(descriptor_set, current_frame_number, descriptor_data);
if (needs_update) {
const vk::Device& dev{device.GetLogical()};
dev.UpdateDescriptorSet(descriptor_set, *descriptor_update_template, descriptor_data);
}
}
scheduler.Record([this, descriptor_data, descriptor_set, bind_pipeline, rescaling_data = rescaling.Data(),
scheduler.Record([this, descriptor_data, bind_pipeline, rescaling_data = rescaling.Data(),
is_rescaling, update_rescaling,
uses_render_area = render_area.uses_render_area,
render_area_data = render_area.words](vk::CommandBuffer cmdbuf) {
@@ -553,8 +540,12 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling,
return;
}
if (uses_push_descriptor) {
cmdbuf.PushDescriptorSetWithTemplateKHR(*descriptor_update_template, *pipeline_layout, 0, descriptor_data);
cmdbuf.PushDescriptorSetWithTemplateKHR(*descriptor_update_template, *pipeline_layout,
0, descriptor_data);
} else {
const VkDescriptorSet descriptor_set{descriptor_allocator.Commit()};
const vk::Device& dev{device.GetLogical()};
dev.UpdateDescriptorSet(descriptor_set, *descriptor_update_template, descriptor_data);
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline_layout, 0,
descriptor_set, nullptr);
}
@@ -127,7 +127,7 @@ public:
maxwell3d = maxwell3d_;
gpu_memory = gpu_memory_;
}
void SetFrameNumber(u64 frame) { current_frame_number = frame; }
private:
template <typename Spec>
bool ConfigureImpl(bool is_indexed);
@@ -172,7 +172,6 @@ private:
std::mutex build_mutex;
std::atomic_bool is_built{false};
bool uses_push_descriptor{false};
u64 current_frame_number{0};
};
} // namespace Vulkan
@@ -222,7 +222,6 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) {
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
// update engine as channel may be different.
pipeline->SetEngine(maxwell3d, gpu_memory);
pipeline->SetFrameNumber(current_frame_number);
if (!pipeline->Configure(is_indexed))
return;
@@ -807,7 +806,6 @@ void RasterizerVulkan::FlushCommands() {
}
void RasterizerVulkan::TickFrame() {
current_frame_number++;
draw_counter = 0;
guest_descriptor_queue.TickFrame();
compute_pass_descriptor_queue.TickFrame();
@@ -160,7 +160,7 @@ private:
void UpdateDynamicStates();
void HandleTransformFeedback();
u64 current_frame_number{0};
void UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs);
@@ -1313,7 +1313,7 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im
case PixelFormat::R32G32_FLOAT:
case PixelFormat::R32G32_SINT:
case PixelFormat::R32_FLOAT:
if (src_view.format == PixelFormat::D32_FLOAT) {
if ((src_view.format == PixelFormat::D32_FLOAT) && Settings::values.fix_bloom_effects.GetValue()) {
const Region2D region{
.start = {0, 0},
.end = {static_cast<s32>(dst->RenderArea().width),
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project