1
0
Fork 0
forked from suyu/suyu

gl_shader_cache: Link loading screen with disk shader cache load

This commit is contained in:
ReinUsesLisp 2019-01-21 16:38:23 -03:00
parent df0f31f44e
commit eb73247433
10 changed files with 62 additions and 12 deletions

View file

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

View file

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <atomic>
#include <functional> #include <functional>
#include "common/common_types.h" #include "common/common_types.h"
#include "video_core/engines/fermi_2d.h" #include "video_core/engines/fermi_2d.h"
@ -63,6 +64,7 @@ public:
virtual void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) {} virtual void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) {}
/// Initialize disk cached resources for the game being emulated /// 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 } // namespace VideoCore

View file

@ -449,7 +449,7 @@ static constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
return boost::make_iterator_range(map.equal_range(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_start{addr >> Memory::PAGE_BITS};
const u64 page_end{(addr + size + Memory::PAGE_SIZE - 1) >> 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}); cached_pages.add({pages_interval, delta});
} }
void RasterizerOpenGL::LoadDiskResources() { void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
shader_cache.LoadDiskCache(); const VideoCore::DiskResourceLoadCallback& callback) {
shader_cache.LoadDiskCache(stop_loading, callback);
} }
std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers( std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(

View file

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

View file

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

View file

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

View file

@ -29,6 +29,15 @@ void EmuThread::run() {
stop_run = false; 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, // holds whether the cpu was running during the last iteration,
// so that the DebugModeLeft signal can be emitted before the // so that the DebugModeLeft signal can be emitted before the
// next execution step // next execution step

View file

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

View file

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

View file

@ -28,6 +28,7 @@
#include "core/loader/loader.h" #include "core/loader/loader.h"
#include "core/settings.h" #include "core/settings.h"
#include "core/telemetry_session.h" #include "core/telemetry_session.h"
#include "video_core/renderer_base.h"
#include "yuzu_cmd/config.h" #include "yuzu_cmd/config.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2.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"); Core::Telemetry().AddField(Telemetry::FieldType::App, "Frontend", "SDL");
system.Renderer().Rasterizer().LoadDiskResources();
while (emu_window->IsOpen()) { while (emu_window->IsOpen()) {
system.RunLoop(); system.RunLoop();
} }