diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 94 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 32 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_sampler_cache.cpp | 52 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_sampler_cache.h | 25 |
5 files changed, 82 insertions, 123 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 1a0cc6df1..6950e9d09 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -46,6 +46,8 @@ add_library(video_core STATIC | |||
| 46 | renderer_opengl/gl_rasterizer_cache.h | 46 | renderer_opengl/gl_rasterizer_cache.h |
| 47 | renderer_opengl/gl_resource_manager.cpp | 47 | renderer_opengl/gl_resource_manager.cpp |
| 48 | renderer_opengl/gl_resource_manager.h | 48 | renderer_opengl/gl_resource_manager.h |
| 49 | renderer_opengl/gl_sampler_cache.cpp | ||
| 50 | renderer_opengl/gl_sampler_cache.h | ||
| 49 | renderer_opengl/gl_shader_cache.cpp | 51 | renderer_opengl/gl_shader_cache.cpp |
| 50 | renderer_opengl/gl_shader_cache.h | 52 | renderer_opengl/gl_shader_cache.h |
| 51 | renderer_opengl/gl_shader_decompiler.cpp | 53 | renderer_opengl/gl_shader_decompiler.cpp |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 046fc935b..40b9f4809 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -103,12 +103,6 @@ struct FramebufferCacheKey { | |||
| 103 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, ScreenInfo& info) | 103 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, ScreenInfo& info) |
| 104 | : res_cache{*this}, shader_cache{*this, system}, global_cache{*this}, system{system}, | 104 | : res_cache{*this}, shader_cache{*this, system}, global_cache{*this}, system{system}, |
| 105 | screen_info{info}, buffer_cache(*this, STREAM_BUFFER_SIZE) { | 105 | screen_info{info}, buffer_cache(*this, STREAM_BUFFER_SIZE) { |
| 106 | // Create sampler objects | ||
| 107 | for (std::size_t i = 0; i < texture_samplers.size(); ++i) { | ||
| 108 | texture_samplers[i].Create(); | ||
| 109 | state.texture_units[i].sampler = texture_samplers[i].sampler.handle; | ||
| 110 | } | ||
| 111 | |||
| 112 | OpenGLState::ApplyDefaultState(); | 106 | OpenGLState::ApplyDefaultState(); |
| 113 | 107 | ||
| 114 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); | 108 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); |
| @@ -807,92 +801,6 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, | |||
| 807 | return true; | 801 | return true; |
| 808 | } | 802 | } |
| 809 | 803 | ||
| 810 | void RasterizerOpenGL::SamplerInfo::Create() { | ||
| 811 | sampler.Create(); | ||
| 812 | mag_filter = Tegra::Texture::TextureFilter::Linear; | ||
| 813 | min_filter = Tegra::Texture::TextureFilter::Linear; | ||
| 814 | wrap_u = Tegra::Texture::WrapMode::Wrap; | ||
| 815 | wrap_v = Tegra::Texture::WrapMode::Wrap; | ||
| 816 | wrap_p = Tegra::Texture::WrapMode::Wrap; | ||
| 817 | use_depth_compare = false; | ||
| 818 | depth_compare_func = Tegra::Texture::DepthCompareFunc::Never; | ||
| 819 | |||
| 820 | // OpenGL's default is GL_LINEAR_MIPMAP_LINEAR | ||
| 821 | glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
| 822 | glSamplerParameteri(sampler.handle, GL_TEXTURE_COMPARE_FUNC, GL_NEVER); | ||
| 823 | |||
| 824 | // Other attributes have correct defaults | ||
| 825 | } | ||
| 826 | |||
| 827 | void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) { | ||
| 828 | const GLuint sampler_id = sampler.handle; | ||
| 829 | if (mag_filter != config.mag_filter) { | ||
| 830 | mag_filter = config.mag_filter; | ||
| 831 | glSamplerParameteri( | ||
| 832 | sampler_id, GL_TEXTURE_MAG_FILTER, | ||
| 833 | MaxwellToGL::TextureFilterMode(mag_filter, Tegra::Texture::TextureMipmapFilter::None)); | ||
| 834 | } | ||
| 835 | if (min_filter != config.min_filter || mipmap_filter != config.mipmap_filter) { | ||
| 836 | min_filter = config.min_filter; | ||
| 837 | mipmap_filter = config.mipmap_filter; | ||
| 838 | glSamplerParameteri(sampler_id, GL_TEXTURE_MIN_FILTER, | ||
| 839 | MaxwellToGL::TextureFilterMode(min_filter, mipmap_filter)); | ||
| 840 | } | ||
| 841 | |||
| 842 | if (wrap_u != config.wrap_u) { | ||
| 843 | wrap_u = config.wrap_u; | ||
| 844 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(wrap_u)); | ||
| 845 | } | ||
| 846 | if (wrap_v != config.wrap_v) { | ||
| 847 | wrap_v = config.wrap_v; | ||
| 848 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(wrap_v)); | ||
| 849 | } | ||
| 850 | if (wrap_p != config.wrap_p) { | ||
| 851 | wrap_p = config.wrap_p; | ||
| 852 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(wrap_p)); | ||
| 853 | } | ||
| 854 | |||
| 855 | if (const bool enabled = config.depth_compare_enabled == 1; use_depth_compare != enabled) { | ||
| 856 | use_depth_compare = enabled; | ||
| 857 | glSamplerParameteri(sampler_id, GL_TEXTURE_COMPARE_MODE, | ||
| 858 | use_depth_compare ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE); | ||
| 859 | } | ||
| 860 | |||
| 861 | if (depth_compare_func != config.depth_compare_func) { | ||
| 862 | depth_compare_func = config.depth_compare_func; | ||
| 863 | glSamplerParameteri(sampler_id, GL_TEXTURE_COMPARE_FUNC, | ||
| 864 | MaxwellToGL::DepthCompareFunc(depth_compare_func)); | ||
| 865 | } | ||
| 866 | |||
| 867 | if (const auto new_border_color = config.GetBorderColor(); border_color != new_border_color) { | ||
| 868 | border_color = new_border_color; | ||
| 869 | glSamplerParameterfv(sampler_id, GL_TEXTURE_BORDER_COLOR, border_color.data()); | ||
| 870 | } | ||
| 871 | |||
| 872 | if (const float anisotropic = config.GetMaxAnisotropy(); max_anisotropic != anisotropic) { | ||
| 873 | max_anisotropic = anisotropic; | ||
| 874 | if (GLAD_GL_ARB_texture_filter_anisotropic) { | ||
| 875 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropic); | ||
| 876 | } else if (GLAD_GL_EXT_texture_filter_anisotropic) { | ||
| 877 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropic); | ||
| 878 | } | ||
| 879 | } | ||
| 880 | |||
| 881 | if (const float min = config.GetMinLod(); min_lod != min) { | ||
| 882 | min_lod = min; | ||
| 883 | glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, min_lod); | ||
| 884 | } | ||
| 885 | if (const float max = config.GetMaxLod(); max_lod != max) { | ||
| 886 | max_lod = max; | ||
| 887 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, max_lod); | ||
| 888 | } | ||
| 889 | |||
| 890 | if (const float bias = config.GetLodBias(); lod_bias != bias) { | ||
| 891 | lod_bias = bias; | ||
| 892 | glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, lod_bias); | ||
| 893 | } | ||
| 894 | } | ||
| 895 | |||
| 896 | void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, | 804 | void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, |
| 897 | const Shader& shader, GLuint program_handle, | 805 | const Shader& shader, GLuint program_handle, |
| 898 | BaseBindings base_bindings) { | 806 | BaseBindings base_bindings) { |
| @@ -988,7 +896,7 @@ void RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, const Shader& s | |||
| 988 | const auto texture = maxwell3d.GetStageTexture(stage, entry.GetOffset()); | 896 | const auto texture = maxwell3d.GetStageTexture(stage, entry.GetOffset()); |
| 989 | const u32 current_bindpoint = base_bindings.sampler + bindpoint; | 897 | const u32 current_bindpoint = base_bindings.sampler + bindpoint; |
| 990 | 898 | ||
| 991 | texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); | 899 | state.texture_units[current_bindpoint].sampler = sampler_cache.GetSampler(texture.tsc); |
| 992 | 900 | ||
| 993 | if (Surface surface = res_cache.GetTextureSurface(texture, entry); surface) { | 901 | if (Surface surface = res_cache.GetTextureSurface(texture, entry); surface) { |
| 994 | state.texture_units[current_bindpoint].texture = | 902 | state.texture_units[current_bindpoint].texture = |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 4de565321..faeeb58ef 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include "video_core/renderer_opengl/gl_primitive_assembler.h" | 28 | #include "video_core/renderer_opengl/gl_primitive_assembler.h" |
| 29 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" | 29 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" |
| 30 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 30 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 31 | #include "video_core/renderer_opengl/gl_sampler_cache.h" | ||
| 31 | #include "video_core/renderer_opengl/gl_shader_cache.h" | 32 | #include "video_core/renderer_opengl/gl_shader_cache.h" |
| 32 | #include "video_core/renderer_opengl/gl_shader_gen.h" | 33 | #include "video_core/renderer_opengl/gl_shader_gen.h" |
| 33 | #include "video_core/renderer_opengl/gl_shader_manager.h" | 34 | #include "video_core/renderer_opengl/gl_shader_manager.h" |
| @@ -80,34 +81,6 @@ public: | |||
| 80 | "The maximum size of a global memory must be a multiple of the size of float"); | 81 | "The maximum size of a global memory must be a multiple of the size of float"); |
| 81 | 82 | ||
| 82 | private: | 83 | private: |
| 83 | class SamplerInfo { | ||
| 84 | public: | ||
| 85 | OGLSampler sampler; | ||
| 86 | |||
| 87 | /// Creates the sampler object, initializing its state so that it's in sync with the | ||
| 88 | /// SamplerInfo struct. | ||
| 89 | void Create(); | ||
| 90 | /// Syncs the sampler object with the config, updating any necessary state. | ||
| 91 | void SyncWithConfig(const Tegra::Texture::TSCEntry& info); | ||
| 92 | |||
| 93 | private: | ||
| 94 | Tegra::Texture::TextureFilter mag_filter = Tegra::Texture::TextureFilter::Nearest; | ||
| 95 | Tegra::Texture::TextureFilter min_filter = Tegra::Texture::TextureFilter::Nearest; | ||
| 96 | Tegra::Texture::TextureMipmapFilter mipmap_filter = | ||
| 97 | Tegra::Texture::TextureMipmapFilter::None; | ||
| 98 | Tegra::Texture::WrapMode wrap_u = Tegra::Texture::WrapMode::ClampToEdge; | ||
| 99 | Tegra::Texture::WrapMode wrap_v = Tegra::Texture::WrapMode::ClampToEdge; | ||
| 100 | Tegra::Texture::WrapMode wrap_p = Tegra::Texture::WrapMode::ClampToEdge; | ||
| 101 | bool use_depth_compare = false; | ||
| 102 | Tegra::Texture::DepthCompareFunc depth_compare_func = | ||
| 103 | Tegra::Texture::DepthCompareFunc::Always; | ||
| 104 | GLvec4 border_color = {}; | ||
| 105 | float min_lod = 0.0f; | ||
| 106 | float max_lod = 16.0f; | ||
| 107 | float lod_bias = 0.0f; | ||
| 108 | float max_anisotropic = 1.0f; | ||
| 109 | }; | ||
| 110 | |||
| 111 | struct FramebufferConfigState { | 84 | struct FramebufferConfigState { |
| 112 | bool using_color_fb{}; | 85 | bool using_color_fb{}; |
| 113 | bool using_depth_fb{}; | 86 | bool using_depth_fb{}; |
| @@ -212,6 +185,7 @@ private: | |||
| 212 | RasterizerCacheOpenGL res_cache; | 185 | RasterizerCacheOpenGL res_cache; |
| 213 | ShaderCacheOpenGL shader_cache; | 186 | ShaderCacheOpenGL shader_cache; |
| 214 | GlobalRegionCacheOpenGL global_cache; | 187 | GlobalRegionCacheOpenGL global_cache; |
| 188 | SamplerCacheOpenGL sampler_cache; | ||
| 215 | 189 | ||
| 216 | Core::System& system; | 190 | Core::System& system; |
| 217 | 191 | ||
| @@ -227,8 +201,6 @@ private: | |||
| 227 | FramebufferConfigState current_framebuffer_config_state; | 201 | FramebufferConfigState current_framebuffer_config_state; |
| 228 | std::pair<bool, bool> current_depth_stencil_usage{}; | 202 | std::pair<bool, bool> current_depth_stencil_usage{}; |
| 229 | 203 | ||
| 230 | std::array<SamplerInfo, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_samplers; | ||
| 231 | |||
| 232 | static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; | 204 | static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; |
| 233 | OGLBufferCache buffer_cache; | 205 | OGLBufferCache buffer_cache; |
| 234 | PrimitiveAssembler primitive_assembler{buffer_cache}; | 206 | PrimitiveAssembler primitive_assembler{buffer_cache}; |
diff --git a/src/video_core/renderer_opengl/gl_sampler_cache.cpp b/src/video_core/renderer_opengl/gl_sampler_cache.cpp new file mode 100644 index 000000000..3ded5ecea --- /dev/null +++ b/src/video_core/renderer_opengl/gl_sampler_cache.cpp | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/logging/log.h" | ||
| 6 | #include "video_core/renderer_opengl/gl_resource_manager.h" | ||
| 7 | #include "video_core/renderer_opengl/gl_sampler_cache.h" | ||
| 8 | #include "video_core/renderer_opengl/maxwell_to_gl.h" | ||
| 9 | |||
| 10 | namespace OpenGL { | ||
| 11 | |||
| 12 | SamplerCacheOpenGL::SamplerCacheOpenGL() = default; | ||
| 13 | |||
| 14 | SamplerCacheOpenGL::~SamplerCacheOpenGL() = default; | ||
| 15 | |||
| 16 | OGLSampler SamplerCacheOpenGL::CreateSampler(const Tegra::Texture::TSCEntry& tsc) const { | ||
| 17 | OGLSampler sampler; | ||
| 18 | sampler.Create(); | ||
| 19 | |||
| 20 | const GLuint sampler_id{sampler.handle}; | ||
| 21 | glSamplerParameteri( | ||
| 22 | sampler_id, GL_TEXTURE_MAG_FILTER, | ||
| 23 | MaxwellToGL::TextureFilterMode(tsc.mag_filter, Tegra::Texture::TextureMipmapFilter::None)); | ||
| 24 | glSamplerParameteri(sampler_id, GL_TEXTURE_MIN_FILTER, | ||
| 25 | MaxwellToGL::TextureFilterMode(tsc.min_filter, tsc.mipmap_filter)); | ||
| 26 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(tsc.wrap_u)); | ||
| 27 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(tsc.wrap_v)); | ||
| 28 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(tsc.wrap_p)); | ||
| 29 | glSamplerParameteri(sampler_id, GL_TEXTURE_COMPARE_MODE, | ||
| 30 | tsc.depth_compare_enabled == 1 ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE); | ||
| 31 | glSamplerParameteri(sampler_id, GL_TEXTURE_COMPARE_FUNC, | ||
| 32 | MaxwellToGL::DepthCompareFunc(tsc.depth_compare_func)); | ||
| 33 | glSamplerParameterfv(sampler_id, GL_TEXTURE_BORDER_COLOR, tsc.GetBorderColor().data()); | ||
| 34 | glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, tsc.GetMinLod()); | ||
| 35 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, tsc.GetMaxLod()); | ||
| 36 | glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, tsc.GetLodBias()); | ||
| 37 | if (GLAD_GL_ARB_texture_filter_anisotropic) { | ||
| 38 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY, tsc.GetMaxAnisotropy()); | ||
| 39 | } else if (GLAD_GL_EXT_texture_filter_anisotropic) { | ||
| 40 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, tsc.GetMaxAnisotropy()); | ||
| 41 | } else if (tsc.GetMaxAnisotropy() != 1) { | ||
| 42 | LOG_WARNING(Render_OpenGL, "Anisotropy not supported by host GPU driver"); | ||
| 43 | } | ||
| 44 | |||
| 45 | return sampler; | ||
| 46 | } | ||
| 47 | |||
| 48 | GLuint SamplerCacheOpenGL::ToSamplerType(const OGLSampler& sampler) const { | ||
| 49 | return sampler.handle; | ||
| 50 | } | ||
| 51 | |||
| 52 | } // namespace OpenGL | ||
diff --git a/src/video_core/renderer_opengl/gl_sampler_cache.h b/src/video_core/renderer_opengl/gl_sampler_cache.h new file mode 100644 index 000000000..defbc2d81 --- /dev/null +++ b/src/video_core/renderer_opengl/gl_sampler_cache.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <glad/glad.h> | ||
| 8 | |||
| 9 | #include "video_core/renderer_opengl/gl_resource_manager.h" | ||
| 10 | #include "video_core/sampler_cache.h" | ||
| 11 | |||
| 12 | namespace OpenGL { | ||
| 13 | |||
| 14 | class SamplerCacheOpenGL final : public VideoCommon::SamplerCache<GLuint, OGLSampler> { | ||
| 15 | public: | ||
| 16 | explicit SamplerCacheOpenGL(); | ||
| 17 | ~SamplerCacheOpenGL(); | ||
| 18 | |||
| 19 | protected: | ||
| 20 | OGLSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const; | ||
| 21 | |||
| 22 | GLuint ToSamplerType(const OGLSampler& sampler) const; | ||
| 23 | }; | ||
| 24 | |||
| 25 | } // namespace OpenGL | ||