diff --git a/src/xenia/base/clock.cc b/src/xenia/base/clock.cc index 527c5eb6b..cd9e23674 100644 --- a/src/xenia/base/clock.cc +++ b/src/xenia/base/clock.cc @@ -39,6 +39,14 @@ double guest_time_scalar_ = 1.0; uint64_t guest_tick_frequency_ = Clock::host_tick_frequency_platform(); // Base FILETIME of the guest system from app start. uint64_t guest_system_time_base_ = Clock::QueryHostSystemTime(); + +std::pair guest_system_time_ratio_ = + []() -> std::pair { + std::pair frac(uint64_t(10000000), guest_tick_frequency_); + reduce_fraction(frac); + return frac; +}(); + // Combined time and frequency ratio between host and guest. // Split in numerator (first) and denominator (second). // Computed by RecomputeGuestTickScalar. @@ -55,6 +63,13 @@ using tick_mutex_type = std::mutex; // std::mutex tick_mutex_; static tick_mutex_type tick_mutex_; +static void RecomputeGuestSystemTimeRatio() { + std::pair frac(uint64_t(10000000), guest_tick_frequency_); + reduce_fraction(frac); + std::lock_guard lock(tick_mutex_); + guest_system_time_ratio_ = frac; +} + void RecomputeGuestTickScalar() { // Create a rational number with numerator (first) and denominator (second) auto frac = @@ -111,11 +126,8 @@ inline uint64_t QueryGuestSystemTimeOffset() { auto guest_tick_count = UpdateGuestClock(); - uint64_t numerator = 10000000; // 100ns/10MHz resolution - uint64_t denominator = guest_tick_frequency_; - reduce_fraction(numerator, denominator); - - return guest_tick_count * numerator / denominator; + return guest_tick_count * guest_system_time_ratio_.first / + guest_system_time_ratio_.second; } uint64_t Clock::QueryHostTickFrequency() { #if XE_CLOCK_RAW_AVAILABLE @@ -154,6 +166,7 @@ uint64_t Clock::guest_tick_frequency() { return guest_tick_frequency_; } void Clock::set_guest_tick_frequency(uint64_t frequency) { guest_tick_frequency_ = frequency; + RecomputeGuestSystemTimeRatio(); RecomputeGuestTickScalar(); } diff --git a/src/xenia/base/string_buffer.h b/src/xenia/base/string_buffer.h index 9a4743deb..215fe45b6 100644 --- a/src/xenia/base/string_buffer.h +++ b/src/xenia/base/string_buffer.h @@ -36,7 +36,7 @@ class StringBuffer { template void AppendFormat(const char* format, const Args&... args) { auto s = fmt::format(fmt::runtime(format), args...); - Append(s.c_str()); + Append(std::string_view(s)); } void AppendVarargs(const char* format, va_list args); diff --git a/src/xenia/cpu/backend/x64/x64_sequences.cc b/src/xenia/cpu/backend/x64/x64_sequences.cc index 34962582b..29c885add 100644 --- a/src/xenia/cpu/backend/x64/x64_sequences.cc +++ b/src/xenia/cpu/backend/x64/x64_sequences.cc @@ -3310,7 +3310,7 @@ bool SelectSequence(X64Emitter* e, const Instr* i, const Instr** new_tail) { auto it = sequence_table.find(key); if (it != sequence_table.end()) { - if (it->second(*e, i, InstrKey(i))) { + if (it->second(*e, i, key)) { *new_tail = i->next; return true; } diff --git a/src/xenia/gpu/render_target_cache.cc b/src/xenia/gpu/render_target_cache.cc index 17af8b42a..5810c1ccf 100644 --- a/src/xenia/gpu/render_target_cache.cc +++ b/src/xenia/gpu/render_target_cache.cc @@ -1624,7 +1624,7 @@ void RenderTargetCache::ChangeOwnership( if (it_pre->second.end_tiles > extent_start && !it_pre->second.IsOwnedBy(dest, host_depth_encoding_different)) { // Different render target overlapping the range - split the head. - ownership_ranges_.emplace(extent_start, it_pre->second); + ownership_ranges_.emplace_hint(it, extent_start, it_pre->second); it_pre->second.end_tiles = extent_start; // Let the next loop do the transfer and needed merging and splitting // starting from the added tail. @@ -1646,7 +1646,7 @@ void RenderTargetCache::ChangeOwnership( // (split in this case) or within it. if (it->second.end_tiles > extent_end) { // Split the tail. - ownership_ranges_.emplace(extent_end, it->second); + ownership_ranges_.emplace_hint(std::next(it), extent_end, it->second); it->second.end_tiles = extent_end; } if (transfers_append_out) { diff --git a/src/xenia/gpu/texture_cache.h b/src/xenia/gpu/texture_cache.h index ac03a329e..dd3a053d3 100644 --- a/src/xenia/gpu/texture_cache.h +++ b/src/xenia/gpu/texture_cache.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "xenia/base/assert.h" @@ -205,13 +206,8 @@ class TextureCache { uint32_t is_valid : 1; // 98 TextureKey() { MakeInvalid(); } - TextureKey(const TextureKey& key) { - std::memcpy(this, &key, sizeof(*this)); - } - TextureKey& operator=(const TextureKey& key) { - std::memcpy(this, &key, sizeof(*this)); - return *this; - } + TextureKey(const TextureKey&) = default; + TextureKey& operator=(const TextureKey&) = default; void MakeInvalid() { // Zero everything, including the padding, for a stable hash. std::memset(this, 0, sizeof(*this)); @@ -252,6 +248,10 @@ class TextureCache { } void LogAction(const char* action) const; }; + static_assert( + std::is_trivially_copyable_v, + "TextureKey is compared and hashed by raw bytes; a trivial copy " + "is required so padding is carried and stays zero."); class Texture { public: diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index 0bb1786ea..4a243539f 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -556,7 +556,13 @@ struct ExportRegistrerHelper { if (TAGS & xe::cpu::ExportTag::kLog && (!(TAGS & xe::cpu::ExportTag::kHighFrequency) || cvars::log_high_frequency_kernel_calls)) { - PrintKernelCall(export_entry, params); + const LogLevel needed_level = + (export_entry->tags & xe::cpu::ExportTag::kImportant) + ? LogLevel::Info + : LogLevel::Debug; + if (logging::ShouldLog(needed_level, LogSrc::Kernel)) { + PrintKernelCall(export_entry, params); + } } if constexpr (std::is_void::value) { KernelTrampoline(fn, std::forward>(params),