gl_shader_cache: Use generic shader cache
Trivially port the generic shader cache to OpenGL.
This commit is contained in:
parent
dc27252352
commit
b96f65b62b
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Reference in New Issue