diff options
| author | 2020-05-22 20:55:38 -0300 | |
|---|---|---|
| committer | 2020-06-07 04:32:57 -0300 | |
| commit | b96f65b62b143544716f66a65e93d2dcb141ee2b (patch) | |
| tree | 63ff95118403d74e68615ad3017c76ccfc8c42f5 /src | |
| parent | shader_cache: Implement a generic shader cache (diff) | |
| download | yuzu-b96f65b62b143544716f66a65e93d2dcb141ee2b.tar.gz yuzu-b96f65b62b143544716f66a65e93d2dcb141ee2b.tar.xz yuzu-b96f65b62b143544716f66a65e93d2dcb141ee2b.zip | |
gl_shader_cache: Use generic shader cache
Trivially port the generic shader cache to OpenGL.
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 16 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 87 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 51 |
4 files changed, 80 insertions, 93 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 55e79aaf6..909ca9e0e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include "video_core/renderer_opengl/gl_shader_cache.h" | 30 | #include "video_core/renderer_opengl/gl_shader_cache.h" |
| 31 | #include "video_core/renderer_opengl/maxwell_to_gl.h" | 31 | #include "video_core/renderer_opengl/maxwell_to_gl.h" |
| 32 | #include "video_core/renderer_opengl/renderer_opengl.h" | 32 | #include "video_core/renderer_opengl/renderer_opengl.h" |
| 33 | #include "video_core/shader_cache.h" | ||
| 33 | 34 | ||
| 34 | namespace OpenGL { | 35 | namespace OpenGL { |
| 35 | 36 | ||
| @@ -282,7 +283,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 282 | continue; | 283 | continue; |
| 283 | } | 284 | } |
| 284 | 285 | ||
| 285 | Shader shader{shader_cache.GetStageProgram(program)}; | 286 | Shader* const shader = shader_cache.GetStageProgram(program); |
| 286 | 287 | ||
| 287 | if (device.UseAssemblyShaders()) { | 288 | if (device.UseAssemblyShaders()) { |
| 288 | // Check for ARB limitation. We only have 16 SSBOs per context state. To workaround this | 289 | // 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, | |||
| 842 | return true; | 843 | return true; |
| 843 | } | 844 | } |
| 844 | 845 | ||
| 845 | void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, const Shader& shader) { | 846 | void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, Shader* shader) { |
| 846 | static constexpr std::array PARAMETER_LUT = { | 847 | static constexpr std::array PARAMETER_LUT = { |
| 847 | GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV, | 848 | GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV, |
| 848 | GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV, GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV, | 849 | 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 | |||
| 872 | } | 873 | } |
| 873 | } | 874 | } |
| 874 | 875 | ||
| 875 | void RasterizerOpenGL::SetupComputeConstBuffers(const Shader& kernel) { | 876 | void RasterizerOpenGL::SetupComputeConstBuffers(Shader* kernel) { |
| 876 | MICROPROFILE_SCOPE(OpenGL_UBO); | 877 | MICROPROFILE_SCOPE(OpenGL_UBO); |
| 877 | const auto& launch_desc = system.GPU().KeplerCompute().launch_description; | 878 | const auto& launch_desc = system.GPU().KeplerCompute().launch_description; |
| 878 | const auto& entries = kernel->GetEntries(); | 879 | const auto& entries = kernel->GetEntries(); |
| @@ -941,7 +942,7 @@ void RasterizerOpenGL::SetupConstBuffer(GLenum stage, u32 binding, | |||
| 941 | } | 942 | } |
| 942 | } | 943 | } |
| 943 | 944 | ||
| 944 | void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader) { | 945 | void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* shader) { |
| 945 | auto& gpu{system.GPU()}; | 946 | auto& gpu{system.GPU()}; |
| 946 | auto& memory_manager{gpu.MemoryManager()}; | 947 | auto& memory_manager{gpu.MemoryManager()}; |
| 947 | const auto cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]}; | 948 | const auto cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]}; |
| @@ -956,7 +957,7 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shad | |||
| 956 | } | 957 | } |
| 957 | } | 958 | } |
| 958 | 959 | ||
| 959 | void RasterizerOpenGL::SetupComputeGlobalMemory(const Shader& kernel) { | 960 | void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) { |
| 960 | auto& gpu{system.GPU()}; | 961 | auto& gpu{system.GPU()}; |
| 961 | auto& memory_manager{gpu.MemoryManager()}; | 962 | auto& memory_manager{gpu.MemoryManager()}; |
| 962 | const auto cbufs{gpu.KeplerCompute().launch_description.const_buffer_config}; | 963 | const auto cbufs{gpu.KeplerCompute().launch_description.const_buffer_config}; |
| @@ -979,7 +980,7 @@ void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& e | |||
| 979 | static_cast<GLsizeiptr>(size)); | 980 | static_cast<GLsizeiptr>(size)); |
| 980 | } | 981 | } |
| 981 | 982 | ||
| 982 | void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& shader) { | 983 | void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) { |
| 983 | MICROPROFILE_SCOPE(OpenGL_Texture); | 984 | MICROPROFILE_SCOPE(OpenGL_Texture); |
| 984 | const auto& maxwell3d = system.GPU().Maxwell3D(); | 985 | const auto& maxwell3d = system.GPU().Maxwell3D(); |
| 985 | u32 binding = device.GetBaseBindings(stage_index).sampler; | 986 | u32 binding = device.GetBaseBindings(stage_index).sampler; |
| @@ -992,7 +993,7 @@ void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& | |||
| 992 | } | 993 | } |
| 993 | } | 994 | } |
| 994 | 995 | ||
| 995 | void RasterizerOpenGL::SetupComputeTextures(const Shader& kernel) { | 996 | void RasterizerOpenGL::SetupComputeTextures(Shader* kernel) { |
| 996 | MICROPROFILE_SCOPE(OpenGL_Texture); | 997 | MICROPROFILE_SCOPE(OpenGL_Texture); |
| 997 | const auto& compute = system.GPU().KeplerCompute(); | 998 | const auto& compute = system.GPU().KeplerCompute(); |
| 998 | u32 binding = 0; | 999 | u32 binding = 0; |
| @@ -1021,7 +1022,7 @@ void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextu | |||
| 1021 | } | 1022 | } |
| 1022 | } | 1023 | } |
| 1023 | 1024 | ||
| 1024 | void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, const Shader& shader) { | 1025 | void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, Shader* shader) { |
| 1025 | const auto& maxwell3d = system.GPU().Maxwell3D(); | 1026 | const auto& maxwell3d = system.GPU().Maxwell3D(); |
| 1026 | u32 binding = device.GetBaseBindings(stage_index).image; | 1027 | u32 binding = device.GetBaseBindings(stage_index).image; |
| 1027 | for (const auto& entry : shader->GetEntries().images) { | 1028 | for (const auto& entry : shader->GetEntries().images) { |
| @@ -1031,7 +1032,7 @@ void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, const Shader& sh | |||
| 1031 | } | 1032 | } |
| 1032 | } | 1033 | } |
| 1033 | 1034 | ||
| 1034 | void RasterizerOpenGL::SetupComputeImages(const Shader& shader) { | 1035 | void RasterizerOpenGL::SetupComputeImages(Shader* shader) { |
| 1035 | const auto& compute = system.GPU().KeplerCompute(); | 1036 | const auto& compute = system.GPU().KeplerCompute(); |
| 1036 | u32 binding = 0; | 1037 | u32 binding = 0; |
| 1037 | for (const auto& entry : shader->GetEntries().images) { | 1038 | for (const auto& entry : shader->GetEntries().images) { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index f5dc56a0e..1f8d45eac 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -100,10 +100,10 @@ private: | |||
| 100 | void ConfigureClearFramebuffer(bool using_color, bool using_depth_stencil); | 100 | void ConfigureClearFramebuffer(bool using_color, bool using_depth_stencil); |
| 101 | 101 | ||
| 102 | /// Configures the current constbuffers to use for the draw command. | 102 | /// Configures the current constbuffers to use for the draw command. |
| 103 | void SetupDrawConstBuffers(std::size_t stage_index, const Shader& shader); | 103 | void SetupDrawConstBuffers(std::size_t stage_index, Shader* shader); |
| 104 | 104 | ||
| 105 | /// Configures the current constbuffers to use for the kernel invocation. | 105 | /// Configures the current constbuffers to use for the kernel invocation. |
| 106 | void SetupComputeConstBuffers(const Shader& kernel); | 106 | void SetupComputeConstBuffers(Shader* kernel); |
| 107 | 107 | ||
| 108 | /// Configures a constant buffer. | 108 | /// Configures a constant buffer. |
| 109 | void SetupConstBuffer(GLenum stage, u32 binding, const Tegra::Engines::ConstBufferInfo& buffer, | 109 | void SetupConstBuffer(GLenum stage, u32 binding, const Tegra::Engines::ConstBufferInfo& buffer, |
| @@ -111,30 +111,30 @@ private: | |||
| 111 | std::size_t unified_offset); | 111 | std::size_t unified_offset); |
| 112 | 112 | ||
| 113 | /// Configures the current global memory entries to use for the draw command. | 113 | /// Configures the current global memory entries to use for the draw command. |
| 114 | void SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader); | 114 | void SetupDrawGlobalMemory(std::size_t stage_index, Shader* shader); |
| 115 | 115 | ||
| 116 | /// Configures the current global memory entries to use for the kernel invocation. | 116 | /// Configures the current global memory entries to use for the kernel invocation. |
| 117 | void SetupComputeGlobalMemory(const Shader& kernel); | 117 | void SetupComputeGlobalMemory(Shader* kernel); |
| 118 | 118 | ||
| 119 | /// Configures a constant buffer. | 119 | /// Configures a constant buffer. |
| 120 | void SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, GPUVAddr gpu_addr, | 120 | void SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, GPUVAddr gpu_addr, |
| 121 | std::size_t size); | 121 | std::size_t size); |
| 122 | 122 | ||
| 123 | /// Configures the current textures to use for the draw command. | 123 | /// Configures the current textures to use for the draw command. |
| 124 | void SetupDrawTextures(std::size_t stage_index, const Shader& shader); | 124 | void SetupDrawTextures(std::size_t stage_index, Shader* shader); |
| 125 | 125 | ||
| 126 | /// Configures the textures used in a compute shader. | 126 | /// Configures the textures used in a compute shader. |
| 127 | void SetupComputeTextures(const Shader& kernel); | 127 | void SetupComputeTextures(Shader* kernel); |
| 128 | 128 | ||
| 129 | /// Configures a texture. | 129 | /// Configures a texture. |
| 130 | void SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture, | 130 | void SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture, |
| 131 | const SamplerEntry& entry); | 131 | const SamplerEntry& entry); |
| 132 | 132 | ||
| 133 | /// Configures images in a graphics shader. | 133 | /// Configures images in a graphics shader. |
| 134 | void SetupDrawImages(std::size_t stage_index, const Shader& shader); | 134 | void SetupDrawImages(std::size_t stage_index, Shader* shader); |
| 135 | 135 | ||
| 136 | /// Configures images in a compute shader. | 136 | /// Configures images in a compute shader. |
| 137 | void SetupComputeImages(const Shader& shader); | 137 | void SetupComputeImages(Shader* shader); |
| 138 | 138 | ||
| 139 | /// Configures an image. | 139 | /// Configures an image. |
| 140 | void SetupImage(u32 binding, const Tegra::Texture::TICEntry& tic, const ImageEntry& entry); | 140 | void SetupImage(u32 binding, const Tegra::Texture::TICEntry& tic, const ImageEntry& entry); |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index a991ca64a..7c6797e02 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include "video_core/shader/memory_util.h" | 29 | #include "video_core/shader/memory_util.h" |
| 30 | #include "video_core/shader/registry.h" | 30 | #include "video_core/shader/registry.h" |
| 31 | #include "video_core/shader/shader_ir.h" | 31 | #include "video_core/shader/shader_ir.h" |
| 32 | #include "video_core/shader_cache.h" | ||
| 32 | 33 | ||
| 33 | namespace OpenGL { | 34 | namespace OpenGL { |
| 34 | 35 | ||
| @@ -194,12 +195,9 @@ std::unordered_set<GLenum> GetSupportedFormats() { | |||
| 194 | 195 | ||
| 195 | } // Anonymous namespace | 196 | } // Anonymous namespace |
| 196 | 197 | ||
| 197 | CachedShader::CachedShader(VAddr cpu_addr, std::size_t size_in_bytes, | 198 | Shader::Shader(std::shared_ptr<VideoCommon::Shader::Registry> registry, ShaderEntries entries, |
| 198 | std::shared_ptr<VideoCommon::Shader::Registry> registry, | 199 | ProgramSharedPtr program) |
| 199 | ShaderEntries entries, ProgramSharedPtr program_) | 200 | : registry{std::move(registry)}, entries{std::move(entries)}, program{std::move(program)} { |
| 200 | : RasterizerCacheObject{cpu_addr}, registry{std::move(registry)}, entries{std::move(entries)}, | ||
| 201 | size_in_bytes{size_in_bytes}, program{std::move(program_)} { | ||
| 202 | // Assign either the assembly program or source program. We can't have both. | ||
| 203 | handle = program->assembly_program.handle; | 201 | handle = program->assembly_program.handle; |
| 204 | if (handle == 0) { | 202 | if (handle == 0) { |
| 205 | handle = program->source_program.handle; | 203 | handle = program->source_program.handle; |
| @@ -207,16 +205,16 @@ CachedShader::CachedShader(VAddr cpu_addr, std::size_t size_in_bytes, | |||
| 207 | ASSERT(handle != 0); | 205 | ASSERT(handle != 0); |
| 208 | } | 206 | } |
| 209 | 207 | ||
| 210 | CachedShader::~CachedShader() = default; | 208 | Shader::~Shader() = default; |
| 211 | 209 | ||
| 212 | GLuint CachedShader::GetHandle() const { | 210 | GLuint Shader::GetHandle() const { |
| 213 | DEBUG_ASSERT(registry->IsConsistent()); | 211 | DEBUG_ASSERT(registry->IsConsistent()); |
| 214 | return handle; | 212 | return handle; |
| 215 | } | 213 | } |
| 216 | 214 | ||
| 217 | Shader CachedShader::CreateStageFromMemory(const ShaderParameters& params, | 215 | std::unique_ptr<Shader> Shader::CreateStageFromMemory(const ShaderParameters& params, |
| 218 | Maxwell::ShaderProgram program_type, ProgramCode code, | 216 | Maxwell::ShaderProgram program_type, |
| 219 | ProgramCode code_b) { | 217 | ProgramCode code, ProgramCode code_b) { |
| 220 | const auto shader_type = GetShaderType(program_type); | 218 | const auto shader_type = GetShaderType(program_type); |
| 221 | const std::size_t size_in_bytes = code.size() * sizeof(u64); | 219 | const std::size_t size_in_bytes = code.size() * sizeof(u64); |
| 222 | 220 | ||
| @@ -241,12 +239,12 @@ Shader CachedShader::CreateStageFromMemory(const ShaderParameters& params, | |||
| 241 | entry.bindless_samplers = registry->GetBindlessSamplers(); | 239 | entry.bindless_samplers = registry->GetBindlessSamplers(); |
| 242 | params.disk_cache.SaveEntry(std::move(entry)); | 240 | params.disk_cache.SaveEntry(std::move(entry)); |
| 243 | 241 | ||
| 244 | return std::shared_ptr<CachedShader>( | 242 | return std::unique_ptr<Shader>(new Shader( |
| 245 | new CachedShader(params.cpu_addr, size_in_bytes, std::move(registry), | 243 | std::move(registry), MakeEntries(params.device, ir, shader_type), std::move(program))); |
| 246 | MakeEntries(params.device, ir, shader_type), std::move(program))); | ||
| 247 | } | 244 | } |
| 248 | 245 | ||
| 249 | Shader CachedShader::CreateKernelFromMemory(const ShaderParameters& params, ProgramCode code) { | 246 | std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params, |
| 247 | ProgramCode code) { | ||
| 250 | const std::size_t size_in_bytes = code.size() * sizeof(u64); | 248 | const std::size_t size_in_bytes = code.size() * sizeof(u64); |
| 251 | 249 | ||
| 252 | auto& engine = params.system.GPU().KeplerCompute(); | 250 | auto& engine = params.system.GPU().KeplerCompute(); |
| @@ -266,23 +264,23 @@ Shader CachedShader::CreateKernelFromMemory(const ShaderParameters& params, Prog | |||
| 266 | entry.bindless_samplers = registry->GetBindlessSamplers(); | 264 | entry.bindless_samplers = registry->GetBindlessSamplers(); |
| 267 | params.disk_cache.SaveEntry(std::move(entry)); | 265 | params.disk_cache.SaveEntry(std::move(entry)); |
| 268 | 266 | ||
| 269 | return std::shared_ptr<CachedShader>( | 267 | return std::unique_ptr<Shader>(new Shader(std::move(registry), |
| 270 | new CachedShader(params.cpu_addr, size_in_bytes, std::move(registry), | 268 | MakeEntries(params.device, ir, ShaderType::Compute), |
| 271 | MakeEntries(params.device, ir, ShaderType::Compute), std::move(program))); | 269 | std::move(program))); |
| 272 | } | 270 | } |
| 273 | 271 | ||
| 274 | Shader CachedShader::CreateFromCache(const ShaderParameters& params, | 272 | std::unique_ptr<Shader> Shader::CreateFromCache(const ShaderParameters& params, |
| 275 | const PrecompiledShader& precompiled_shader, | 273 | const PrecompiledShader& precompiled_shader) { |
| 276 | std::size_t size_in_bytes) { | 274 | return std::unique_ptr<Shader>(new Shader( |
| 277 | return std::shared_ptr<CachedShader>( | 275 | precompiled_shader.registry, precompiled_shader.entries, precompiled_shader.program)); |
| 278 | new CachedShader(params.cpu_addr, size_in_bytes, precompiled_shader.registry, | ||
| 279 | precompiled_shader.entries, precompiled_shader.program)); | ||
| 280 | } | 276 | } |
| 281 | 277 | ||
| 282 | ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, | 278 | ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, |
| 283 | Core::Frontend::EmuWindow& emu_window, const Device& device) | 279 | Core::Frontend::EmuWindow& emu_window, const Device& device) |
| 284 | : RasterizerCache{rasterizer}, system{system}, emu_window{emu_window}, device{device}, | 280 | : VideoCommon::ShaderCache<Shader>{rasterizer}, system{system}, |
| 285 | disk_cache{system} {} | 281 | emu_window{emu_window}, device{device}, disk_cache{system} {} |
| 282 | |||
| 283 | ShaderCacheOpenGL::~ShaderCacheOpenGL() = default; | ||
| 286 | 284 | ||
| 287 | void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, | 285 | void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, |
| 288 | const VideoCore::DiskResourceLoadCallback& callback) { | 286 | const VideoCore::DiskResourceLoadCallback& callback) { |
| @@ -436,7 +434,7 @@ ProgramSharedPtr ShaderCacheOpenGL::GeneratePrecompiledProgram( | |||
| 436 | return program; | 434 | return program; |
| 437 | } | 435 | } |
| 438 | 436 | ||
| 439 | Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { | 437 | Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { |
| 440 | if (!system.GPU().Maxwell3D().dirty.flags[Dirty::Shaders]) { | 438 | if (!system.GPU().Maxwell3D().dirty.flags[Dirty::Shaders]) { |
| 441 | return last_shaders[static_cast<std::size_t>(program)]; | 439 | return last_shaders[static_cast<std::size_t>(program)]; |
| 442 | } | 440 | } |
| @@ -446,8 +444,7 @@ Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { | |||
| 446 | 444 | ||
| 447 | // Look up shader in the cache based on address | 445 | // Look up shader in the cache based on address |
| 448 | const auto cpu_addr{memory_manager.GpuToCpuAddress(address)}; | 446 | const auto cpu_addr{memory_manager.GpuToCpuAddress(address)}; |
| 449 | Shader shader{cpu_addr ? TryGet(*cpu_addr) : null_shader}; | 447 | if (Shader* const shader{cpu_addr ? TryGet(*cpu_addr) : null_shader.get()}) { |
| 450 | if (shader) { | ||
| 451 | return last_shaders[static_cast<std::size_t>(program)] = shader; | 448 | return last_shaders[static_cast<std::size_t>(program)] = shader; |
| 452 | } | 449 | } |
| 453 | 450 | ||
| @@ -468,30 +465,29 @@ Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { | |||
| 468 | const ShaderParameters params{system, disk_cache, device, | 465 | const ShaderParameters params{system, disk_cache, device, |
| 469 | *cpu_addr, host_ptr, unique_identifier}; | 466 | *cpu_addr, host_ptr, unique_identifier}; |
| 470 | 467 | ||
| 468 | std::unique_ptr<Shader> shader; | ||
| 471 | const auto found = runtime_cache.find(unique_identifier); | 469 | const auto found = runtime_cache.find(unique_identifier); |
| 472 | if (found == runtime_cache.end()) { | 470 | if (found == runtime_cache.end()) { |
| 473 | shader = CachedShader::CreateStageFromMemory(params, program, std::move(code), | 471 | shader = Shader::CreateStageFromMemory(params, program, std::move(code), std::move(code_b)); |
| 474 | std::move(code_b)); | ||
| 475 | } else { | 472 | } else { |
| 476 | const std::size_t size_in_bytes = code.size() * sizeof(u64); | 473 | shader = Shader::CreateFromCache(params, found->second); |
| 477 | shader = CachedShader::CreateFromCache(params, found->second, size_in_bytes); | ||
| 478 | } | 474 | } |
| 479 | 475 | ||
| 476 | Shader* const result = shader.get(); | ||
| 480 | if (cpu_addr) { | 477 | if (cpu_addr) { |
| 481 | Register(shader); | 478 | Register(std::move(shader), *cpu_addr, code.size() * sizeof(u64)); |
| 482 | } else { | 479 | } else { |
| 483 | null_shader = shader; | 480 | null_shader = std::move(shader); |
| 484 | } | 481 | } |
| 485 | 482 | ||
| 486 | return last_shaders[static_cast<std::size_t>(program)] = shader; | 483 | return last_shaders[static_cast<std::size_t>(program)] = result; |
| 487 | } | 484 | } |
| 488 | 485 | ||
| 489 | Shader ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) { | 486 | Shader* ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) { |
| 490 | auto& memory_manager{system.GPU().MemoryManager()}; | 487 | auto& memory_manager{system.GPU().MemoryManager()}; |
| 491 | const auto cpu_addr{memory_manager.GpuToCpuAddress(code_addr)}; | 488 | const auto cpu_addr{memory_manager.GpuToCpuAddress(code_addr)}; |
| 492 | 489 | ||
| 493 | auto kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel; | 490 | if (Shader* const kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get()) { |
| 494 | if (kernel) { | ||
| 495 | return kernel; | 491 | return kernel; |
| 496 | } | 492 | } |
| 497 | 493 | ||
| @@ -503,20 +499,21 @@ Shader ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) { | |||
| 503 | const ShaderParameters params{system, disk_cache, device, | 499 | const ShaderParameters params{system, disk_cache, device, |
| 504 | *cpu_addr, host_ptr, unique_identifier}; | 500 | *cpu_addr, host_ptr, unique_identifier}; |
| 505 | 501 | ||
| 502 | std::unique_ptr<Shader> kernel; | ||
| 506 | const auto found = runtime_cache.find(unique_identifier); | 503 | const auto found = runtime_cache.find(unique_identifier); |
| 507 | if (found == runtime_cache.end()) { | 504 | if (found == runtime_cache.end()) { |
| 508 | kernel = CachedShader::CreateKernelFromMemory(params, std::move(code)); | 505 | kernel = Shader::CreateKernelFromMemory(params, std::move(code)); |
| 509 | } else { | 506 | } else { |
| 510 | const std::size_t size_in_bytes = code.size() * sizeof(u64); | 507 | kernel = Shader::CreateFromCache(params, found->second); |
| 511 | kernel = CachedShader::CreateFromCache(params, found->second, size_in_bytes); | ||
| 512 | } | 508 | } |
| 513 | 509 | ||
| 510 | Shader* const result = kernel.get(); | ||
| 514 | if (cpu_addr) { | 511 | if (cpu_addr) { |
| 515 | Register(kernel); | 512 | Register(std::move(kernel), *cpu_addr, code.size() * sizeof(u64)); |
| 516 | } else { | 513 | } else { |
| 517 | null_kernel = kernel; | 514 | null_kernel = std::move(kernel); |
| 518 | } | 515 | } |
| 519 | return kernel; | 516 | return result; |
| 520 | } | 517 | } |
| 521 | 518 | ||
| 522 | } // namespace OpenGL | 519 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index b2ae8d7f9..6848f1388 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h | |||
| @@ -18,12 +18,12 @@ | |||
| 18 | 18 | ||
| 19 | #include "common/common_types.h" | 19 | #include "common/common_types.h" |
| 20 | #include "video_core/engines/shader_type.h" | 20 | #include "video_core/engines/shader_type.h" |
| 21 | #include "video_core/rasterizer_cache.h" | ||
| 22 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 21 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 23 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" | 22 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" |
| 24 | #include "video_core/renderer_opengl/gl_shader_disk_cache.h" | 23 | #include "video_core/renderer_opengl/gl_shader_disk_cache.h" |
| 25 | #include "video_core/shader/registry.h" | 24 | #include "video_core/shader/registry.h" |
| 26 | #include "video_core/shader/shader_ir.h" | 25 | #include "video_core/shader/shader_ir.h" |
| 26 | #include "video_core/shader_cache.h" | ||
| 27 | 27 | ||
| 28 | namespace Core { | 28 | namespace Core { |
| 29 | class System; | 29 | class System; |
| @@ -35,12 +35,10 @@ class EmuWindow; | |||
| 35 | 35 | ||
| 36 | namespace OpenGL { | 36 | namespace OpenGL { |
| 37 | 37 | ||
| 38 | class CachedShader; | ||
| 39 | class Device; | 38 | class Device; |
| 40 | class RasterizerOpenGL; | 39 | class RasterizerOpenGL; |
| 41 | struct UnspecializedShader; | 40 | struct UnspecializedShader; |
| 42 | 41 | ||
| 43 | using Shader = std::shared_ptr<CachedShader>; | ||
| 44 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 42 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| 45 | 43 | ||
| 46 | struct ProgramHandle { | 44 | struct ProgramHandle { |
| @@ -64,62 +62,53 @@ struct ShaderParameters { | |||
| 64 | u64 unique_identifier; | 62 | u64 unique_identifier; |
| 65 | }; | 63 | }; |
| 66 | 64 | ||
| 67 | class CachedShader final : public RasterizerCacheObject { | 65 | class Shader final { |
| 68 | public: | 66 | public: |
| 69 | ~CachedShader(); | 67 | ~Shader(); |
| 70 | 68 | ||
| 71 | /// Gets the GL program handle for the shader | 69 | /// Gets the GL program handle for the shader |
| 72 | GLuint GetHandle() const; | 70 | GLuint GetHandle() const; |
| 73 | 71 | ||
| 74 | /// Returns the size in bytes of the shader | ||
| 75 | std::size_t GetSizeInBytes() const override { | ||
| 76 | return size_in_bytes; | ||
| 77 | } | ||
| 78 | |||
| 79 | /// Gets the shader entries for the shader | 72 | /// Gets the shader entries for the shader |
| 80 | const ShaderEntries& GetEntries() const { | 73 | const ShaderEntries& GetEntries() const { |
| 81 | return entries; | 74 | return entries; |
| 82 | } | 75 | } |
| 83 | 76 | ||
| 84 | static Shader CreateStageFromMemory(const ShaderParameters& params, | 77 | static std::unique_ptr<Shader> CreateStageFromMemory(const ShaderParameters& params, |
| 85 | Maxwell::ShaderProgram program_type, | 78 | Maxwell::ShaderProgram program_type, |
| 86 | ProgramCode program_code, ProgramCode program_code_b); | 79 | ProgramCode program_code, |
| 87 | static Shader CreateKernelFromMemory(const ShaderParameters& params, ProgramCode code); | 80 | ProgramCode program_code_b); |
| 81 | static std::unique_ptr<Shader> CreateKernelFromMemory(const ShaderParameters& params, | ||
| 82 | ProgramCode code); | ||
| 88 | 83 | ||
| 89 | static Shader CreateFromCache(const ShaderParameters& params, | 84 | static std::unique_ptr<Shader> CreateFromCache(const ShaderParameters& params, |
| 90 | const PrecompiledShader& precompiled_shader, | 85 | const PrecompiledShader& precompiled_shader); |
| 91 | std::size_t size_in_bytes); | ||
| 92 | 86 | ||
| 93 | private: | 87 | private: |
| 94 | explicit CachedShader(VAddr cpu_addr, std::size_t size_in_bytes, | 88 | explicit Shader(std::shared_ptr<VideoCommon::Shader::Registry> registry, ShaderEntries entries, |
| 95 | std::shared_ptr<VideoCommon::Shader::Registry> registry, | 89 | ProgramSharedPtr program); |
| 96 | ShaderEntries entries, ProgramSharedPtr program); | ||
| 97 | 90 | ||
| 98 | std::shared_ptr<VideoCommon::Shader::Registry> registry; | 91 | std::shared_ptr<VideoCommon::Shader::Registry> registry; |
| 99 | ShaderEntries entries; | 92 | ShaderEntries entries; |
| 100 | std::size_t size_in_bytes = 0; | ||
| 101 | ProgramSharedPtr program; | 93 | ProgramSharedPtr program; |
| 102 | GLuint handle = 0; | 94 | GLuint handle = 0; |
| 103 | }; | 95 | }; |
| 104 | 96 | ||
| 105 | class ShaderCacheOpenGL final : public RasterizerCache<Shader> { | 97 | class ShaderCacheOpenGL final : public VideoCommon::ShaderCache<Shader> { |
| 106 | public: | 98 | public: |
| 107 | explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, | 99 | explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, |
| 108 | Core::Frontend::EmuWindow& emu_window, const Device& device); | 100 | Core::Frontend::EmuWindow& emu_window, const Device& device); |
| 101 | ~ShaderCacheOpenGL() override; | ||
| 109 | 102 | ||
| 110 | /// Loads disk cache for the current game | 103 | /// Loads disk cache for the current game |
| 111 | void LoadDiskCache(const std::atomic_bool& stop_loading, | 104 | void LoadDiskCache(const std::atomic_bool& stop_loading, |
| 112 | const VideoCore::DiskResourceLoadCallback& callback); | 105 | const VideoCore::DiskResourceLoadCallback& callback); |
| 113 | 106 | ||
| 114 | /// Gets the current specified shader stage program | 107 | /// Gets the current specified shader stage program |
| 115 | Shader GetStageProgram(Maxwell::ShaderProgram program); | 108 | Shader* GetStageProgram(Maxwell::ShaderProgram program); |
| 116 | 109 | ||
| 117 | /// Gets a compute kernel in the passed address | 110 | /// Gets a compute kernel in the passed address |
| 118 | Shader GetComputeKernel(GPUVAddr code_addr); | 111 | Shader* GetComputeKernel(GPUVAddr code_addr); |
| 119 | |||
| 120 | protected: | ||
| 121 | // We do not have to flush this cache as things in it are never modified by us. | ||
| 122 | void FlushObjectInner(const Shader& object) override {} | ||
| 123 | 112 | ||
| 124 | private: | 113 | private: |
| 125 | ProgramSharedPtr GeneratePrecompiledProgram( | 114 | ProgramSharedPtr GeneratePrecompiledProgram( |
| @@ -132,10 +121,10 @@ private: | |||
| 132 | ShaderDiskCacheOpenGL disk_cache; | 121 | ShaderDiskCacheOpenGL disk_cache; |
| 133 | std::unordered_map<u64, PrecompiledShader> runtime_cache; | 122 | std::unordered_map<u64, PrecompiledShader> runtime_cache; |
| 134 | 123 | ||
| 135 | Shader null_shader{}; | 124 | std::unique_ptr<Shader> null_shader; |
| 136 | Shader null_kernel{}; | 125 | std::unique_ptr<Shader> null_kernel; |
| 137 | 126 | ||
| 138 | std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; | 127 | std::array<Shader*, Maxwell::MaxShaderProgram> last_shaders{}; |
| 139 | }; | 128 | }; |
| 140 | 129 | ||
| 141 | } // namespace OpenGL | 130 | } // namespace OpenGL |