Prechádzať zdrojové kódy

gl_shader_cache: Link loading screen with disk shader cache load

ReinUsesLisp 7 rokov pred
rodič
commit
eb73247433

+ 0 - 2
src/core/core.cpp

@@ -176,8 +176,6 @@ struct System::Impl {
                                              static_cast<u32>(load_result));
         }
 
-        renderer->Rasterizer().LoadDiskResources();
-
         status = ResultStatus::Success;
         return status;
     }

+ 3 - 1
src/video_core/rasterizer_interface.h

@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <atomic>
 #include <functional>
 #include "common/common_types.h"
 #include "video_core/engines/fermi_2d.h"
@@ -63,6 +64,7 @@ public:
     virtual void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) {}
 
     /// Initialize disk cached resources for the game being emulated
-    virtual void LoadDiskResources() {}
+    virtual void LoadDiskResources(const std::atomic_bool& stop_loading = false,
+                                   const DiskResourceLoadCallback& callback = {}) {}
 };
 } // namespace VideoCore

+ 4 - 3
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -449,7 +449,7 @@ static constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
     return boost::make_iterator_range(map.equal_range(interval));
 }
 
-void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
+void RasterizerOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) {
     const u64 page_start{addr >> Memory::PAGE_BITS};
     const u64 page_end{(addr + size + Memory::PAGE_SIZE - 1) >> Memory::PAGE_BITS};
 
@@ -479,8 +479,9 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
         cached_pages.add({pages_interval, delta});
 }
 
-void RasterizerOpenGL::LoadDiskResources() {
-    shader_cache.LoadDiskCache();
+void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
+                                         const VideoCore::DiskResourceLoadCallback& callback) {
+    shader_cache.LoadDiskCache(stop_loading, callback);
 }
 
 std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(

+ 3 - 1
src/video_core/renderer_opengl/gl_rasterizer.h

@@ -5,6 +5,7 @@
 #pragma once
 
 #include <array>
+#include <atomic>
 #include <cstddef>
 #include <map>
 #include <memory>
@@ -65,7 +66,8 @@ public:
                            u32 pixel_stride) override;
     bool AccelerateDrawBatch(bool is_indexed) override;
     void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) override;
-    void LoadDiskResources() override;
+    void LoadDiskResources(const std::atomic_bool& stop_loading,
+                           const VideoCore::DiskResourceLoadCallback& callback) override;
 
     /// Maximum supported size that a constbuffer can have in bytes.
     static constexpr std::size_t MaxConstbufferSize = 0x10000;

+ 26 - 3
src/video_core/renderer_opengl/gl_shader_cache.cpp

@@ -345,7 +345,8 @@ ShaderDiskCacheUsage CachedShader::GetUsage(GLenum primitive_mode,
 ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system)
     : RasterizerCache{rasterizer}, disk_cache{system} {}
 
-void ShaderCacheOpenGL::LoadDiskCache() {
+void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
+                                      const VideoCore::DiskResourceLoadCallback& callback) {
     const auto transferable = disk_cache.LoadTransferable();
     if (!transferable) {
         return;
@@ -355,10 +356,18 @@ void ShaderCacheOpenGL::LoadDiskCache() {
     auto [decompiled, dumps] = disk_cache.LoadPrecompiled();
 
     const auto supported_formats{GetSupportedFormats()};
-    const auto unspecialized{GenerateUnspecializedShaders(raws, decompiled)};
+    const auto unspecialized{
+        GenerateUnspecializedShaders(stop_loading, callback, raws, decompiled)};
+    if (stop_loading)
+        return;
 
     // Build shaders
+    if (callback)
+        callback(VideoCore::LoadCallbackStage::Build, 0, usages.size());
     for (std::size_t i = 0; i < usages.size(); ++i) {
+        if (stop_loading)
+            return;
+
         const auto& usage{usages[i]};
         LOG_INFO(Render_OpenGL, "Building shader {:016x} ({} of {})", usage.unique_identifier,
                  i + 1, usages.size());
@@ -381,6 +390,9 @@ void ShaderCacheOpenGL::LoadDiskCache() {
                                       usage.bindings, usage.primitive, true);
         }
         precompiled_programs.insert({usage, std::move(shader)});
+
+        if (callback)
+            callback(VideoCore::LoadCallbackStage::Build, i + 1, usages.size());
     }
 
     // TODO(Rodrigo): Do state tracking for transferable shaders and do a dummy draw before
@@ -420,11 +432,19 @@ CachedProgram ShaderCacheOpenGL::GeneratePrecompiledProgram(
 }
 
 std::map<u64, UnspecializedShader> ShaderCacheOpenGL::GenerateUnspecializedShaders(
+    const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback,
     const std::vector<ShaderDiskCacheRaw>& raws,
     const std::map<u64, ShaderDiskCacheDecompiled>& decompiled) {
     std::map<u64, UnspecializedShader> unspecialized;
 
-    for (const auto& raw : raws) {
+    if (callback)
+        callback(VideoCore::LoadCallbackStage::Decompile, 0, raws.size());
+
+    for (std::size_t i = 0; i < raws.size(); ++i) {
+        if (stop_loading)
+            return {};
+
+        const auto& raw{raws[i]};
         const u64 unique_identifier = raw.GetUniqueIdentifier();
         const u64 calculated_hash =
             GetUniqueIdentifier(raw.GetProgramType(), raw.GetProgramCode(), raw.GetProgramCodeB());
@@ -454,6 +474,9 @@ std::map<u64, UnspecializedShader> ShaderCacheOpenGL::GenerateUnspecializedShade
         unspecialized.insert(
             {raw.GetUniqueIdentifier(),
              {std::move(result.first), std::move(result.second), raw.GetProgramType()}});
+
+        if (callback)
+            callback(VideoCore::LoadCallbackStage::Decompile, i, raws.size());
     }
     return unspecialized;
 }

+ 4 - 1
src/video_core/renderer_opengl/gl_shader_cache.h

@@ -15,6 +15,7 @@
 #include "common/assert.h"
 #include "common/common_types.h"
 #include "video_core/rasterizer_cache.h"
+#include "video_core/renderer_base.h"
 #include "video_core/renderer_opengl/gl_resource_manager.h"
 #include "video_core/renderer_opengl/gl_shader_decompiler.h"
 #include "video_core/renderer_opengl/gl_shader_disk_cache.h"
@@ -114,13 +115,15 @@ public:
     explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system);
 
     /// Loads disk cache for the current game
-    void LoadDiskCache();
+    void LoadDiskCache(const std::atomic_bool& stop_loading,
+                       const VideoCore::DiskResourceLoadCallback& callback);
 
     /// Gets the current specified shader stage program
     Shader GetStageProgram(Maxwell::ShaderProgram program);
 
 private:
     std::map<u64, UnspecializedShader> GenerateUnspecializedShaders(
+        const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback,
         const std::vector<ShaderDiskCacheRaw>& raws,
         const std::map<u64, ShaderDiskCacheDecompiled>& decompiled);
 

+ 9 - 0
src/yuzu/bootmanager.cpp

@@ -29,6 +29,15 @@ void EmuThread::run() {
 
     stop_run = false;
 
+    emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
+
+    Core::System::GetInstance().Renderer().Rasterizer().LoadDiskResources(
+        stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
+            emit LoadProgress(stage, value, total);
+        });
+
+    emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
+
     // holds whether the cpu was running during the last iteration,
     // so that the DebugModeLeft signal can be emitted before the
     // next execution step

+ 7 - 1
src/yuzu/bootmanager.h

@@ -22,6 +22,10 @@ class GGLWidgetInternal;
 class GMainWindow;
 class GRenderWindow;
 
+namespace VideoCore {
+enum class LoadCallbackStage;
+}
+
 class EmuThread : public QThread {
     Q_OBJECT
 
@@ -75,7 +79,7 @@ public:
 private:
     bool exec_step = false;
     bool running = false;
-    std::atomic<bool> stop_run{false};
+    std::atomic_bool stop_run{false};
     std::mutex running_mutex;
     std::condition_variable running_cv;
 
@@ -101,6 +105,8 @@ signals:
     void DebugModeLeft();
 
     void ErrorThrown(Core::System::ResultStatus, std::string);
+
+    void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total);
 };
 
 class GRenderWindow : public QWidget, public Core::Frontend::EmuWindow {

+ 3 - 0
src/yuzu/main.cpp

@@ -887,6 +887,9 @@ void GMainWindow::BootGame(const QString& filename) {
     connect(emu_thread.get(), &EmuThread::DebugModeLeft, waitTreeWidget,
             &WaitTreeWidget::OnDebugModeLeft, Qt::BlockingQueuedConnection);
 
+    connect(emu_thread.get(), &EmuThread::LoadProgress, loading_screen,
+            &LoadingScreen::OnLoadProgress, Qt::QueuedConnection);
+
     // Update the GUI
     if (ui.action_Single_Window_Mode->isChecked()) {
         game_list->hide();

+ 3 - 0
src/yuzu_cmd/yuzu.cpp

@@ -28,6 +28,7 @@
 #include "core/loader/loader.h"
 #include "core/settings.h"
 #include "core/telemetry_session.h"
+#include "video_core/renderer_base.h"
 #include "yuzu_cmd/config.h"
 #include "yuzu_cmd/emu_window/emu_window_sdl2.h"
 
@@ -217,6 +218,8 @@ int main(int argc, char** argv) {
 
     Core::Telemetry().AddField(Telemetry::FieldType::App, "Frontend", "SDL");
 
+    system.Renderer().Rasterizer().LoadDiskResources();
+
     while (emu_window->IsOpen()) {
         system.RunLoop();
     }