2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

gl_shader_cache: Use generic shader cache

Trivially port the generic shader cache to OpenGL.
This commit is contained in:
ReinUsesLisp 2020-05-22 20:55:38 -03:00
parent dc27252352
commit b96f65b62b
4 changed files with 80 additions and 93 deletions

View file

@ -30,6 +30,7 @@
#include "video_core/renderer_opengl/gl_shader_cache.h" #include "video_core/renderer_opengl/gl_shader_cache.h"
#include "video_core/renderer_opengl/maxwell_to_gl.h" #include "video_core/renderer_opengl/maxwell_to_gl.h"
#include "video_core/renderer_opengl/renderer_opengl.h" #include "video_core/renderer_opengl/renderer_opengl.h"
#include "video_core/shader_cache.h"
namespace OpenGL { namespace OpenGL {
@ -282,7 +283,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
continue; continue;
} }
Shader shader{shader_cache.GetStageProgram(program)}; Shader* const shader = shader_cache.GetStageProgram(program);
if (device.UseAssemblyShaders()) { if (device.UseAssemblyShaders()) {
// Check for ARB limitation. We only have 16 SSBOs per context state. To workaround this // Check for ARB limitation. We only have 16 SSBOs per context state. To workaround this
@ -842,7 +843,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
return true; return true;
} }
void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, const Shader& shader) { void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, Shader* shader) {
static constexpr std::array PARAMETER_LUT = { static constexpr std::array PARAMETER_LUT = {
GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV, GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV,
GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV, GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV, GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV,
@ -872,7 +873,7 @@ void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, const Shad
} }
} }
void RasterizerOpenGL::SetupComputeConstBuffers(const Shader& kernel) { void RasterizerOpenGL::SetupComputeConstBuffers(Shader* kernel) {
MICROPROFILE_SCOPE(OpenGL_UBO); MICROPROFILE_SCOPE(OpenGL_UBO);
const auto& launch_desc = system.GPU().KeplerCompute().launch_description; const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
const auto& entries = kernel->GetEntries(); const auto& entries = kernel->GetEntries();
@ -941,7 +942,7 @@ void RasterizerOpenGL::SetupConstBuffer(GLenum stage, u32 binding,
} }
} }
void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader) { void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* shader) {
auto& gpu{system.GPU()}; auto& gpu{system.GPU()};
auto& memory_manager{gpu.MemoryManager()}; auto& memory_manager{gpu.MemoryManager()};
const auto cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]}; const auto cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]};
@ -956,7 +957,7 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shad
} }
} }
void RasterizerOpenGL::SetupComputeGlobalMemory(const Shader& kernel) { void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) {
auto& gpu{system.GPU()}; auto& gpu{system.GPU()};
auto& memory_manager{gpu.MemoryManager()}; auto& memory_manager{gpu.MemoryManager()};
const auto cbufs{gpu.KeplerCompute().launch_description.const_buffer_config}; const auto cbufs{gpu.KeplerCompute().launch_description.const_buffer_config};
@ -979,7 +980,7 @@ void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& e
static_cast<GLsizeiptr>(size)); static_cast<GLsizeiptr>(size));
} }
void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& shader) { void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) {
MICROPROFILE_SCOPE(OpenGL_Texture); MICROPROFILE_SCOPE(OpenGL_Texture);
const auto& maxwell3d = system.GPU().Maxwell3D(); const auto& maxwell3d = system.GPU().Maxwell3D();
u32 binding = device.GetBaseBindings(stage_index).sampler; u32 binding = device.GetBaseBindings(stage_index).sampler;
@ -992,7 +993,7 @@ void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader&
} }
} }
void RasterizerOpenGL::SetupComputeTextures(const Shader& kernel) { void RasterizerOpenGL::SetupComputeTextures(Shader* kernel) {
MICROPROFILE_SCOPE(OpenGL_Texture); MICROPROFILE_SCOPE(OpenGL_Texture);
const auto& compute = system.GPU().KeplerCompute(); const auto& compute = system.GPU().KeplerCompute();
u32 binding = 0; u32 binding = 0;
@ -1021,7 +1022,7 @@ void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextu
} }
} }
void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, const Shader& shader) { void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, Shader* shader) {
const auto& maxwell3d = system.GPU().Maxwell3D(); const auto& maxwell3d = system.GPU().Maxwell3D();
u32 binding = device.GetBaseBindings(stage_index).image; u32 binding = device.GetBaseBindings(stage_index).image;
for (const auto& entry : shader->GetEntries().images) { for (const auto& entry : shader->GetEntries().images) {
@ -1031,7 +1032,7 @@ void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, const Shader& sh
} }
} }
void RasterizerOpenGL::SetupComputeImages(const Shader& shader) { void RasterizerOpenGL::SetupComputeImages(Shader* shader) {
const auto& compute = system.GPU().KeplerCompute(); const auto& compute = system.GPU().KeplerCompute();
u32 binding = 0; u32 binding = 0;
for (const auto& entry : shader->GetEntries().images) { for (const auto& entry : shader->GetEntries().images) {

View file

@ -100,10 +100,10 @@ private:
void ConfigureClearFramebuffer(bool using_color, bool using_depth_stencil); void ConfigureClearFramebuffer(bool using_color, bool using_depth_stencil);
/// Configures the current constbuffers to use for the draw command. /// Configures the current constbuffers to use for the draw command.
void SetupDrawConstBuffers(std::size_t stage_index, const Shader& shader); void SetupDrawConstBuffers(std::size_t stage_index, Shader* shader);
/// Configures the current constbuffers to use for the kernel invocation. /// Configures the current constbuffers to use for the kernel invocation.
void SetupComputeConstBuffers(const Shader& kernel); void SetupComputeConstBuffers(Shader* kernel);
/// Configures a constant buffer. /// Configures a constant buffer.
void SetupConstBuffer(GLenum stage, u32 binding, const Tegra::Engines::ConstBufferInfo& buffer, void SetupConstBuffer(GLenum stage, u32 binding, const Tegra::Engines::ConstBufferInfo& buffer,
@ -111,30 +111,30 @@ private:
std::size_t unified_offset); std::size_t unified_offset);
/// Configures the current global memory entries to use for the draw command. /// Configures the current global memory entries to use for the draw command.
void SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader); void SetupDrawGlobalMemory(std::size_t stage_index, Shader* shader);
/// Configures the current global memory entries to use for the kernel invocation. /// Configures the current global memory entries to use for the kernel invocation.
void SetupComputeGlobalMemory(const Shader& kernel); void SetupComputeGlobalMemory(Shader* kernel);
/// Configures a constant buffer. /// Configures a constant buffer.
void SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, GPUVAddr gpu_addr, void SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, GPUVAddr gpu_addr,
std::size_t size); std::size_t size);
/// Configures the current textures to use for the draw command. /// Configures the current textures to use for the draw command.
void SetupDrawTextures(std::size_t stage_index, const Shader& shader); void SetupDrawTextures(std::size_t stage_index, Shader* shader);
/// Configures the textures used in a compute shader. /// Configures the textures used in a compute shader.
void SetupComputeTextures(const Shader& kernel); void SetupComputeTextures(Shader* kernel);
/// Configures a texture. /// Configures a texture.
void SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture, void SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture,
const SamplerEntry& entry); const SamplerEntry& entry);
/// Configures images in a graphics shader. /// Configures images in a graphics shader.
void SetupDrawImages(std::size_t stage_index, const Shader& shader); void SetupDrawImages(std::size_t stage_index, Shader* shader);
/// Configures images in a compute shader. /// Configures images in a compute shader.
void SetupComputeImages(const Shader& shader); void SetupComputeImages(Shader* shader);
/// Configures an image. /// Configures an image.
void SetupImage(u32 binding, const Tegra::Texture::TICEntry& tic, const ImageEntry& entry); void SetupImage(u32 binding, const Tegra::Texture::TICEntry& tic, const ImageEntry& entry);

View file

@ -29,6 +29,7 @@
#include "video_core/shader/memory_util.h" #include "video_core/shader/memory_util.h"
#include "video_core/shader/registry.h" #include "video_core/shader/registry.h"
#include "video_core/shader/shader_ir.h" #include "video_core/shader/shader_ir.h"
#include "video_core/shader_cache.h"
namespace OpenGL { namespace OpenGL {
@ -194,12 +195,9 @@ std::unordered_set<GLenum> GetSupportedFormats() {
} // Anonymous namespace } // Anonymous namespace
CachedShader::CachedShader(VAddr cpu_addr, std::size_t size_in_bytes, Shader::Shader(std::shared_ptr<VideoCommon::Shader::Registry> registry, ShaderEntries entries,
std::shared_ptr<VideoCommon::Shader::Registry> registry, ProgramSharedPtr program)
ShaderEntries entries, ProgramSharedPtr program_) : registry{std::move(registry)}, entries{std::move(entries)}, program{std::move(program)} {
: RasterizerCacheObject{cpu_addr}, registry{std::move(registry)}, entries{std::move(entries)},
size_in_bytes{size_in_bytes}, program{std::move(program_)} {
// Assign either the assembly program or source program. We can't have both.
handle = program->assembly_program.handle; handle = program->assembly_program.handle;
if (handle == 0) { if (handle == 0) {
handle = program->source_program.handle; handle = program->source_program.handle;
@ -207,16 +205,16 @@ CachedShader::CachedShader(VAddr cpu_addr, std::size_t size_in_bytes,
ASSERT(handle != 0); ASSERT(handle != 0);
} }
CachedShader::~CachedShader() = default; Shader::~Shader() = default;
GLuint CachedShader::GetHandle() const { GLuint Shader::GetHandle() const {
DEBUG_ASSERT(registry->IsConsistent()); DEBUG_ASSERT(registry->IsConsistent());
return handle; return handle;
} }
Shader CachedShader::CreateStageFromMemory(const ShaderParameters& params, std::unique_ptr<Shader> Shader::CreateStageFromMemory(const ShaderParameters& params,
Maxwell::ShaderProgram program_type, ProgramCode code, Maxwell::ShaderProgram program_type,
ProgramCode code_b) { ProgramCode code, ProgramCode code_b) {
const auto shader_type = GetShaderType(program_type); const auto shader_type = GetShaderType(program_type);
const std::size_t size_in_bytes = code.size() * sizeof(u64); const std::size_t size_in_bytes = code.size() * sizeof(u64);
@ -241,12 +239,12 @@ Shader CachedShader::CreateStageFromMemory(const ShaderParameters& params,
entry.bindless_samplers = registry->GetBindlessSamplers(); entry.bindless_samplers = registry->GetBindlessSamplers();
params.disk_cache.SaveEntry(std::move(entry)); params.disk_cache.SaveEntry(std::move(entry));
return std::shared_ptr<CachedShader>( return std::unique_ptr<Shader>(new Shader(
new CachedShader(params.cpu_addr, size_in_bytes, std::move(registry), std::move(registry), MakeEntries(params.device, ir, shader_type), std::move(program)));
MakeEntries(params.device, ir, shader_type), std::move(program)));
} }
Shader CachedShader::CreateKernelFromMemory(const ShaderParameters& params, ProgramCode code) { std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params,
ProgramCode code) {
const std::size_t size_in_bytes = code.size() * sizeof(u64); const std::size_t size_in_bytes = code.size() * sizeof(u64);
auto& engine = params.system.GPU().KeplerCompute(); auto& engine = params.system.GPU().KeplerCompute();
@ -266,23 +264,23 @@ Shader CachedShader::CreateKernelFromMemory(const ShaderParameters& params, Prog
entry.bindless_samplers = registry->GetBindlessSamplers(); entry.bindless_samplers = registry->GetBindlessSamplers();
params.disk_cache.SaveEntry(std::move(entry)); params.disk_cache.SaveEntry(std::move(entry));
return std::shared_ptr<CachedShader>( return std::unique_ptr<Shader>(new Shader(std::move(registry),
new CachedShader(params.cpu_addr, size_in_bytes, std::move(registry), MakeEntries(params.device, ir, ShaderType::Compute),
MakeEntries(params.device, ir, ShaderType::Compute), std::move(program))); std::move(program)));
} }
Shader CachedShader::CreateFromCache(const ShaderParameters& params, std::unique_ptr<Shader> Shader::CreateFromCache(const ShaderParameters& params,
const PrecompiledShader& precompiled_shader, const PrecompiledShader& precompiled_shader) {
std::size_t size_in_bytes) { return std::unique_ptr<Shader>(new Shader(
return std::shared_ptr<CachedShader>( precompiled_shader.registry, precompiled_shader.entries, precompiled_shader.program));
new CachedShader(params.cpu_addr, size_in_bytes, precompiled_shader.registry,
precompiled_shader.entries, precompiled_shader.program));
} }
ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system,
Core::Frontend::EmuWindow& emu_window, const Device& device) Core::Frontend::EmuWindow& emu_window, const Device& device)
: RasterizerCache{rasterizer}, system{system}, emu_window{emu_window}, device{device}, : VideoCommon::ShaderCache<Shader>{rasterizer}, system{system},
disk_cache{system} {} emu_window{emu_window}, device{device}, disk_cache{system} {}
ShaderCacheOpenGL::~ShaderCacheOpenGL() = default;
void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
const VideoCore::DiskResourceLoadCallback& callback) { const VideoCore::DiskResourceLoadCallback& callback) {
@ -436,7 +434,7 @@ ProgramSharedPtr ShaderCacheOpenGL::GeneratePrecompiledProgram(
return program; return program;
} }
Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
if (!system.GPU().Maxwell3D().dirty.flags[Dirty::Shaders]) { if (!system.GPU().Maxwell3D().dirty.flags[Dirty::Shaders]) {
return last_shaders[static_cast<std::size_t>(program)]; return last_shaders[static_cast<std::size_t>(program)];
} }
@ -446,8 +444,7 @@ Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
// Look up shader in the cache based on address // Look up shader in the cache based on address
const auto cpu_addr{memory_manager.GpuToCpuAddress(address)}; const auto cpu_addr{memory_manager.GpuToCpuAddress(address)};
Shader shader{cpu_addr ? TryGet(*cpu_addr) : null_shader}; if (Shader* const shader{cpu_addr ? TryGet(*cpu_addr) : null_shader.get()}) {
if (shader) {
return last_shaders[static_cast<std::size_t>(program)] = shader; return last_shaders[static_cast<std::size_t>(program)] = shader;
} }
@ -468,30 +465,29 @@ Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
const ShaderParameters params{system, disk_cache, device, const ShaderParameters params{system, disk_cache, device,
*cpu_addr, host_ptr, unique_identifier}; *cpu_addr, host_ptr, unique_identifier};
std::unique_ptr<Shader> shader;
const auto found = runtime_cache.find(unique_identifier); const auto found = runtime_cache.find(unique_identifier);
if (found == runtime_cache.end()) { if (found == runtime_cache.end()) {
shader = CachedShader::CreateStageFromMemory(params, program, std::move(code), shader = Shader::CreateStageFromMemory(params, program, std::move(code), std::move(code_b));
std::move(code_b));
} else { } else {
const std::size_t size_in_bytes = code.size() * sizeof(u64); shader = Shader::CreateFromCache(params, found->second);
shader = CachedShader::CreateFromCache(params, found->second, size_in_bytes);
} }
Shader* const result = shader.get();
if (cpu_addr) { if (cpu_addr) {
Register(shader); Register(std::move(shader), *cpu_addr, code.size() * sizeof(u64));
} else { } else {
null_shader = shader; null_shader = std::move(shader);
} }
return last_shaders[static_cast<std::size_t>(program)] = shader; return last_shaders[static_cast<std::size_t>(program)] = result;
} }
Shader ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) { Shader* ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) {
auto& memory_manager{system.GPU().MemoryManager()}; auto& memory_manager{system.GPU().MemoryManager()};
const auto cpu_addr{memory_manager.GpuToCpuAddress(code_addr)}; const auto cpu_addr{memory_manager.GpuToCpuAddress(code_addr)};
auto kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel; if (Shader* const kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get()) {
if (kernel) {
return kernel; return kernel;
} }
@ -503,20 +499,21 @@ Shader ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) {
const ShaderParameters params{system, disk_cache, device, const ShaderParameters params{system, disk_cache, device,
*cpu_addr, host_ptr, unique_identifier}; *cpu_addr, host_ptr, unique_identifier};
std::unique_ptr<Shader> kernel;
const auto found = runtime_cache.find(unique_identifier); const auto found = runtime_cache.find(unique_identifier);
if (found == runtime_cache.end()) { if (found == runtime_cache.end()) {
kernel = CachedShader::CreateKernelFromMemory(params, std::move(code)); kernel = Shader::CreateKernelFromMemory(params, std::move(code));
} else { } else {
const std::size_t size_in_bytes = code.size() * sizeof(u64); kernel = Shader::CreateFromCache(params, found->second);
kernel = CachedShader::CreateFromCache(params, found->second, size_in_bytes);
} }
Shader* const result = kernel.get();
if (cpu_addr) { if (cpu_addr) {
Register(kernel); Register(std::move(kernel), *cpu_addr, code.size() * sizeof(u64));
} else { } else {
null_kernel = kernel; null_kernel = std::move(kernel);
} }
return kernel; return result;
} }
} // namespace OpenGL } // namespace OpenGL

View file

@ -18,12 +18,12 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "video_core/engines/shader_type.h" #include "video_core/engines/shader_type.h"
#include "video_core/rasterizer_cache.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"
#include "video_core/shader/registry.h" #include "video_core/shader/registry.h"
#include "video_core/shader/shader_ir.h" #include "video_core/shader/shader_ir.h"
#include "video_core/shader_cache.h"
namespace Core { namespace Core {
class System; class System;
@ -35,12 +35,10 @@ class EmuWindow;
namespace OpenGL { namespace OpenGL {
class CachedShader;
class Device; class Device;
class RasterizerOpenGL; class RasterizerOpenGL;
struct UnspecializedShader; struct UnspecializedShader;
using Shader = std::shared_ptr<CachedShader>;
using Maxwell = Tegra::Engines::Maxwell3D::Regs; using Maxwell = Tegra::Engines::Maxwell3D::Regs;
struct ProgramHandle { struct ProgramHandle {
@ -64,62 +62,53 @@ struct ShaderParameters {
u64 unique_identifier; u64 unique_identifier;
}; };
class CachedShader final : public RasterizerCacheObject { class Shader final {
public: public:
~CachedShader(); ~Shader();
/// Gets the GL program handle for the shader /// Gets the GL program handle for the shader
GLuint GetHandle() const; GLuint GetHandle() const;
/// Returns the size in bytes of the shader
std::size_t GetSizeInBytes() const override {
return size_in_bytes;
}
/// Gets the shader entries for the shader /// Gets the shader entries for the shader
const ShaderEntries& GetEntries() const { const ShaderEntries& GetEntries() const {
return entries; return entries;
} }
static Shader CreateStageFromMemory(const ShaderParameters& params, static std::unique_ptr<Shader> CreateStageFromMemory(const ShaderParameters& params,
Maxwell::ShaderProgram program_type, Maxwell::ShaderProgram program_type,
ProgramCode program_code, ProgramCode program_code_b); ProgramCode program_code,
static Shader CreateKernelFromMemory(const ShaderParameters& params, ProgramCode code); ProgramCode program_code_b);
static std::unique_ptr<Shader> CreateKernelFromMemory(const ShaderParameters& params,
ProgramCode code);
static Shader CreateFromCache(const ShaderParameters& params, static std::unique_ptr<Shader> CreateFromCache(const ShaderParameters& params,
const PrecompiledShader& precompiled_shader, const PrecompiledShader& precompiled_shader);
std::size_t size_in_bytes);
private: private:
explicit CachedShader(VAddr cpu_addr, std::size_t size_in_bytes, explicit Shader(std::shared_ptr<VideoCommon::Shader::Registry> registry, ShaderEntries entries,
std::shared_ptr<VideoCommon::Shader::Registry> registry, ProgramSharedPtr program);
ShaderEntries entries, ProgramSharedPtr program);
std::shared_ptr<VideoCommon::Shader::Registry> registry; std::shared_ptr<VideoCommon::Shader::Registry> registry;
ShaderEntries entries; ShaderEntries entries;
std::size_t size_in_bytes = 0;
ProgramSharedPtr program; ProgramSharedPtr program;
GLuint handle = 0; GLuint handle = 0;
}; };
class ShaderCacheOpenGL final : public RasterizerCache<Shader> { class ShaderCacheOpenGL final : public VideoCommon::ShaderCache<Shader> {
public: public:
explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system,
Core::Frontend::EmuWindow& emu_window, const Device& device); Core::Frontend::EmuWindow& emu_window, const Device& device);
~ShaderCacheOpenGL() override;
/// Loads disk cache for the current game /// Loads disk cache for the current game
void LoadDiskCache(const std::atomic_bool& stop_loading, void LoadDiskCache(const std::atomic_bool& stop_loading,
const VideoCore::DiskResourceLoadCallback& callback); 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);
/// Gets a compute kernel in the passed address /// Gets a compute kernel in the passed address
Shader GetComputeKernel(GPUVAddr code_addr); Shader* GetComputeKernel(GPUVAddr code_addr);
protected:
// We do not have to flush this cache as things in it are never modified by us.
void FlushObjectInner(const Shader& object) override {}
private: private:
ProgramSharedPtr GeneratePrecompiledProgram( ProgramSharedPtr GeneratePrecompiledProgram(
@ -132,10 +121,10 @@ private:
ShaderDiskCacheOpenGL disk_cache; ShaderDiskCacheOpenGL disk_cache;
std::unordered_map<u64, PrecompiledShader> runtime_cache; std::unordered_map<u64, PrecompiledShader> runtime_cache;
Shader null_shader{}; std::unique_ptr<Shader> null_shader;
Shader null_kernel{}; std::unique_ptr<Shader> null_kernel;
std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; std::array<Shader*, Maxwell::MaxShaderProgram> last_shaders{};
}; };
} // namespace OpenGL } // namespace OpenGL