From 23d1664dc271a1b695057e1b58c330d7559f213a Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Sun, 16 May 2021 21:32:58 +0200 Subject: [PATCH] early-access version 1690 --- README.md | 2 +- src/core/core.cpp | 3 ++- src/core/file_sys/registered_cache.cpp | 7 +++++ src/core/file_sys/registered_cache.h | 1 + .../service/nvdrv/devices/nvdisp_disp0.cpp | 1 - src/core/perf_stats.cpp | 12 ++++----- src/core/perf_stats.h | 9 ++++--- src/video_core/buffer_cache/buffer_cache.h | 5 +++- src/video_core/gpu.cpp | 5 ++++ src/video_core/gpu.h | 2 ++ .../renderer_opengl/renderer_opengl.cpp | 1 + .../renderer_vulkan/renderer_vulkan.cpp | 1 + src/yuzu/main.cpp | 26 +++++++++++++++---- src/yuzu/main.h | 1 + src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 2 +- 15 files changed, 59 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 43e173e7b..aa55a8cac 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 1689. +This is the source code for early-access 1690. ## Legal Notice diff --git a/src/core/core.cpp b/src/core/core.cpp index 5d1f3b845..47b98e577 100755 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -289,7 +289,8 @@ struct System::Impl { telemetry_session->AddField(performance, "Shutdown_EmulationSpeed", perf_results.emulation_speed * 100.0); - telemetry_session->AddField(performance, "Shutdown_Framerate", perf_results.game_fps); + telemetry_session->AddField(performance, "Shutdown_Framerate", + perf_results.average_game_fps); telemetry_session->AddField(performance, "Shutdown_Frametime", perf_results.frametime * 1000.0); telemetry_session->AddField(performance, "Mean_Frametime_MS", diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index 31500cca9..066c6789a 100755 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -12,6 +12,7 @@ #include "common/logging/log.h" #include "core/crypto/key_manager.h" #include "core/file_sys/card_image.h" +#include "core/file_sys/common_funcs.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/registered_cache.h" @@ -592,6 +593,12 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex const CNMT cnmt(cnmt_file); const auto title_id = cnmt.GetTitleID(); + const auto version = cnmt.GetTitleVersion(); + + if (title_id == GetBaseTitleID(title_id) && version == 0) { + return InstallResult::ErrorBaseInstall; + } + const auto result = RemoveExistingEntry(title_id); // Install Metadata File diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h index b31630014..d042aef90 100755 --- a/src/core/file_sys/registered_cache.h +++ b/src/core/file_sys/registered_cache.h @@ -38,6 +38,7 @@ enum class InstallResult { ErrorAlreadyExists, ErrorCopyFailed, ErrorMetaFailed, + ErrorBaseInstall, }; struct ContentProviderEntry { diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index bbef04a29..2cc0da124 100755 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -52,7 +52,6 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 addr, offset, width, height, stride, static_cast(format), transform, crop_rect}; - system.GetPerfStats().EndGameFrame(); system.GetPerfStats().EndSystemFrame(); system.GPU().SwapBuffers(&framebuffer); system.FrameLimiter().DoFrameLimiting(system.CoreTiming().GetGlobalTimeUs()); diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index b11dc9c9d..6635a1339 100755 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -76,9 +76,7 @@ void PerfStats::EndSystemFrame() { } void PerfStats::EndGameFrame() { - std::lock_guard lock{object_mutex}; - - game_frames += 1; + game_frames.fetch_add(1, std::memory_order_relaxed); } double PerfStats::GetMeanFrametime() const { @@ -101,10 +99,11 @@ PerfStatsResults PerfStats::GetAndResetStats(microseconds current_system_time_us const auto interval = duration_cast(now - reset_point).count(); const auto system_us_per_second = (current_system_time_us - reset_point_system_us) / interval; - + const auto current_frames = static_cast(game_frames.load(std::memory_order_relaxed)); + const auto current_fps = current_frames / interval; const PerfStatsResults results{ .system_fps = static_cast(system_frames) / interval, - .game_fps = static_cast(game_frames) / interval, + .average_game_fps = (current_fps + previous_fps) / 2.0, .frametime = duration_cast(accumulated_frametime).count() / static_cast(system_frames), .emulation_speed = system_us_per_second.count() / 1'000'000.0, @@ -115,7 +114,8 @@ PerfStatsResults PerfStats::GetAndResetStats(microseconds current_system_time_us reset_point_system_us = current_system_time_us; accumulated_frametime = Clock::duration::zero(); system_frames = 0; - game_frames = 0; + game_frames.store(0, std::memory_order_relaxed); + previous_fps = current_fps; return results; } diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index ae4698696..e5d603717 100755 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include #include @@ -15,8 +16,8 @@ namespace Core { struct PerfStatsResults { /// System FPS (LCD VBlanks) in Hz double system_fps; - /// Game FPS (GSP frame submissions) in Hz - double game_fps; + /// Average game FPS (GPU frame renders) in Hz + double average_game_fps; /// Walltime per system frame, in seconds, excluding any waits double frametime; /// Ratio of walltime / emulated time elapsed @@ -72,7 +73,7 @@ private: /// Cumulative number of system frames (LCD VBlanks) presented since last reset u32 system_frames = 0; /// Cumulative number of game frames (GSP frame submissions) since last reset - u32 game_frames = 0; + std::atomic game_frames = 0; /// Point when the previous system frame ended Clock::time_point previous_frame_end = reset_point; @@ -80,6 +81,8 @@ private: Clock::time_point frame_begin = reset_point; /// Total visible duration (including frame-limiting, etc.) of the previous system frame Clock::duration previous_frame_length = Clock::duration::zero(); + /// Previously computed fps + double previous_fps = 0; }; class FrameLimiter { diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 32dcbd693..de971041f 100755 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -690,7 +690,10 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 const VAddr cpu_addr = binding.cpu_addr; const u32 size = binding.size; Buffer& buffer = slot_buffers[binding.buffer_id]; - if (size <= uniform_buffer_skip_cache_size && !buffer.IsRegionGpuModified(cpu_addr, size)) { + const bool use_fast_buffer = binding.buffer_id != NULL_BUFFER_ID && + size <= uniform_buffer_skip_cache_size && + !buffer.IsRegionGpuModified(cpu_addr, size); + if (use_fast_buffer) { if constexpr (IS_OPENGL) { if (runtime.HasFastBufferSubData()) { // Fast path for Nvidia diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index a38024242..37f7b24e1 100755 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -13,6 +13,7 @@ #include "core/frontend/emu_window.h" #include "core/hardware_interrupt_manager.h" #include "core/memory.h" +#include "core/perf_stats.h" #include "video_core/engines/fermi_2d.h" #include "video_core/engines/kepler_compute.h" #include "video_core/engines/kepler_memory.h" @@ -191,6 +192,10 @@ u64 GPU::GetTicks() const { return nanoseconds_num * gpu_ticks_num + (nanoseconds_rem * gpu_ticks_num) / gpu_ticks_den; } +void GPU::RendererFrameEndNotify() { + system.GetPerfStats().EndGameFrame(); +} + void GPU::FlushCommands() { rasterizer->FlushCommands(); } diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 8669e9940..29a867863 100755 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -247,6 +247,8 @@ public: return use_nvdec; } + void RendererFrameEndNotify(); + enum class FenceOperation : u32 { Acquire = 0, Increment = 1, diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index cc2e499f9..a718bff7a 100755 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -155,6 +155,7 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { ++m_current_frame; + gpu.RendererFrameEndNotify(); rasterizer.TickFrame(); context->SwapBuffers(); diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 2e0cf4232..3986eb172 100755 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -154,6 +154,7 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { if (swapchain.Present(render_semaphore)) { blit_screen.Recreate(); } + gpu.RendererFrameEndNotify(); rasterizer.TickFrame(); } diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f6409d59d..a2687573a 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1367,7 +1367,7 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index) { game_list->hide(); game_list_placeholder->hide(); } - status_bar_update_timer.start(2000); + status_bar_update_timer.start(500); async_status_button->setDisabled(true); multicore_status_button->setDisabled(true); renderer_status_button->setDisabled(true); @@ -2098,6 +2098,7 @@ void GMainWindow::OnMenuInstallToNAND() { QStringList new_files{}; // Newly installed files that do not yet exist in the NAND QStringList overwritten_files{}; // Files that overwrote those existing in the NAND QStringList failed_files{}; // Files that failed to install due to errors + bool detected_base_install{}; // Whether a base game was attempted to be installed ui.action_Install_File_NAND->setEnabled(false); @@ -2123,6 +2124,7 @@ void GMainWindow::OnMenuInstallToNAND() { while (!future.isFinished()) { QCoreApplication::processEvents(); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } result = future.result(); @@ -2143,6 +2145,10 @@ void GMainWindow::OnMenuInstallToNAND() { case InstallResult::Failure: failed_files.append(QFileInfo(file).fileName()); break; + case InstallResult::BaseInstallAttempted: + failed_files.append(QFileInfo(file).fileName()); + detected_base_install = true; + break; } --remaining; @@ -2150,6 +2156,13 @@ void GMainWindow::OnMenuInstallToNAND() { install_progress->close(); + if (detected_base_install) { + QMessageBox::warning( + this, tr("Install Results"), + tr("To avoid possible conflicts, we discourage users from installing base games to the " + "NAND.\nPlease, only use this feature to install updates and DLC.")); + } + const QString install_results = (new_files.isEmpty() ? QString{} : tr("%n file(s) were newly installed\n", "", new_files.size())) + @@ -2211,11 +2224,14 @@ InstallResult GMainWindow::InstallNSPXCI(const QString& filename) { const auto res = Core::System::GetInstance().GetFileSystemController().GetUserNANDContents()->InstallEntry( *nsp, true, qt_raw_copy); - if (res == FileSys::InstallResult::Success) { + switch (res) { + case FileSys::InstallResult::Success: return InstallResult::Success; - } else if (res == FileSys::InstallResult::OverwriteExisting) { + case FileSys::InstallResult::OverwriteExisting: return InstallResult::Overwrite; - } else { + case FileSys::InstallResult::ErrorBaseInstall: + return InstallResult::BaseInstallAttempted; + default: return InstallResult::Failure; } } @@ -2792,7 +2808,7 @@ void GMainWindow::UpdateStatusBar() { } else { emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); } - game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0)); + game_fps_label->setText(tr("Game: %1 FPS").arg(results.average_game_fps, 0, 'f', 0)); emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2)); emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue()); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 98a608fce..b3a5033ce 100755 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -76,6 +76,7 @@ enum class InstallResult { Success, Overwrite, Failure, + BaseInstallAttempted, }; enum class ReinitializeKeyBehavior { diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index d64f81106..06b20c975 100755 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -215,7 +215,7 @@ void EmuWindow_SDL2::WaitEvent() { const auto results = Core::System::GetInstance().GetAndResetPerfStats(); const auto title = fmt::format("yuzu {} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname, - Common::g_scm_branch, Common::g_scm_desc, results.game_fps, + Common::g_scm_branch, Common::g_scm_desc, results.average_game_fps, results.emulation_speed * 100.0); SDL_SetWindowTitle(render_window, title.c_str()); last_time = current_time;