diff --git a/CMakeLists.txt b/CMakeLists.txt index 411de4620b..994bc184fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -310,6 +310,7 @@ endif() if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX)) set(HAS_NCE 1) add_compile_definitions(HAS_NCE=1) + find_package(oaknut 2.0.1) endif() if (YUZU_ROOM) diff --git a/CMakeModules/Findsirit.cmake b/CMakeModules/Findsirit.cmake deleted file mode 100644 index 83b81b09c5..0000000000 --- a/CMakeModules/Findsirit.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - -include(FindPackageHandleStandardArgs) - -find_package(PkgConfig QUIET) -pkg_search_module(sirit QUIET IMPORTED_TARGET sirit) -find_package_handle_standard_args(sirit - REQUIRED_VARS sirit_LINK_LIBRARIES - VERSION_VAR sirit_VERSION -) diff --git a/externals/cpmfile.json b/externals/cpmfile.json index 283da76743..dcafc8f97d 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -10,7 +10,7 @@ "repo": "eden-emulator/sirit", "sha": "db1f1e8ab5", "hash": "73eb3a042848c63a10656545797e85f40d142009dfb7827384548a385e1e28e1ac72f42b25924ce530d58275f8638554281e884d72f9c7aaf4ed08690a414b05", - "find_args": "MODULE", + "find_args": "CONFIG", "options": [ "SIRIT_USE_SYSTEM_SPIRV_HEADERS ON" ] diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 7759ea6a21..96ea429e5a 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -32,7 +32,6 @@ add_library( atomic_ops.h bit_cast.h bit_field.h - bit_set.h bit_util.h bounded_threadsafe_queue.h cityhash.cpp diff --git a/src/common/bit_set.h b/src/common/bit_set.h deleted file mode 100644 index 74754504be..0000000000 --- a/src/common/bit_set.h +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include - -#include "common/alignment.h" -#include "common/bit_util.h" -#include "common/common_types.h" - -namespace Common { - -namespace impl { - -template -class BitSet { - -public: - constexpr BitSet() = default; - - constexpr void SetBit(size_t i) { - this->words[i / FlagsPerWord] |= GetBitMask(i % FlagsPerWord); - } - - constexpr void ClearBit(size_t i) { - this->words[i / FlagsPerWord] &= ~GetBitMask(i % FlagsPerWord); - } - - constexpr size_t CountLeadingZero() const { - for (size_t i = 0; i < NumWords; i++) { - if (this->words[i]) { - return FlagsPerWord * i + CountLeadingZeroImpl(this->words[i]); - } - } - return FlagsPerWord * NumWords; - } - - constexpr size_t GetNextSet(size_t n) const { - for (size_t i = (n + 1) / FlagsPerWord; i < NumWords; i++) { - Storage word = this->words[i]; - if (!IsAligned(n + 1, FlagsPerWord)) { - word &= GetBitMask(n % FlagsPerWord) - 1; - } - if (word) { - return FlagsPerWord * i + CountLeadingZeroImpl(word); - } - } - return FlagsPerWord * NumWords; - } - -private: - static_assert(std::is_unsigned_v); - static_assert(sizeof(Storage) <= sizeof(u64)); - - static constexpr size_t FlagsPerWord = BitSize(); - static constexpr size_t NumWords = AlignUp(N, FlagsPerWord) / FlagsPerWord; - - static constexpr auto CountLeadingZeroImpl(Storage word) { - return std::countl_zero(static_cast(word)) - - (BitSize() - FlagsPerWord); - } - - static constexpr Storage GetBitMask(size_t bit) { - return Storage(1) << (FlagsPerWord - 1 - bit); - } - - std::array words{}; -}; - -} // namespace impl - -template -using BitSet8 = impl::BitSet; - -template -using BitSet16 = impl::BitSet; - -template -using BitSet32 = impl::BitSet; - -template -using BitSet64 = impl::BitSet; - -} // namespace Common diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 6b64ab7820..11c217fce6 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1224,7 +1224,7 @@ if (HAS_NCE) arm/nce/patcher.h arm/nce/visitor_base.h ) - target_link_libraries(core PRIVATE merry::mcl merry::oaknut) + target_link_libraries(core PRIVATE merry::oaknut) endif() if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) diff --git a/src/core/arm/nce/patcher.h b/src/core/arm/nce/patcher.h index 7f54608e3f..31b122477f 100644 --- a/src/core/arm/nce/patcher.h +++ b/src/core/arm/nce/patcher.h @@ -27,11 +27,11 @@ template <> struct std::hash { size_t operator()(const PatchCacheKey& key) const { // Simple XOR hash of first few bytes - size_t hash = 0; + size_t hash_ = 0; for (size_t i = 0; i < key.module_id.size(); ++i) { - hash ^= static_cast(key.module_id[i]) << ((i % sizeof(size_t)) * 8); + hash_ ^= static_cast(key.module_id[i]) << ((i % sizeof(size_t)) * 8); } - return hash ^ std::hash{}(key.offset); + return hash_ ^ std::hash{}(key.offset); } }; diff --git a/src/core/hle/kernel/k_priority_queue.h b/src/core/hle/kernel/k_priority_queue.h index 26677ec65c..99347b5aef 100644 --- a/src/core/hle/kernel/k_priority_queue.h +++ b/src/core/hle/kernel/k_priority_queue.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -5,10 +8,12 @@ #include #include +#include #include +#include +#include "common/alignment.h" #include "common/assert.h" -#include "common/bit_set.h" #include "common/common_types.h" #include "common/concepts.h" @@ -159,7 +164,7 @@ public: } if (m_queues[priority].PushBack(core, member)) { - m_available_priorities[core].SetBit(priority); + m_available_priorities[core].set(std::size_t(priority)); } } @@ -172,7 +177,7 @@ public: } if (m_queues[priority].PushFront(core, member)) { - m_available_priorities[core].SetBit(priority); + m_available_priorities[core].set(std::size_t(priority)); } } @@ -185,14 +190,19 @@ public: } if (m_queues[priority].Remove(core, member)) { - m_available_priorities[core].ClearBit(priority); + m_available_priorities[core].reset(std::size_t(priority)); } } constexpr Member* GetFront(s32 core) const { ASSERT(IsValidCore(core)); - const s32 priority = static_cast(m_available_priorities[core].CountLeadingZero()); + const s32 priority = s32([](auto const& e) { + for (size_t i = 0; i < e.size(); ++i) + if (e[i]) + return i; + return e.size(); + }(m_available_priorities[core])); if (priority <= LowestPriority) { return m_queues[priority].GetFront(core); } else { @@ -211,16 +221,22 @@ public: } } + template + constexpr size_t GetNextSet(std::bitset const& bit, size_t n) const { + for (size_t i = n + 1; i < bit.size(); i++) + if (bit[i]) + return i; + return bit.size(); + } + constexpr Member* GetNext(s32 core, const Member* member) const { ASSERT(IsValidCore(core)); Member* next = member->GetPriorityQueueEntry(core).GetNext(); if (next == nullptr) { - const s32 priority = static_cast( - m_available_priorities[core].GetNextSet(member->GetPriority())); - if (priority <= LowestPriority) { + s32 priority = s32(GetNextSet(m_available_priorities[core], member->GetPriority())); + if (priority <= LowestPriority) next = m_queues[priority].GetFront(core); - } } return next; } @@ -250,7 +266,7 @@ public: private: std::array m_queues{}; - std::array, NumCores> m_available_priorities{}; + std::array, NumCores> m_available_priorities{}; }; private: diff --git a/src/dynarmic/src/dynarmic/CMakeLists.txt b/src/dynarmic/src/dynarmic/CMakeLists.txt index 3155a1cda1..34cbc308be 100644 --- a/src/dynarmic/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/src/dynarmic/CMakeLists.txt @@ -370,7 +370,7 @@ endif() target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS}) target_link_libraries(dynarmic - PRIVATE + PUBLIC fmt::fmt merry::mcl ) diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 94ef1a48df..eb18a4bd66 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -792,6 +792,11 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 const u32 size = (std::min)(binding.size, (*channel_state->uniform_buffer_sizes)[stage][index]); Buffer& buffer = slot_buffers[binding.buffer_id]; TouchBuffer(buffer, binding.buffer_id); + const bool sync_buffer = SynchronizeBuffer(buffer, device_addr, size); + if (sync_buffer) { + ++channel_state->uniform_cache_hits[0]; + } + ++channel_state->uniform_cache_shots[0]; const bool use_fast_buffer = binding.buffer_id != NULL_BUFFER_ID && size <= channel_state->uniform_buffer_skip_cache_size && !memory_tracker.IsRegionGpuModified(device_addr, size); @@ -822,12 +827,6 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 device_memory.ReadBlockUnsafe(device_addr, span.data(), size); return; } - // Classic cached path - const bool sync_cached = SynchronizeBuffer(buffer, device_addr, size); - if (sync_cached) { - ++channel_state->uniform_cache_hits[0]; - } - ++channel_state->uniform_cache_shots[0]; // Skip binding if it's not needed and if the bound buffer is not the fast version // This exists to avoid instances where the fast buffer is bound and a GPU write happens