|
@@ -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,
|
|
|
|
|
- std::shared_ptr<VideoCommon::Shader::Registry> registry,
|
|
|
|
|
- ShaderEntries entries, ProgramSharedPtr 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.
|
|
|
|
|
|
|
+Shader::Shader(std::shared_ptr<VideoCommon::Shader::Registry> registry, ShaderEntries entries,
|
|
|
|
|
+ ProgramSharedPtr program)
|
|
|
|
|
+ : registry{std::move(registry)}, entries{std::move(entries)}, program{std::move(program)} {
|
|
|
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,
|
|
|
|
|
- Maxwell::ShaderProgram program_type, ProgramCode code,
|
|
|
|
|
- ProgramCode code_b) {
|
|
|
|
|
|
|
+std::unique_ptr<Shader> Shader::CreateStageFromMemory(const ShaderParameters& params,
|
|
|
|
|
+ Maxwell::ShaderProgram program_type,
|
|
|
|
|
+ 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>(
|
|
|
|
|
- new CachedShader(params.cpu_addr, size_in_bytes, std::move(registry),
|
|
|
|
|
- MakeEntries(params.device, ir, shader_type), std::move(program)));
|
|
|
|
|
|
|
+ return std::unique_ptr<Shader>(new Shader(
|
|
|
|
|
+ std::move(registry), 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>(
|
|
|
|
|
- new CachedShader(params.cpu_addr, size_in_bytes, std::move(registry),
|
|
|
|
|
- MakeEntries(params.device, ir, ShaderType::Compute), std::move(program)));
|
|
|
|
|
|
|
+ return std::unique_ptr<Shader>(new Shader(std::move(registry),
|
|
|
|
|
+ MakeEntries(params.device, ir, ShaderType::Compute),
|
|
|
|
|
+ std::move(program)));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Shader CachedShader::CreateFromCache(const ShaderParameters& params,
|
|
|
|
|
- const PrecompiledShader& precompiled_shader,
|
|
|
|
|
- std::size_t size_in_bytes) {
|
|
|
|
|
- return std::shared_ptr<CachedShader>(
|
|
|
|
|
- new CachedShader(params.cpu_addr, size_in_bytes, precompiled_shader.registry,
|
|
|
|
|
- precompiled_shader.entries, precompiled_shader.program));
|
|
|
|
|
|
|
+std::unique_ptr<Shader> Shader::CreateFromCache(const ShaderParameters& params,
|
|
|
|
|
+ const PrecompiledShader& precompiled_shader) {
|
|
|
|
|
+ return std::unique_ptr<Shader>(new Shader(
|
|
|
|
|
+ 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},
|
|
|
|
|
- disk_cache{system} {}
|
|
|
|
|
|
|
+ : VideoCommon::ShaderCache<Shader>{rasterizer}, system{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) {
|
|
|
|
|
|
|
+ if (Shader* const shader{cpu_addr ? TryGet(*cpu_addr) : null_shader.get()}) {
|
|
|
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),
|
|
|
|
|
- std::move(code_b));
|
|
|
|
|
|
|
+ shader = Shader::CreateStageFromMemory(params, program, std::move(code), std::move(code_b));
|
|
|
} else {
|
|
} else {
|
|
|
- const std::size_t size_in_bytes = code.size() * sizeof(u64);
|
|
|
|
|
- shader = CachedShader::CreateFromCache(params, found->second, size_in_bytes);
|
|
|
|
|
|
|
+ shader = Shader::CreateFromCache(params, found->second);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ 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 (kernel) {
|
|
|
|
|
|
|
+ if (Shader* const kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get()) {
|
|
|
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 = CachedShader::CreateFromCache(params, found->second, size_in_bytes);
|
|
|
|
|
|
|
+ kernel = Shader::CreateFromCache(params, found->second);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ 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
|