gl_shader_cache: Link loading screen with disk shader cache load
This commit is contained in:
parent
df0f31f44e
commit
eb73247433
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue