diff options
Diffstat (limited to 'src')
29 files changed, 225 insertions, 81 deletions
diff --git a/src/common/fs/file.h b/src/common/fs/file.h index 2c4ab4332..a4f7944cd 100644 --- a/src/common/fs/file.h +++ b/src/common/fs/file.h @@ -188,9 +188,8 @@ public: #ifdef _WIN32 template <typename Path> - [[nodiscard]] void Open(const Path& path, FileAccessMode mode, - FileType type = FileType::BinaryFile, - FileShareFlag flag = FileShareFlag::ShareReadOnly) { + void Open(const Path& path, FileAccessMode mode, FileType type = FileType::BinaryFile, + FileShareFlag flag = FileShareFlag::ShareReadOnly) { using ValueType = typename Path::value_type; if constexpr (IsChar<ValueType>) { Open(ToU8String(path), mode, type, flag); diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp index ffa282e88..9acf7551e 100644 --- a/src/common/wall_clock.cpp +++ b/src/common/wall_clock.cpp @@ -65,16 +65,20 @@ private: #ifdef ARCHITECTURE_x86_64 -std::unique_ptr<WallClock> CreateBestMatchingClock(u32 emulated_cpu_frequency, - u32 emulated_clock_frequency) { +std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency, + u64 emulated_clock_frequency) { const auto& caps = GetCPUCaps(); u64 rtsc_frequency = 0; if (caps.invariant_tsc) { rtsc_frequency = EstimateRDTSCFrequency(); } - // Fallback to StandardWallClock if rtsc period is higher than a nano second - if (rtsc_frequency <= 1000000000) { + // Fallback to StandardWallClock if the hardware TSC does not have the precision greater than: + // - A nanosecond + // - The emulated CPU frequency + // - The emulated clock counter frequency (CNTFRQ) + if (rtsc_frequency <= WallClock::NS_RATIO || rtsc_frequency <= emulated_cpu_frequency || + rtsc_frequency <= emulated_clock_frequency) { return std::make_unique<StandardWallClock>(emulated_cpu_frequency, emulated_clock_frequency); } else { @@ -85,8 +89,8 @@ std::unique_ptr<WallClock> CreateBestMatchingClock(u32 emulated_cpu_frequency, #else -std::unique_ptr<WallClock> CreateBestMatchingClock(u32 emulated_cpu_frequency, - u32 emulated_clock_frequency) { +std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency, + u64 emulated_clock_frequency) { return std::make_unique<StandardWallClock>(emulated_cpu_frequency, emulated_clock_frequency); } diff --git a/src/common/wall_clock.h b/src/common/wall_clock.h index cef3e9499..874448c27 100644 --- a/src/common/wall_clock.h +++ b/src/common/wall_clock.h @@ -13,6 +13,10 @@ namespace Common { class WallClock { public: + static constexpr u64 NS_RATIO = 1'000'000'000; + static constexpr u64 US_RATIO = 1'000'000; + static constexpr u64 MS_RATIO = 1'000; + virtual ~WallClock() = default; /// Returns current wall time in nanoseconds @@ -49,7 +53,7 @@ private: bool is_native; }; -[[nodiscard]] std::unique_ptr<WallClock> CreateBestMatchingClock(u32 emulated_cpu_frequency, - u32 emulated_clock_frequency); +[[nodiscard]] std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency, + u64 emulated_clock_frequency); } // namespace Common diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index 82ee2c8a1..91b842829 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp @@ -47,9 +47,9 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen _mm_mfence(); time_point.inner.last_measure = __rdtsc(); time_point.inner.accumulated_ticks = 0U; - ns_rtsc_factor = GetFixedPoint64Factor(1000000000, rtsc_frequency); - us_rtsc_factor = GetFixedPoint64Factor(1000000, rtsc_frequency); - ms_rtsc_factor = GetFixedPoint64Factor(1000, rtsc_frequency); + ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); + us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); + ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); } diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 40bb893ac..4f7aebf3f 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -2613,7 +2613,7 @@ static const FunctionDef SVC_Table_32[] = { {0x33, SvcWrap32<GetThreadContext32>, "GetThreadContext32"}, {0x34, SvcWrap32<WaitForAddress32>, "WaitForAddress32"}, {0x35, SvcWrap32<SignalToAddress32>, "SignalToAddress32"}, - {0x36, nullptr, "Unknown"}, + {0x36, SvcWrap32<SynchronizePreemptionState>, "SynchronizePreemptionState32"}, {0x37, nullptr, "Unknown"}, {0x38, nullptr, "Unknown"}, {0x39, nullptr, "Unknown"}, diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 048dba4f3..fa26eb8b0 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -131,6 +131,8 @@ public: void DownloadMemory(VAddr cpu_addr, u64 size); + bool InlineMemory(VAddr dest_address, size_t copy_size, std::span<u8> inlined_buffer); + void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size); void DisableGraphicsUniformBuffer(size_t stage, u32 index); @@ -808,6 +810,8 @@ void BufferCache<P>::CommitAsyncFlushesHigh() { return; } MICROPROFILE_SCOPE(GPU_DownloadMemory); + const bool is_accuracy_normal = + Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::Normal; boost::container::small_vector<std::pair<BufferCopy, BufferId>, 1> downloads; u64 total_size_bytes = 0; @@ -819,6 +823,9 @@ void BufferCache<P>::CommitAsyncFlushesHigh() { ForEachBufferInRange(cpu_addr, size, [&](BufferId buffer_id, Buffer& buffer) { buffer.ForEachDownloadRangeAndClear( cpu_addr, size, [&](u64 range_offset, u64 range_size) { + if (is_accuracy_normal) { + return; + } const VAddr buffer_addr = buffer.CpuAddr(); const auto add_download = [&](VAddr start, VAddr end) { const u64 new_offset = start - buffer_addr; @@ -1417,10 +1424,8 @@ void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 s const IntervalType base_interval{cpu_addr, cpu_addr + size}; common_ranges.add(base_interval); - const bool is_accuracy_high = - Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::High; const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue(); - if (!is_async && !is_accuracy_high) { + if (!is_async) { return; } uncommitted_ranges.add(base_interval); @@ -1644,6 +1649,42 @@ void BufferCache<P>::MappedUploadMemory(Buffer& buffer, u64 total_size_bytes, } template <class P> +bool BufferCache<P>::InlineMemory(VAddr dest_address, size_t copy_size, + std::span<u8> inlined_buffer) { + const bool is_dirty = IsRegionRegistered(dest_address, copy_size); + if (!is_dirty) { + return false; + } + if (!IsRegionGpuModified(dest_address, copy_size)) { + return false; + } + + const IntervalType subtract_interval{dest_address, dest_address + copy_size}; + ClearDownload(subtract_interval); + common_ranges.subtract(subtract_interval); + + BufferId buffer_id = FindBuffer(dest_address, static_cast<u32>(copy_size)); + auto& buffer = slot_buffers[buffer_id]; + SynchronizeBuffer(buffer, dest_address, static_cast<u32>(copy_size)); + + if constexpr (USE_MEMORY_MAPS) { + std::array copies{BufferCopy{ + .src_offset = 0, + .dst_offset = buffer.Offset(dest_address), + .size = copy_size, + }}; + auto upload_staging = runtime.UploadStagingBuffer(copy_size); + u8* const src_pointer = upload_staging.mapped_span.data(); + std::memcpy(src_pointer, inlined_buffer.data(), copy_size); + runtime.CopyBuffer(buffer, upload_staging.buffer, copies); + } else { + buffer.ImmediateUpload(buffer.Offset(dest_address), inlined_buffer.first(copy_size)); + } + + return true; +} + +template <class P> void BufferCache<P>::DownloadBufferMemory(Buffer& buffer) { DownloadBufferMemory(buffer, buffer.CpuAddr(), buffer.SizeBytes()); } diff --git a/src/video_core/engines/engine_upload.cpp b/src/video_core/engines/engine_upload.cpp index 71d7e1473..351b110fe 100644 --- a/src/video_core/engines/engine_upload.cpp +++ b/src/video_core/engines/engine_upload.cpp @@ -7,6 +7,7 @@ #include "common/assert.h" #include "video_core/engines/engine_upload.h" #include "video_core/memory_manager.h" +#include "video_core/rasterizer_interface.h" #include "video_core/textures/decoders.h" namespace Tegra::Engines::Upload { @@ -16,6 +17,10 @@ State::State(MemoryManager& memory_manager_, Registers& regs_) State::~State() = default; +void State::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { + rasterizer = rasterizer_; +} + void State::ProcessExec(const bool is_linear_) { write_offset = 0; copy_size = regs.line_length_in * regs.line_count; @@ -32,7 +37,7 @@ void State::ProcessData(const u32 data, const bool is_last_call) { } const GPUVAddr address{regs.dest.Address()}; if (is_linear) { - memory_manager.WriteBlock(address, inner_buffer.data(), copy_size); + rasterizer->AccelerateInlineToMemory(address, copy_size, inner_buffer); } else { UNIMPLEMENTED_IF(regs.dest.z != 0); UNIMPLEMENTED_IF(regs.dest.depth != 1); diff --git a/src/video_core/engines/engine_upload.h b/src/video_core/engines/engine_upload.h index 1c7f1effa..c9c5ec8c3 100644 --- a/src/video_core/engines/engine_upload.h +++ b/src/video_core/engines/engine_upload.h @@ -12,6 +12,10 @@ namespace Tegra { class MemoryManager; } +namespace VideoCore { +class RasterizerInterface; +} + namespace Tegra::Engines::Upload { struct Registers { @@ -60,6 +64,9 @@ public: void ProcessExec(bool is_linear_); void ProcessData(u32 data, bool is_last_call); + /// Binds a rasterizer to this engine. + void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); + private: u32 write_offset = 0; u32 copy_size = 0; @@ -68,6 +75,7 @@ private: bool is_linear = false; Registers& regs; MemoryManager& memory_manager; + VideoCore::RasterizerInterface* rasterizer = nullptr; }; } // namespace Tegra::Engines::Upload diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index 492b4c5a3..5a1c12076 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp @@ -22,6 +22,7 @@ KeplerCompute::~KeplerCompute() = default; void KeplerCompute::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { rasterizer = rasterizer_; + upload_state.BindRasterizer(rasterizer); } void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_call) { diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp index 560551157..8aed16caa 100644 --- a/src/video_core/engines/kepler_memory.cpp +++ b/src/video_core/engines/kepler_memory.cpp @@ -19,6 +19,10 @@ KeplerMemory::KeplerMemory(Core::System& system_, MemoryManager& memory_manager) KeplerMemory::~KeplerMemory() = default; +void KeplerMemory::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { + upload_state.BindRasterizer(rasterizer_); +} + void KeplerMemory::CallMethod(u32 method, u32 method_argument, bool is_last_call) { ASSERT_MSG(method < Regs::NUM_REGS, "Invalid KeplerMemory register, increase the size of the Regs structure"); diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h index 0d8ea09a9..949e2fae1 100644 --- a/src/video_core/engines/kepler_memory.h +++ b/src/video_core/engines/kepler_memory.h @@ -22,6 +22,10 @@ namespace Tegra { class MemoryManager; } +namespace VideoCore { +class RasterizerInterface; +} + namespace Tegra::Engines { /** @@ -38,6 +42,9 @@ public: explicit KeplerMemory(Core::System& system_, MemoryManager& memory_manager); ~KeplerMemory() override; + /// Binds a rasterizer to this engine. + void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); + /// Write the value to the register identified by method. void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index c38ebd670..5d6d217bb 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -31,6 +31,7 @@ Maxwell3D::~Maxwell3D() = default; void Maxwell3D::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { rasterizer = rasterizer_; + upload_state.BindRasterizer(rasterizer_); } void Maxwell3D::InitializeRegisterDefaults() { diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index f22342dfb..dc9df6c8b 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -1557,7 +1557,8 @@ private: static constexpr u32 null_cb_data = 0xFFFFFFFF; struct CBDataState { - std::array<std::array<u32, 0x4000>, 16> buffer; + static constexpr size_t inline_size = 0x4000; + std::array<std::array<u32, inline_size>, 16> buffer; u32 current{null_cb_data}; u32 id{null_cb_data}; u32 start_pos{}; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 705765c99..ba9ba082f 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -59,6 +59,7 @@ struct GPU::Impl { maxwell_3d->BindRasterizer(rasterizer); fermi_2d->BindRasterizer(rasterizer); kepler_compute->BindRasterizer(rasterizer); + kepler_memory->BindRasterizer(rasterizer); maxwell_dma->BindRasterizer(rasterizer); } @@ -502,8 +503,13 @@ struct GPU::Impl { case BufferMethods::SemaphoreAddressHigh: case BufferMethods::SemaphoreAddressLow: case BufferMethods::SemaphoreSequence: + break; case BufferMethods::UnkCacheFlush: + rasterizer->SyncGuestHost(); + break; case BufferMethods::WrcacheFlush: + rasterizer->SignalReference(); + break; case BufferMethods::FenceValue: break; case BufferMethods::RefCnt: @@ -513,7 +519,7 @@ struct GPU::Impl { ProcessFenceActionMethod(); break; case BufferMethods::WaitForInterrupt: - ProcessWaitForInterruptMethod(); + rasterizer->WaitForIdle(); break; case BufferMethods::SemaphoreTrigger: { ProcessSemaphoreTriggerMethod(); diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 38d8d9d74..61bfe47c7 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h @@ -143,6 +143,8 @@ public: [[nodiscard]] GPUVAddr Allocate(std::size_t size, std::size_t align); void Unmap(GPUVAddr gpu_addr, std::size_t size); + void FlushRegion(GPUVAddr gpu_addr, size_t size) const; + private: [[nodiscard]] PageEntry GetPageEntry(GPUVAddr gpu_addr) const; void SetPageEntry(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size = page_size); @@ -153,8 +155,6 @@ private: void TryLockPage(PageEntry page_entry, std::size_t size); void TryUnlockPage(PageEntry page_entry, std::size_t size); - void FlushRegion(GPUVAddr gpu_addr, size_t size) const; - void ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size, bool is_safe) const; void WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size, diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index b094fc064..1f1f12291 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -123,6 +123,9 @@ public: [[nodiscard]] virtual Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() = 0; + virtual void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, + std::span<u8> memory) = 0; + /// Attempt to use a faster method to display the framebuffer to screen [[nodiscard]] virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, u32 pixel_stride) { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 9b516c64f..142412a8e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -484,6 +484,28 @@ Tegra::Engines::AccelerateDMAInterface& RasterizerOpenGL::AccessAccelerateDMA() return accelerate_dma; } +void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, + std::span<u8> memory) { + auto cpu_addr = gpu_memory.GpuToCpuAddress(address); + if (!cpu_addr) [[unlikely]] { + gpu_memory.WriteBlock(address, memory.data(), copy_size); + return; + } + gpu_memory.WriteBlockUnsafe(address, memory.data(), copy_size); + { + std::unique_lock<std::mutex> lock{buffer_cache.mutex}; + if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) { + buffer_cache.WriteMemory(*cpu_addr, copy_size); + } + } + { + std::scoped_lock lock_texture{texture_cache.mutex}; + texture_cache.WriteMemory(*cpu_addr, copy_size); + } + shader_cache.InvalidateRegion(*cpu_addr, copy_size); + query_cache.InvalidateRegion(*cpu_addr, copy_size); +} + bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, u32 pixel_stride) { if (framebuffer_addr == 0) { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index d0397b745..98f6fd342 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -106,6 +106,8 @@ public: const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Config& copy_config) override; Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override; + void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, + std::span<u8> memory) override; bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, u32 pixel_stride) override; void LoadDiskResources(u64 title_id, std::stop_token stop_loading, diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index fd334a146..2227d9197 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -548,6 +548,28 @@ Tegra::Engines::AccelerateDMAInterface& RasterizerVulkan::AccessAccelerateDMA() return accelerate_dma; } +void RasterizerVulkan::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, + std::span<u8> memory) { + auto cpu_addr = gpu_memory.GpuToCpuAddress(address); + if (!cpu_addr) [[unlikely]] { + gpu_memory.WriteBlock(address, memory.data(), copy_size); + return; + } + gpu_memory.WriteBlockUnsafe(address, memory.data(), copy_size); + { + std::unique_lock<std::mutex> lock{buffer_cache.mutex}; + if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) { + buffer_cache.WriteMemory(*cpu_addr, copy_size); + } + } + { + std::scoped_lock lock_texture{texture_cache.mutex}; + texture_cache.WriteMemory(*cpu_addr, copy_size); + } + pipeline_cache.InvalidateRegion(*cpu_addr, copy_size); + query_cache.InvalidateRegion(*cpu_addr, copy_size); +} + bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, u32 pixel_stride) { if (!framebuffer_addr) { diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 866827247..5af2e275b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -99,6 +99,8 @@ public: const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Config& copy_config) override; Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override; + void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, + std::span<u8> memory) override; bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, u32 pixel_stride) override; void LoadDiskResources(u64 title_id, std::stop_token stop_loading, diff --git a/src/video_core/shader_cache.cpp b/src/video_core/shader_cache.cpp index 78bf90c48..87636857d 100644 --- a/src/video_core/shader_cache.cpp +++ b/src/video_core/shader_cache.cpp @@ -170,7 +170,7 @@ void ShaderCache::RemovePendingShaders() { marked_for_removal.clear(); if (!removed_shaders.empty()) { - RemoveShadersFromStorage(std::move(removed_shaders)); + RemoveShadersFromStorage(removed_shaders); } } @@ -213,7 +213,7 @@ void ShaderCache::UnmarkMemory(Entry* entry) { rasterizer.UpdatePagesCachedCount(addr, size, -1); } -void ShaderCache::RemoveShadersFromStorage(std::vector<ShaderInfo*> removed_shaders) { +void ShaderCache::RemoveShadersFromStorage(std::span<ShaderInfo*> removed_shaders) { // Remove them from the cache std::erase_if(storage, [&removed_shaders](const std::unique_ptr<ShaderInfo>& shader) { return std::ranges::find(removed_shaders, shader.get()) != removed_shaders.end(); diff --git a/src/video_core/shader_cache.h b/src/video_core/shader_cache.h index 136fe294c..8836bc8c6 100644 --- a/src/video_core/shader_cache.h +++ b/src/video_core/shader_cache.h @@ -4,7 +4,6 @@ #pragma once -#include <algorithm> #include <array> #include <memory> #include <mutex> @@ -138,7 +137,7 @@ private: /// @param removed_shaders Shaders to be removed from the storage /// @pre invalidation_mutex is locked /// @pre lookup_mutex is locked - void RemoveShadersFromStorage(std::vector<ShaderInfo*> removed_shaders); + void RemoveShadersFromStorage(std::span<ShaderInfo*> removed_shaders); /// @brief Creates a new entry in the lookup cache and returns its pointer /// @pre lookup_mutex is locked diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 464e7a489..19133ccf5 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -109,7 +109,7 @@ void ConfigureDialog::ApplyConfiguration() { ui_tab->ApplyConfiguration(); system_tab->ApplyConfiguration(); profile_tab->ApplyConfiguration(); - filesystem_tab->applyConfiguration(); + filesystem_tab->ApplyConfiguration(); input_tab->ApplyConfiguration(); hotkeys_tab->ApplyConfiguration(registry); cpu_tab->ApplyConfiguration(); diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp index 9cb317822..d6fb43f8b 100644 --- a/src/yuzu/configuration/configure_filesystem.cpp +++ b/src/yuzu/configuration/configure_filesystem.cpp @@ -14,7 +14,7 @@ ConfigureFilesystem::ConfigureFilesystem(QWidget* parent) : QWidget(parent), ui(std::make_unique<Ui::ConfigureFilesystem>()) { ui->setupUi(this); - this->setConfiguration(); + SetConfiguration(); connect(ui->nand_directory_button, &QToolButton::pressed, this, [this] { SetDirectory(DirectoryTarget::NAND, ui->nand_directory_edit); }); @@ -38,7 +38,15 @@ ConfigureFilesystem::ConfigureFilesystem(QWidget* parent) ConfigureFilesystem::~ConfigureFilesystem() = default; -void ConfigureFilesystem::setConfiguration() { +void ConfigureFilesystem::changeEvent(QEvent* event) { + if (event->type() == QEvent::LanguageChange) { + RetranslateUI(); + } + + QWidget::changeEvent(event); +} + +void ConfigureFilesystem::SetConfiguration() { ui->nand_directory_edit->setText( QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::NANDDir))); ui->sdmc_directory_edit->setText( @@ -60,7 +68,7 @@ void ConfigureFilesystem::setConfiguration() { UpdateEnabledControls(); } -void ConfigureFilesystem::applyConfiguration() { +void ConfigureFilesystem::ApplyConfiguration() { Common::FS::SetYuzuPath(Common::FS::YuzuPath::NANDDir, ui->nand_directory_edit->text().toStdString()); Common::FS::SetYuzuPath(Common::FS::YuzuPath::SDMCDir, @@ -143,6 +151,6 @@ void ConfigureFilesystem::UpdateEnabledControls() { !ui->gamecard_current_game->isChecked()); } -void ConfigureFilesystem::retranslateUi() { +void ConfigureFilesystem::RetranslateUI() { ui->retranslateUi(this); } diff --git a/src/yuzu/configuration/configure_filesystem.h b/src/yuzu/configuration/configure_filesystem.h index 2147cd405..b4f9355eb 100644 --- a/src/yuzu/configuration/configure_filesystem.h +++ b/src/yuzu/configuration/configure_filesystem.h @@ -20,11 +20,13 @@ public: explicit ConfigureFilesystem(QWidget* parent = nullptr); ~ConfigureFilesystem() override; - void applyConfiguration(); - void retranslateUi(); + void ApplyConfiguration(); private: - void setConfiguration(); + void changeEvent(QEvent* event) override; + + void RetranslateUI(); + void SetConfiguration(); enum class DirectoryTarget { NAND, diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp index be10e0a31..53e629a5e 100644 --- a/src/yuzu/configuration/configure_hotkeys.cpp +++ b/src/yuzu/configuration/configure_hotkeys.cpp @@ -178,52 +178,52 @@ void ConfigureHotkeys::SetPollingResult(Core::HID::NpadButton button, const bool QString ConfigureHotkeys::GetButtonName(Core::HID::NpadButton button) const { Core::HID::NpadButtonState state{button}; if (state.a) { - return tr("A"); + return QStringLiteral("A"); } if (state.b) { - return tr("B"); + return QStringLiteral("B"); } if (state.x) { - return tr("X"); + return QStringLiteral("X"); } if (state.y) { - return tr("Y"); + return QStringLiteral("Y"); } if (state.l || state.right_sl || state.left_sl) { - return tr("L"); + return QStringLiteral("L"); } if (state.r || state.right_sr || state.left_sr) { - return tr("R"); + return QStringLiteral("R"); } if (state.zl) { - return tr("ZL"); + return QStringLiteral("ZL"); } if (state.zr) { - return tr("ZR"); + return QStringLiteral("ZR"); } if (state.left) { - return tr("Dpad_Left"); + return QStringLiteral("Dpad_Left"); } if (state.right) { - return tr("Dpad_Right"); + return QStringLiteral("Dpad_Right"); } if (state.up) { - return tr("Dpad_Up"); + return QStringLiteral("Dpad_Up"); } if (state.down) { - return tr("Dpad_Down"); + return QStringLiteral("Dpad_Down"); } if (state.stick_l) { - return tr("Left_Stick"); + return QStringLiteral("Left_Stick"); } if (state.stick_r) { - return tr("Right_Stick"); + return QStringLiteral("Right_Stick"); } if (state.minus) { - return tr("Minus"); + return QStringLiteral("Minus"); } if (state.plus) { - return tr("Plus"); + return QStringLiteral("Plus"); } return tr("Invalid"); } diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 956c9d644..cc0534907 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -330,7 +330,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i connect(button, &QPushButton::clicked, [=, this] { HandleClick( button, button_id, - [=, this](Common::ParamPackage params) { + [=, this](const Common::ParamPackage& params) { emulated_controller->SetButtonParam(button_id, params); }, InputCommon::Polling::InputType::Button); @@ -396,7 +396,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i connect(button, &QPushButton::clicked, [=, this] { HandleClick( button, motion_id, - [=, this](Common::ParamPackage params) { + [=, this](const Common::ParamPackage& params) { emulated_controller->SetMotionParam(motion_id, params); }, InputCommon::Polling::InputType::Motion); @@ -501,10 +501,11 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i param.Set("invert_y", invert_str); emulated_controller->SetStickParam(analog_id, param); } - for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; - ++sub_button_id) { - analog_map_buttons[analog_id][sub_button_id]->setText( - AnalogToText(param, analog_sub_buttons[sub_button_id])); + for (int analog_sub_button_id = 0; + analog_sub_button_id < ANALOG_SUB_BUTTONS_NUM; + ++analog_sub_button_id) { + analog_map_buttons[analog_id][analog_sub_button_id]->setText( + AnalogToText(param, analog_sub_buttons[analog_sub_button_id])); } }); context_menu.exec(analog_map_buttons[analog_id][sub_button_id]->mapToGlobal( @@ -787,7 +788,7 @@ void ConfigureInputPlayer::UpdateInputDeviceCombobox() { if (devices.size() == 1) { const auto devices_it = std::find_if( input_devices.begin(), input_devices.end(), - [first_engine, first_guid, first_port, first_pad](const Common::ParamPackage param) { + [first_engine, first_guid, first_port, first_pad](const Common::ParamPackage& param) { return param.Get("engine", "") == first_engine && param.Get("guid", "") == first_guid && param.Get("port", 0) == first_port && param.Get("pad", 0) == first_pad; @@ -818,7 +819,7 @@ void ConfigureInputPlayer::UpdateInputDeviceCombobox() { if (is_engine_equal && is_port_equal) { const auto devices_it = std::find_if( input_devices.begin(), input_devices.end(), - [first_engine, first_guid, second_guid, first_port](const Common::ParamPackage param) { + [first_engine, first_guid, second_guid, first_port](const Common::ParamPackage& param) { const bool is_guid_valid = (param.Get("guid", "") == first_guid && param.Get("guid2", "") == second_guid) || @@ -1030,7 +1031,7 @@ int ConfigureInputPlayer::GetIndexFromControllerType(Core::HID::NpadStyleIndex t void ConfigureInputPlayer::UpdateInputDevices() { input_devices = input_subsystem->GetInputDevices(); ui->comboDevices->clear(); - for (auto device : input_devices) { + for (const auto& device : input_devices) { ui->comboDevices->addItem(QString::fromStdString(device.Get("display", "Unknown")), {}); } } @@ -1312,7 +1313,7 @@ void ConfigureInputPlayer::HandleClick( } button->setFocus(); - input_setter = new_input_setter; + input_setter = std::move(new_input_setter); input_subsystem->BeginMapping(type); @@ -1362,7 +1363,7 @@ bool ConfigureInputPlayer::IsInputAcceptable(const Common::ParamPackage& params) return params.Get("engine", "") == "keyboard" || params.Get("engine", "") == "mouse"; } - const auto current_input_device = input_devices[ui->comboDevices->currentIndex()]; + const auto& current_input_device = input_devices[ui->comboDevices->currentIndex()]; return params.Get("engine", "") == current_input_device.Get("engine", "") && (params.Get("guid", "") == current_input_device.Get("guid", "") || params.Get("guid", "") == current_input_device.Get("guid2", "")) && diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp index 8539a5c8b..4340de304 100644 --- a/src/yuzu/configuration/configure_motion_touch.cpp +++ b/src/yuzu/configuration/configure_motion_touch.cpp @@ -42,23 +42,25 @@ CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent, job = std::make_unique<CalibrationConfigurationJob>( host, port, [this](CalibrationConfigurationJob::Status status) { - QString text; - switch (status) { - case CalibrationConfigurationJob::Status::Ready: - text = tr("Touch the top left corner <br>of your touchpad."); - break; - case CalibrationConfigurationJob::Status::Stage1Completed: - text = tr("Now touch the bottom right corner <br>of your touchpad."); - break; - case CalibrationConfigurationJob::Status::Completed: - text = tr("Configuration completed!"); - break; - default: - break; - } - QMetaObject::invokeMethod(this, "UpdateLabelText", Q_ARG(QString, text)); + QMetaObject::invokeMethod(this, [status, this] { + QString text; + switch (status) { + case CalibrationConfigurationJob::Status::Ready: + text = tr("Touch the top left corner <br>of your touchpad."); + break; + case CalibrationConfigurationJob::Status::Stage1Completed: + text = tr("Now touch the bottom right corner <br>of your touchpad."); + break; + case CalibrationConfigurationJob::Status::Completed: + text = tr("Configuration completed!"); + break; + default: + break; + } + UpdateLabelText(text); + }); if (status == CalibrationConfigurationJob::Status::Completed) { - QMetaObject::invokeMethod(this, "UpdateButtonText", Q_ARG(QString, tr("OK"))); + QMetaObject::invokeMethod(this, [this] { UpdateButtonText(tr("OK")); }); } }, [this](u16 min_x_, u16 min_y_, u16 max_x_, u16 max_y_) { @@ -215,11 +217,11 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() { ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), [this] { LOG_INFO(Frontend, "UDP input test success"); - QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true)); + QMetaObject::invokeMethod(this, [this] { ShowUDPTestResult(true); }); }, [this] { LOG_ERROR(Frontend, "UDP input test failed"); - QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, false)); + QMetaObject::invokeMethod(this, [this] { ShowUDPTestResult(false); }); }); } diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 8b5c4a10a..e3661b390 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -161,7 +161,7 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { * @return true if the haystack contains all words of userinput */ static bool ContainsAllWords(const QString& haystack, const QString& userinput) { - const QStringList userinput_split = userinput.split(QLatin1Char{' '}, QString::SkipEmptyParts); + const QStringList userinput_split = userinput.split(QLatin1Char{' '}, Qt::SkipEmptyParts); return std::all_of(userinput_split.begin(), userinput_split.end(), [&haystack](const QString& s) { return haystack.contains(s); }); |