diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 7041edaee..7bc1844c9 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -215,7 +215,8 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) { LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); std::unique_ptr cpu_context; - system.GPU().Renderer().Rasterizer()->LoadDiskResources(stop_run, &LoadDiskCacheProgress); + system.GPU().Renderer().Rasterizer()->LoadDefaultDiskResources(stop_run, + &LoadDiskCacheProgress); LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 41b6c212e..5b2842aa3 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -72,9 +72,14 @@ void EmuThread::run() { std::size_t total) { emit LoadProgress(stage, value, total); }); } + system.GPU().Renderer().Rasterizer()->SetSwitchDiskResourcesCallback( + [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { + emit SwitchDiskResources(stage, value, total); + }); + emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); - system.GPU().Renderer().Rasterizer()->LoadDiskResources( + system.GPU().Renderer().Rasterizer()->LoadDefaultDiskResources( stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { emit LoadProgress(stage, value, total); }); diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h index 24fdf45e3..8082b5590 100644 --- a/src/citra_qt/bootmanager.h +++ b/src/citra_qt/bootmanager.h @@ -1,4 +1,4 @@ -// Copyright 2014 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -110,6 +110,9 @@ signals: void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total); + void SwitchDiskResources(VideoCore::LoadCallbackStage stage, std::size_t value, + std::size_t total); + void HideLoadingScreen(); }; diff --git a/src/citra_qt/citra_qt.cpp b/src/citra_qt/citra_qt.cpp index 5df60a896..eb855401a 100644 --- a/src/citra_qt/citra_qt.cpp +++ b/src/citra_qt/citra_qt.cpp @@ -500,6 +500,8 @@ void GMainWindow::InitializeWidgets() { progress_bar->hide(); statusBar()->addPermanentWidget(progress_bar); + loading_shaders_label = new QLabel(); + artic_traffic_label = new QLabel(); artic_traffic_label->setToolTip( tr("Current Artic traffic speed. Higher values indicate bigger transfer loads.")); @@ -515,8 +517,8 @@ void GMainWindow::InitializeWidgets() { tr("Time taken to emulate a 3DS frame, not counting framelimiting or v-sync. For " "full-speed emulation this should be at most 16.67 ms.")); - for (auto& label : - {artic_traffic_label, emu_speed_label, game_fps_label, emu_frametime_label}) { + for (auto& label : {loading_shaders_label, artic_traffic_label, emu_speed_label, game_fps_label, + emu_frametime_label}) { label->setVisible(false); label->setFrameStyle(QFrame::NoFrame); label->setContentsMargins(4, 0, 4, 0); @@ -1430,6 +1432,8 @@ void GMainWindow::BootGame(const QString& filename) { connect(emu_thread.get(), &EmuThread::LoadProgress, loading_screen, &LoadingScreen::OnLoadProgress, Qt::QueuedConnection); + connect(emu_thread.get(), &EmuThread::SwitchDiskResources, this, + &GMainWindow::OnSwitchDiskResources, Qt::QueuedConnection); connect(emu_thread.get(), &EmuThread::HideLoadingScreen, loading_screen, &LoadingScreen::OnLoadComplete); @@ -1529,6 +1533,7 @@ void GMainWindow::ShutdownGame() { status_bar_update_timer.stop(); message_label_used_for_movie = false; show_artic_label = false; + loading_shaders_label->setVisible(false); artic_traffic_label->setVisible(false); emu_speed_label->setVisible(false); game_fps_label->setVisible(false); @@ -3711,6 +3716,18 @@ void GMainWindow::OnEmulatorUpdateAvailable() { } #endif +void GMainWindow::OnSwitchDiskResources(VideoCore::LoadCallbackStage stage, std::size_t value, + std::size_t total) { + if (stage == VideoCore::LoadCallbackStage::Prepare) { + loading_shaders_label->setText(QString()); + loading_shaders_label->setVisible(true); + } else if (stage == VideoCore::LoadCallbackStage::Complete) { + loading_shaders_label->setVisible(false); + } else { + loading_shaders_label->setText(loading_screen->GetStageTranslation(stage, value, total)); + } +} + void GMainWindow::UpdateWindowTitle() { const QString full_name = QString::fromUtf8(Common::g_build_fullname); diff --git a/src/citra_qt/citra_qt.h b/src/citra_qt/citra_qt.h index 90fba44c0..c8d74a131 100644 --- a/src/citra_qt/citra_qt.h +++ b/src/citra_qt/citra_qt.h @@ -24,6 +24,7 @@ #include "citra_qt/user_data_migration.h" #include "core/core.h" #include "core/savestate.h" +#include "video_core/rasterizer_interface.h" // Needs to be included at the end due to https://bugreports.qt.io/browse/QTBUG-73263 #include @@ -299,6 +300,8 @@ private slots: #ifdef ENABLE_QT_UPDATE_CHECKER void OnEmulatorUpdateAvailable(); #endif + void OnSwitchDiskResources(VideoCore::LoadCallbackStage stage, std::size_t value, + std::size_t total); private: Q_INVOKABLE void OnMoviePlaybackCompleted(); @@ -334,6 +337,7 @@ private: QProgressBar* progress_bar = nullptr; QLabel* message_label = nullptr; bool show_artic_label = false; + QLabel* loading_shaders_label = nullptr; QLabel* artic_traffic_label = nullptr; QLabel* emu_speed_label = nullptr; QLabel* game_fps_label = nullptr; diff --git a/src/citra_qt/loading_screen.cpp b/src/citra_qt/loading_screen.cpp index 2135b7db1..ba2fdcaa6 100644 --- a/src/citra_qt/loading_screen.cpp +++ b/src/citra_qt/loading_screen.cpp @@ -1,4 +1,4 @@ -// Copyright 2020 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -184,14 +184,7 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size } // update labels and progress bar - const auto& stg = tr(stage_translations.at(stage)); - if (stage == VideoCore::LoadCallbackStage::Decompile || - stage == VideoCore::LoadCallbackStage::Build || - stage == VideoCore::LoadCallbackStage::Preload) { - ui->stage->setText(stg.arg(value).arg(total)); - } else { - ui->stage->setText(stg); - } + ui->stage->setText(GetStageTranslation(stage, value, total)); ui->value->setText(estimate); ui->progress_bar->setValue(static_cast(value)); previous_time = now; @@ -205,4 +198,16 @@ void LoadingScreen::paintEvent(QPaintEvent* event) { QWidget::paintEvent(event); } +QString LoadingScreen::GetStageTranslation(VideoCore::LoadCallbackStage stage, std::size_t value, + std::size_t total) { + const auto& stg = tr(stage_translations.at(stage)); + if (stage == VideoCore::LoadCallbackStage::Decompile || + stage == VideoCore::LoadCallbackStage::Build || + stage == VideoCore::LoadCallbackStage::Preload) { + return stg.arg(value).arg(total); + } else { + return stg; + } +} + void LoadingScreen::Clear() {} diff --git a/src/citra_qt/loading_screen.h b/src/citra_qt/loading_screen.h index 98d18e243..a6bfc7d09 100644 --- a/src/citra_qt/loading_screen.h +++ b/src/citra_qt/loading_screen.h @@ -1,4 +1,4 @@ -// Copyright 2020 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -49,6 +49,9 @@ public: // See https://wiki.qt.io/How_to_Change_the_Background_Color_of_QWidget void paintEvent(QPaintEvent* event) override; + QString GetStageTranslation(VideoCore::LoadCallbackStage stage, std::size_t value, + std::size_t total); + signals: void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total); /// Signals that this widget is completely hidden now and should be replaced with the other diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 556b2cde3..79e1c0ece 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -509,9 +509,7 @@ Result CIAFile::WriteTitleMetadata(std::span tmd_data, std::size_t off return FileSys::ResultFileNotFound; } - PrepareToImportContent(tmd); - - return ResultSuccess; + return PrepareToImportContent(tmd); } ResultVal CIAFile::WriteContentData(u64 offset, std::size_t length, const u8* buffer) { diff --git a/src/core/hle/service/gsp/gsp_gpu.cpp b/src/core/hle/service/gsp/gsp_gpu.cpp index 8f07c22e6..6887de663 100644 --- a/src/core/hle/service/gsp/gsp_gpu.cpp +++ b/src/core/hle/service/gsp/gsp_gpu.cpp @@ -21,6 +21,7 @@ #include "video_core/gpu.h" #include "video_core/gpu_debugger.h" #include "video_core/pica/regs_lcd.h" +#include "video_core/renderer_base.h" #include "video_core/right_eye_disabler.h" SERIALIZE_EXPORT_IMPL(Service::GSP::SessionData) @@ -613,6 +614,8 @@ Result GSP_GPU::AcquireGpuRight(const Kernel::HLERequestContext& ctx, ErrorLevel::Success}; } + gpu.Renderer().Rasterizer()->SwitchDiskResources(process->codeset->program_id); + if (blocking) { // TODO: The thread should be put to sleep until acquired. ASSERT_MSG(active_thread_id == std::numeric_limits::max(), diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp index 26bff40dd..60a336f72 100644 --- a/src/video_core/rasterizer_accelerated.cpp +++ b/src/video_core/rasterizer_accelerated.cpp @@ -9,6 +9,8 @@ namespace VideoCore { +DiskResourceLoadCallback RasterizerInterface::switch_disk_resources_callback{}; + using Pica::f24; static Common::Vec4f ColorRGBA8(const u32 color) { diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index cd74bae5e..9f024ad2c 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -1,4 +1,4 @@ -// Copyright 2015 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -78,8 +78,15 @@ public: return false; } - virtual void LoadDiskResources([[maybe_unused]] const std::atomic_bool& stop_loading, - [[maybe_unused]] const DiskResourceLoadCallback& callback) {} + virtual void LoadDefaultDiskResources( + [[maybe_unused]] const std::atomic_bool& stop_loading, + [[maybe_unused]] const DiskResourceLoadCallback& callback) {} + + virtual void SwitchDiskResources([[maybe_unused]] u64 title_id) {} + + static void SetSwitchDiskResourcesCallback(const DiskResourceLoadCallback& callback) { + switch_disk_resources_callback = callback; + } virtual void SyncEntireState() {} @@ -89,5 +96,9 @@ public: protected: bool accurate_mul = false; + + // Rasterizer gets destroyed on reboot, so make the callback + // static until a better solution is found. + static DiskResourceLoadCallback switch_disk_resources_callback; }; } // namespace VideoCore diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index fb613b42f..c39a0a10a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -8,6 +8,7 @@ #include "common/logging/log.h" #include "common/math_util.h" #include "common/microprofile.h" +#include "core/loader/loader.h" #include "video_core/pica/pica_core.h" #include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/pica_to_gl.h" @@ -84,8 +85,8 @@ RasterizerOpenGL::RasterizerOpenGL(Memory::MemorySystem& memory, Pica::PicaCore& VideoCore::CustomTexManager& custom_tex_manager, VideoCore::RendererBase& renderer, Driver& driver_) : VideoCore::RasterizerAccelerated{memory, pica}, driver{driver_}, - shader_manager{renderer.GetRenderWindow(), driver, !driver.IsOpenGLES()}, - runtime{driver, renderer}, res_cache{memory, custom_tex_manager, runtime, regs, renderer}, + render_window{renderer.GetRenderWindow()}, runtime{driver, renderer}, + res_cache{memory, custom_tex_manager, runtime, regs, renderer}, vertex_buffer{driver, GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE}, uniform_buffer{driver, GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE}, index_buffer{driver, GL_ELEMENT_ARRAY_BUFFER, INDEX_BUFFER_SIZE}, @@ -173,9 +174,86 @@ void RasterizerOpenGL::TickFrame() { res_cache.TickFrame(); } -void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, - const VideoCore::DiskResourceLoadCallback& callback) { - shader_manager.LoadDiskCache(stop_loading, callback, accurate_mul); +void RasterizerOpenGL::LoadDefaultDiskResources( + const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback) { + // First element in vector is the default one and cannot be removed. + u64 program_id; + if (Core::System::GetInstance().GetAppLoader().ReadProgramId(program_id) != + Loader::ResultStatus::Success) { + program_id = 0; + } + + shader_managers.clear(); + curr_shader_manager = shader_managers.emplace_back(std::make_shared( + render_window, driver, program_id, !driver.IsOpenGLES())); + + curr_shader_manager->LoadDiskCache(stop_loading, callback, accurate_mul); +} + +void RasterizerOpenGL::SwitchDiskResources(u64 title_id) { + // NOTE: curr_shader_manager can be null if emulation restarted without calling + // LoadDefaultDiskResources + + // Check if the current manager is for the specified TID. + if (curr_shader_manager && curr_shader_manager->GetProgramID() == title_id) { + return; + } + + // Search for an existing manager + size_t new_pos = 0; + for (new_pos = 0; new_pos < shader_managers.size(); new_pos++) { + if (shader_managers[new_pos]->GetProgramID() == title_id) { + break; + } + } + // Manager does not exist, create it and append to the end + if (new_pos >= shader_managers.size()) { + new_pos = shader_managers.size(); + auto& new_manager = shader_managers.emplace_back(std::make_shared( + render_window, driver, title_id, !driver.IsOpenGLES())); + + if (switch_disk_resources_callback) { + switch_disk_resources_callback(VideoCore::LoadCallbackStage::Prepare, 0, 0); + } + + std::atomic_bool stop_loading; + new_manager->LoadDiskCache(stop_loading, switch_disk_resources_callback, accurate_mul); + + if (switch_disk_resources_callback) { + switch_disk_resources_callback(VideoCore::LoadCallbackStage::Complete, 0, 0); + } + } + + auto is_applet = [](u64 tid) { + constexpr u32 APPLET_TID_HIGH = 0x00040030; + return static_cast(tid >> 32) == APPLET_TID_HIGH; + }; + + bool prev_applet = curr_shader_manager ? is_applet(curr_shader_manager->GetProgramID()) : false; + bool new_applet = is_applet(shader_managers[new_pos]->GetProgramID()); + curr_shader_manager = shader_managers[new_pos]; + + if (prev_applet) { + // If we came from an applet, clean up all other applets + for (auto it = shader_managers.begin(); it != shader_managers.end();) { + if (it == shader_managers.begin() || *it == curr_shader_manager || + !is_applet((*it)->GetProgramID())) { + it++; + continue; + } + it = shader_managers.erase(it); + } + } + if (!new_applet) { + // If we are going into a non-applet, clean up everything + for (auto it = shader_managers.begin(); it != shader_managers.end();) { + if (it == shader_managers.begin() || *it == curr_shader_manager) { + it++; + continue; + } + it = shader_managers.erase(it); + } + } } void RasterizerOpenGL::SyncFixedState() { @@ -271,7 +349,7 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset, bool RasterizerOpenGL::SetupVertexShader() { MICROPROFILE_SCOPE(OpenGL_VS); - return shader_manager.UseProgrammableVertexShader(regs, pica.vs_setup, accurate_mul); + return curr_shader_manager->UseProgrammableVertexShader(regs, pica.vs_setup, accurate_mul); } bool RasterizerOpenGL::SetupGeometryShader() { @@ -286,9 +364,9 @@ bool RasterizerOpenGL::SetupGeometryShader() { // lighting and care about proper quaternions. Otherwise just use standard vertex+fragment // shaders if (regs.lighting.disable) { - shader_manager.UseTrivialGeometryShader(); + curr_shader_manager->UseTrivialGeometryShader(); } else { - shader_manager.UseFixedGeometryShader(regs); + curr_shader_manager->UseFixedGeometryShader(regs); } return true; @@ -333,7 +411,7 @@ bool RasterizerOpenGL::AccelerateDrawBatchInternal(bool is_indexed) { SetupVertexArray(buffer_ptr, buffer_offset, vs_input_index_min, vs_input_index_max); vertex_buffer.Unmap(vs_input_size); - shader_manager.ApplyTo(state, accurate_mul); + curr_shader_manager->ApplyTo(state, accurate_mul); state.Apply(); if (is_indexed) { @@ -444,7 +522,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { // Sync and bind the shader if (shader_dirty) { - shader_manager.UseFragmentShader(regs, user_config); + curr_shader_manager->UseFragmentShader(regs, user_config); shader_dirty = false; } @@ -462,9 +540,9 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { } else { state.draw.vertex_array = sw_vao.handle; state.draw.vertex_buffer = vertex_buffer.GetHandle(); - shader_manager.UseTrivialVertexShader(); - shader_manager.UseTrivialGeometryShader(); - shader_manager.ApplyTo(state, accurate_mul); + curr_shader_manager->UseTrivialVertexShader(); + curr_shader_manager->UseTrivialGeometryShader(); + curr_shader_manager->ApplyTo(state, accurate_mul); state.Apply(); std::size_t max_vertices = 3 * (VERTEX_BUFFER_SIZE / (3 * sizeof(HardwareVertex))); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index b63b34e86..deb3ccb3f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -1,4 +1,4 @@ -// Copyright 2022 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -40,8 +40,9 @@ public: ~RasterizerOpenGL() override; void TickFrame(); - void LoadDiskResources(const std::atomic_bool& stop_loading, - const VideoCore::DiskResourceLoadCallback& callback) override; + void LoadDefaultDiskResources(const std::atomic_bool& stop_loading, + const VideoCore::DiskResourceLoadCallback& callback) override; + void SwitchDiskResources(u64 title_id) override; void DrawTriangles() override; void FlushAll() override; @@ -137,7 +138,9 @@ private: private: Driver& driver; OpenGLState state; - ShaderProgramManager shader_manager; + Frontend::EmuWindow& render_window; + std::vector> shader_managers; + std::shared_ptr curr_shader_manager{}; TextureRuntime runtime; RasterizerCache res_cache; diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp index 065eeedbe..1f9a16793 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp @@ -1,3 +1,7 @@ +// Copyright Citra Emulator Project / Azahar Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + // Copyright 2019 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -12,8 +16,6 @@ #include "common/scm_rev.h" #include "common/settings.h" #include "common/zstd_compression.h" -#include "core/core.h" -#include "core/loader/loader.h" #include "video_core/renderer_opengl/gl_shader_disk_cache.h" namespace OpenGL { @@ -103,8 +105,8 @@ bool ShaderDiskCacheRaw::Save(FileUtil::IOFile& file) const { return true; } -ShaderDiskCache::ShaderDiskCache(bool separable) - : separable{separable}, transferable_file(AppendTransferableFile()), +ShaderDiskCache::ShaderDiskCache(u64 program_id, bool separable) + : separable{separable}, program_id{program_id}, transferable_file(AppendTransferableFile()), // seperable shaders use the virtual precompile file, that already has a header. precompiled_file(AppendPrecompiledFile(!separable)) {} @@ -568,15 +570,7 @@ std::string ShaderDiskCache::GetBaseDir() const { return FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir) + DIR_SEP "opengl"; } -u64 ShaderDiskCache::GetProgramID() { - // Skip games without title id - if (program_id != 0) { - return program_id; - } - if (Core::System::GetInstance().GetAppLoader().ReadProgramId(program_id) != - Loader::ResultStatus::Success) { - return 0; - } +u64 ShaderDiskCache::GetProgramID() const { return program_id; } diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.h b/src/video_core/renderer_opengl/gl_shader_disk_cache.h index 4720b6ab7..6bc018435 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.h @@ -1,3 +1,7 @@ +// Copyright Citra Emulator Project / Azahar Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + // Copyright 2019 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -83,7 +87,7 @@ struct ShaderDiskCacheDump { class ShaderDiskCache { public: - explicit ShaderDiskCache(bool separable); + explicit ShaderDiskCache(u64 title_id, bool separable); ~ShaderDiskCache() = default; /// Loads transferable cache. If file has a old version or on failure, it deletes the file. @@ -113,6 +117,9 @@ public: /// Serializes virtual precompiled shader cache file to real file void SaveVirtualPrecompiledFile(); + /// Get current game's title id as u64 + u64 GetProgramID() const; + private: /// Loads the transferable cache. Returns empty on failure. std::optional> LoadPrecompiledFile( @@ -161,9 +168,6 @@ private: /// Get user's shader directory path std::string GetBaseDir() const; - /// Get current game's title id as u64 - u64 GetProgramID(); - /// Get current game's title id std::string GetTitleID(); diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 6681980c2..e70319ef3 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp @@ -1,4 +1,4 @@ -// Copyright 2022 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -259,10 +259,10 @@ using FragmentShaders = ShaderCache(driver_, separable)} {} + impl{std::make_unique(driver_, title_id, separable)} {} ShaderProgramManager::~ShaderProgramManager() = default; @@ -425,6 +425,10 @@ void ShaderProgramManager::ApplyTo(OpenGLState& state, bool accurate_mul) { } } +u64 ShaderProgramManager::GetProgramID() const { + return impl->disk_cache.GetProgramID(); +} + void ShaderProgramManager::LoadDiskCache(const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback, bool accurate_mul) { diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index a42aedd5f..652bec51f 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h @@ -1,4 +1,4 @@ -// Copyright 2022 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -34,7 +34,8 @@ enum UniformBindings { /// A class that manage different shader stages and configures them with given config data. class ShaderProgramManager { public: - ShaderProgramManager(Frontend::EmuWindow& emu_window, const Driver& driver, bool separable); + ShaderProgramManager(Frontend::EmuWindow& emu_window, const Driver& driver, u64 title_id, + bool separable); ~ShaderProgramManager(); void LoadDiskCache(const std::atomic_bool& stop_loading, @@ -53,6 +54,8 @@ public: void ApplyTo(OpenGLState& state, bool accurate_mul); + u64 GetProgramID() const; + private: Frontend::EmuWindow& emu_window; const Driver& driver; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 41529d234..942f2ec25 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -143,8 +143,8 @@ void RasterizerVulkan::TickFrame() { res_cache.TickFrame(); } -void RasterizerVulkan::LoadDiskResources(const std::atomic_bool& stop_loading, - const VideoCore::DiskResourceLoadCallback& callback) { +void RasterizerVulkan::LoadDefaultDiskResources( + const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback) { pipeline_cache.LoadDiskCache(); } diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 8f33e0d87..63337487c 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -1,4 +1,4 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -45,8 +45,8 @@ public: ~RasterizerVulkan() override; void TickFrame(); - void LoadDiskResources(const std::atomic_bool& stop_loading, - const VideoCore::DiskResourceLoadCallback& callback) override; + void LoadDefaultDiskResources(const std::atomic_bool& stop_loading, + const VideoCore::DiskResourceLoadCallback& callback) override; void DrawTriangles() override; void FlushAll() override;