summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/rasterizer_interface.h4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp29
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h5
5 files changed, 40 insertions, 9 deletions
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index bb4bc0e36..77da135a0 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/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
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 94a5058de..974ca6a20 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/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(
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index ebabf80d1..f3b607f4d 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/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;
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 7eeae082a..e0e624e6f 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/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;
}
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index 6914127c3..9c6b19fc3 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/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);