Compare commits

..

5 Commits

Author SHA1 Message Date
CamilleLaVey
fa07d25b7f [vk, pipeline] Added In-flight conditional for multiple pipeline compilations 2025-12-24 16:43:21 -03:00
Caio Oliveira
00ec67d65b [android] Properly set Root of the Project (#3177)
Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3177
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-committed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-12-23 22:23:56 +01:00
Marcin Serwin
fbd28a9d34 [cmake] fix dynarmic tests (#3192)
The old style `add_test` invocation is not target aware which means that
trying to run the test via `ninja test` results in:

    Could not find executable dynarmic_tests

Signed-off-by: Marcin Serwin <marcin@serwin.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3192
Co-authored-by: Marcin Serwin <marcin@serwin.dev>
Co-committed-by: Marcin Serwin <marcin@serwin.dev>
2025-12-23 01:34:58 +01:00
Caio Oliveira
3413fbd9da [FIXUP] Partially revert "[NCE] Fix cache invalidation and signal interrupt race condition (#3063)" (#3190)
* this fixes Jamboree and SSB

This reverts commit e3c942b209.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3190
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-committed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-12-22 02:58:40 +01:00
SDK Chan
bccc46a325 [src/dynarmic] Fix No member named 'join' in namespace 'fmt' (#3188)
Clang seems to complain that fmt doesn't have a member named join so, it fails to build.
Including fmt/ranges.h fixes that, and lets eden be buildable again.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3188
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: SDK Chan <sdkchan@eden-emu.dev>
Co-committed-by: SDK Chan <sdkchan@eden-emu.dev>
2025-12-21 17:28:49 +01:00
7 changed files with 129 additions and 27 deletions

View File

@@ -18,6 +18,7 @@ plugins {
id("androidx.navigation.safeargs.kotlin")
id("org.jlleitschuh.gradle.ktlint") version "11.4.0"
id("com.github.triplet.play") version "3.8.6"
id("idea")
}
/**
@@ -27,6 +28,8 @@ plugins {
*/
val autoVersion = (((System.currentTimeMillis() / 1000) - 1451606400) / 10).toInt()
val edenDir = project(":Eden").projectDir
@Suppress("UnstableApiUsage")
android {
namespace = "org.yuzu.yuzu_emu"
@@ -241,11 +244,17 @@ android {
externalNativeBuild {
cmake {
version = "3.22.1"
path = file("../../../CMakeLists.txt")
path = file("${edenDir}/CMakeLists.txt")
}
}
}
idea {
module {
// Inclusion to exclude build/ dir from non-Android
excludeDirs.add(file("${edenDir}/build"))
}
}
tasks.register<Delete>("ktlintReset", fun Delete.() {
delete(File(layout.buildDirectory.toString() + File.separator + "intermediates/ktLint"))
@@ -346,7 +355,7 @@ fun getGitVersion(): String {
}
afterEvaluate {
val artifactsDir = layout.projectDirectory.dir("../../../artifacts")
val artifactsDir = layout.projectDirectory.dir("${edenDir}/artifacts")
val outputsDir = layout.buildDirectory.dir("outputs").get()
android.applicationVariants.forEach { variant ->

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -19,3 +22,6 @@ dependencyResolutionManagement {
}
include(":app")
include("Eden")
project(":Eden").projectDir = file("../..")

View File

@@ -391,28 +391,15 @@ const std::size_t CACHE_PAGE_SIZE = 4096;
void ArmNce::ClearInstructionCache() {
#ifdef __aarch64__
// Use IC IALLU to actually invalidate L1 instruction cache
// Ensure all previous memory operations complete
asm volatile("dsb ish\n"
"ic iallu\n"
"dsb ish\n"
"isb" ::: "memory");
#endif
}
void ArmNce::InvalidateCacheRange(u64 addr, std::size_t size) {
#ifdef ARCHITECTURE_arm64
// Invalidate instruction cache for specific range instead of full flush
constexpr u64 cache_line_size = 64;
const u64 aligned_addr = addr & ~(cache_line_size - 1);
const u64 end_addr = (addr + size + cache_line_size - 1) & ~(cache_line_size - 1);
asm volatile("dsb ish" ::: "memory");
for (u64 i = aligned_addr; i < end_addr; i += cache_line_size) {
asm volatile("ic ivau, %0" :: "r"(i) : "memory");
}
asm volatile("dsb ish\n"
"isb" ::: "memory");
#endif
this->ClearInstructionCache();
}
} // namespace Core

View File

@@ -134,4 +134,4 @@ target_include_directories(dynarmic_tests PRIVATE . ../src)
target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS})
target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
add_test(dynarmic_tests dynarmic_tests --durations yes)
add_test(NAME dynarmic_tests COMMAND dynarmic_tests --durations yes)

View File

@@ -17,6 +17,7 @@
#include <fmt/format.h>
#include <fmt/ostream.h>
#include <fmt/ranges.h>
#include <mcl/bit/swap.hpp>
#include "dynarmic/common/common_types.h"

View File

@@ -451,12 +451,17 @@ ComputePipeline* PipelineCache::CurrentComputePipeline() {
.shared_memory_size = qmd.shared_alloc,
.workgroup_size{qmd.block_dim_x, qmd.block_dim_y, qmd.block_dim_z},
};
const auto [pair, is_new]{compute_cache.try_emplace(key)};
const auto [pair, inserted]{compute_cache.try_emplace(key)};
auto& pipeline{pair->second};
if (!is_new) {
return pipeline.get();
if (!pipeline) {
auto [slot, should_build] = AcquireComputeBuildSlot(key);
if (!should_build) {
WaitForBuildCompletion(slot);
} else {
pipeline = CreateComputePipeline(key, shader);
ReleaseComputeBuildSlot(key, slot);
}
}
pipeline = CreateComputePipeline(key, shader);
return pipeline.get();
}
@@ -572,13 +577,20 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
}
GraphicsPipeline* PipelineCache::CurrentGraphicsPipelineSlowPath() {
const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)};
const auto [pair, inserted]{graphics_cache.try_emplace(graphics_key)};
auto& pipeline{pair->second};
if (is_new) {
pipeline = CreateGraphicsPipeline();
}
if (!pipeline) {
return nullptr;
const auto key = pair->first;
auto [slot, should_build] = AcquireGraphicsBuildSlot(key);
if (!should_build) {
WaitForBuildCompletion(slot);
} else {
pipeline = CreateGraphicsPipeline();
ReleaseGraphicsBuildSlot(key, slot);
}
if (!pipeline) {
return nullptr;
}
}
if (current_pipeline) {
current_pipeline->AddTransition(pipeline.get());
@@ -879,4 +891,68 @@ vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem::
}
}
auto PipelineCache::AcquireGraphicsBuildSlot(const GraphicsPipelineCacheKey& key)
-> std::pair<InFlightPipelinePtr, bool> {
std::scoped_lock lock(graphics_inflight_mutex);
auto [it, inserted] = graphics_inflight_builds.try_emplace(key);
if (inserted || !it->second) {
it->second = std::make_shared<InFlightPipelineBuild>();
return {it->second, true};
}
return {it->second, false};
}
auto PipelineCache::AcquireComputeBuildSlot(const ComputePipelineCacheKey& key)
-> std::pair<InFlightPipelinePtr, bool> {
std::scoped_lock lock(compute_inflight_mutex);
auto [it, inserted] = compute_inflight_builds.try_emplace(key);
if (inserted || !it->second) {
it->second = std::make_shared<InFlightPipelineBuild>();
return {it->second, true};
}
return {it->second, false};
}
void PipelineCache::ReleaseGraphicsBuildSlot(const GraphicsPipelineCacheKey& key,
const InFlightPipelinePtr& slot) {
if (!slot) {
return;
}
{
std::scoped_lock slot_lock(slot->mutex);
slot->building = false;
}
slot->cv.notify_all();
std::scoped_lock map_lock(graphics_inflight_mutex);
auto it = graphics_inflight_builds.find(key);
if (it != graphics_inflight_builds.end() && it->second == slot) {
graphics_inflight_builds.erase(it);
}
}
void PipelineCache::ReleaseComputeBuildSlot(const ComputePipelineCacheKey& key,
const InFlightPipelinePtr& slot) {
if (!slot) {
return;
}
{
std::scoped_lock slot_lock(slot->mutex);
slot->building = false;
}
slot->cv.notify_all();
std::scoped_lock map_lock(compute_inflight_mutex);
auto it = compute_inflight_builds.find(key);
if (it != compute_inflight_builds.end() && it->second == slot) {
compute_inflight_builds.erase(it);
}
}
void PipelineCache::WaitForBuildCompletion(const InFlightPipelinePtr& slot) const {
if (!slot) {
return;
}
std::unique_lock lock(slot->mutex);
slot->cv.wait(lock, [&] { return !slot->building; });
}
} // namespace Vulkan

View File

@@ -5,8 +5,10 @@
#include <array>
#include <cstddef>
#include <condition_variable>
#include <filesystem>
#include <memory>
#include <mutex>
#include <type_traits>
#include <unordered_map>
#include <vector>
@@ -114,6 +116,14 @@ public:
const VideoCore::DiskResourceLoadCallback& callback);
private:
struct InFlightPipelineBuild {
std::mutex mutex;
std::condition_variable cv;
bool building{true};
};
using InFlightPipelinePtr = std::shared_ptr<InFlightPipelineBuild>;
[[nodiscard]] GraphicsPipeline* CurrentGraphicsPipelineSlowPath();
[[nodiscard]] GraphicsPipeline* BuiltPipeline(GraphicsPipeline* pipeline) const noexcept;
@@ -140,6 +150,14 @@ private:
vk::PipelineCache LoadVulkanPipelineCache(const std::filesystem::path& filename,
u32 expected_cache_version);
std::pair<InFlightPipelinePtr, bool> AcquireGraphicsBuildSlot(
const GraphicsPipelineCacheKey& key);
std::pair<InFlightPipelinePtr, bool> AcquireComputeBuildSlot(
const ComputePipelineCacheKey& key);
void ReleaseGraphicsBuildSlot(const GraphicsPipelineCacheKey& key, const InFlightPipelinePtr& slot);
void ReleaseComputeBuildSlot(const ComputePipelineCacheKey& key, const InFlightPipelinePtr& slot);
void WaitForBuildCompletion(const InFlightPipelinePtr& slot) const;
const Device& device;
Scheduler& scheduler;
DescriptorPool& descriptor_pool;
@@ -158,6 +176,11 @@ private:
std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<ComputePipeline>> compute_cache;
std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<GraphicsPipeline>> graphics_cache;
std::mutex graphics_inflight_mutex;
std::unordered_map<GraphicsPipelineCacheKey, InFlightPipelinePtr> graphics_inflight_builds;
std::mutex compute_inflight_mutex;
std::unordered_map<ComputePipelineCacheKey, InFlightPipelinePtr> compute_inflight_builds;
ShaderPools main_pools;
Shader::Profile profile;