diff options
Diffstat (limited to 'src/video_core/renderer_opengl/gl_shader_cache.h')
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 96 |
1 files changed, 46 insertions, 50 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 08f470de3..904d15dd0 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h @@ -4,13 +4,18 @@ #pragma once +#include <array> #include <map> #include <memory> +#include <tuple> + +#include <glad/glad.h> #include "common/assert.h" #include "common/common_types.h" #include "video_core/rasterizer_cache.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_gen.h" namespace OpenGL { @@ -21,6 +26,16 @@ class RasterizerOpenGL; using Shader = std::shared_ptr<CachedShader>; using Maxwell = Tegra::Engines::Maxwell3D::Regs; +struct BaseBindings { + u32 cbuf{}; + u32 gmem{}; + u32 sampler{}; + + bool operator<(const BaseBindings& rhs) const { + return std::tie(cbuf, gmem, sampler) < std::tie(rhs.cbuf, rhs.gmem, rhs.sampler); + } +}; + class CachedShader final : public RasterizerCacheObject { public: CachedShader(VAddr addr, Maxwell::ShaderProgram program_type); @@ -42,67 +57,45 @@ public: } /// Gets the GL program handle for the shader - GLuint GetProgramHandle(GLenum primitive_mode) { - if (program_type != Maxwell::ShaderProgram::Geometry) { - return program.handle; - } - switch (primitive_mode) { - case GL_POINTS: - return LazyGeometryProgram(geometry_programs.points, "points", 1, "ShaderPoints"); - case GL_LINES: - case GL_LINE_STRIP: - return LazyGeometryProgram(geometry_programs.lines, "lines", 2, "ShaderLines"); - case GL_LINES_ADJACENCY: - case GL_LINE_STRIP_ADJACENCY: - return LazyGeometryProgram(geometry_programs.lines_adjacency, "lines_adjacency", 4, - "ShaderLinesAdjacency"); - case GL_TRIANGLES: - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - return LazyGeometryProgram(geometry_programs.triangles, "triangles", 3, - "ShaderTriangles"); - case GL_TRIANGLES_ADJACENCY: - case GL_TRIANGLE_STRIP_ADJACENCY: - return LazyGeometryProgram(geometry_programs.triangles_adjacency, "triangles_adjacency", - 6, "ShaderTrianglesAdjacency"); - default: - UNREACHABLE_MSG("Unknown primitive mode."); - } - } - - /// Gets the GL program resource location for the specified resource, caching as needed - GLuint GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer); - - /// Gets the GL uniform location for the specified resource, caching as needed - GLint GetUniformLocation(const GLShader::SamplerEntry& sampler); + std::tuple<GLuint, BaseBindings> GetProgramHandle(GLenum primitive_mode, + BaseBindings base_bindings); private: - /// Generates a geometry shader or returns one that already exists. - GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology, - u32 max_vertices, const std::string& debug_name); - - VAddr addr; - std::size_t shader_length; - Maxwell::ShaderProgram program_type; - GLShader::ShaderSetup setup; - GLShader::ShaderEntries entries; - - // Non-geometry program. - OGLProgram program; - // Geometry programs. These are needed because GLSL needs an input topology but it's not // declared by the hardware. Workaround this issue by generating a different shader per input // topology class. - struct { - std::string code; + struct GeometryPrograms { OGLProgram points; OGLProgram lines; OGLProgram lines_adjacency; OGLProgram triangles; OGLProgram triangles_adjacency; - } geometry_programs; + }; + + std::string AllocateBindings(BaseBindings base_bindings); - std::map<u32, GLuint> resource_cache; + GLuint GetGeometryShader(GLenum primitive_mode, BaseBindings base_bindings); + + /// Generates a geometry shader or returns one that already exists. + GLuint LazyGeometryProgram(OGLProgram& target_program, BaseBindings base_bindings, + const std::string& glsl_topology, u32 max_vertices, + const std::string& debug_name); + + void CalculateProperties(); + + VAddr addr{}; + std::size_t shader_length{}; + Maxwell::ShaderProgram program_type{}; + GLShader::ShaderSetup setup; + GLShader::ShaderEntries entries; + + std::string code; + + std::map<BaseBindings, OGLProgram> programs; + std::map<BaseBindings, GeometryPrograms> geometry_programs; + + std::map<u32, GLuint> cbuf_resource_cache; + std::map<u32, GLuint> gmem_resource_cache; std::map<u32, GLint> uniform_cache; }; @@ -112,6 +105,9 @@ public: /// Gets the current specified shader stage program Shader GetStageProgram(Maxwell::ShaderProgram program); + +private: + std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; }; } // namespace OpenGL |