diff options
| author | 2019-04-17 21:45:56 -0400 | |
|---|---|---|
| committer | 2019-04-17 21:45:56 -0400 | |
| commit | 4294062516c91c8fdabbcb5b5bcde641c03c9218 (patch) | |
| tree | 8420493647f54dbab66b3b654115e8c509f536d6 /src/video_core/renderer_opengl | |
| parent | Merge pull request #2348 from FernandoS27/guest-bindless (diff) | |
| parent | gl_sampler_cache: Port sampler cache to OpenGL (diff) | |
| download | yuzu-4294062516c91c8fdabbcb5b5bcde641c03c9218.tar.gz yuzu-4294062516c91c8fdabbcb5b5bcde641c03c9218.tar.xz yuzu-4294062516c91c8fdabbcb5b5bcde641c03c9218.zip | |
Merge pull request #2318 from ReinUsesLisp/sampler-cache
gl_sampler_cache: Port sampler cache to OpenGL
Diffstat (limited to 'src/video_core/renderer_opengl')
| -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 |
4 files changed, 80 insertions, 123 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 86a2e117d..6034dc489 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -101,12 +101,6 @@ struct FramebufferCacheKey { | |||
| 101 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, ScreenInfo& info) | 101 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, ScreenInfo& info) |
| 102 | : res_cache{*this}, shader_cache{*this, system}, global_cache{*this}, system{system}, | 102 | : res_cache{*this}, shader_cache{*this, system}, global_cache{*this}, system{system}, |
| 103 | screen_info{info}, buffer_cache(*this, STREAM_BUFFER_SIZE) { | 103 | screen_info{info}, buffer_cache(*this, STREAM_BUFFER_SIZE) { |
| 104 | // Create sampler objects | ||
| 105 | for (std::size_t i = 0; i < texture_samplers.size(); ++i) { | ||
| 106 | texture_samplers[i].Create(); | ||
| 107 | state.texture_units[i].sampler = texture_samplers[i].sampler.handle; | ||
| 108 | } | ||
| 109 | |||
| 110 | OpenGLState::ApplyDefaultState(); | 104 | OpenGLState::ApplyDefaultState(); |
| 111 | 105 | ||
| 112 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); | 106 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); |
| @@ -813,92 +807,6 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, | |||
| 813 | return true; | 807 | return true; |
| 814 | } | 808 | } |
| 815 | 809 | ||
| 816 | void RasterizerOpenGL::SamplerInfo::Create() { | ||
| 817 | sampler.Create(); | ||
| 818 | mag_filter = Tegra::Texture::TextureFilter::Linear; | ||
| 819 | min_filter = Tegra::Texture::TextureFilter::Linear; | ||
| 820 | wrap_u = Tegra::Texture::WrapMode::Wrap; | ||
| 821 | wrap_v = Tegra::Texture::WrapMode::Wrap; | ||
| 822 | wrap_p = Tegra::Texture::WrapMode::Wrap; | ||
| 823 | use_depth_compare = false; | ||
| 824 | depth_compare_func = Tegra::Texture::DepthCompareFunc::Never; | ||
| 825 | |||
| 826 | // OpenGL's default is GL_LINEAR_MIPMAP_LINEAR | ||
| 827 | glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
| 828 | glSamplerParameteri(sampler.handle, GL_TEXTURE_COMPARE_FUNC, GL_NEVER); | ||
| 829 | |||
| 830 | // Other attributes have correct defaults | ||
| 831 | } | ||
| 832 | |||
| 833 | void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) { | ||
| 834 | const GLuint sampler_id = sampler.handle; | ||
| 835 | if (mag_filter != config.mag_filter) { | ||
| 836 | mag_filter = config.mag_filter; | ||
| 837 | glSamplerParameteri( | ||
| 838 | sampler_id, GL_TEXTURE_MAG_FILTER, | ||
| 839 | MaxwellToGL::TextureFilterMode(mag_filter, Tegra::Texture::TextureMipmapFilter::None)); | ||
| 840 | } | ||
| 841 | if (min_filter != config.min_filter || mipmap_filter != config.mipmap_filter) { | ||
| 842 | min_filter = config.min_filter; | ||
| 843 | mipmap_filter = config.mipmap_filter; | ||
| 844 | glSamplerParameteri(sampler_id, GL_TEXTURE_MIN_FILTER, | ||
| 845 | MaxwellToGL::TextureFilterMode(min_filter, mipmap_filter)); | ||
| 846 | } | ||
| 847 | |||
| 848 | if (wrap_u != config.wrap_u) { | ||
| 849 | wrap_u = config.wrap_u; | ||
| 850 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(wrap_u)); | ||
| 851 | } | ||
| 852 | if (wrap_v != config.wrap_v) { | ||
| 853 | wrap_v = config.wrap_v; | ||
| 854 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(wrap_v)); | ||
| 855 | } | ||
| 856 | if (wrap_p != config.wrap_p) { | ||
| 857 | wrap_p = config.wrap_p; | ||
| 858 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(wrap_p)); | ||
| 859 | } | ||
| 860 | |||
| 861 | if (const bool enabled = config.depth_compare_enabled == 1; use_depth_compare != enabled) { | ||
| 862 | use_depth_compare = enabled; | ||
| 863 | glSamplerParameteri(sampler_id, GL_TEXTURE_COMPARE_MODE, | ||
| 864 | use_depth_compare ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE); | ||
| 865 | } | ||
| 866 | |||
| 867 | if (depth_compare_func != config.depth_compare_func) { | ||
| 868 | depth_compare_func = config.depth_compare_func; | ||
| 869 | glSamplerParameteri(sampler_id, GL_TEXTURE_COMPARE_FUNC, | ||
| 870 | MaxwellToGL::DepthCompareFunc(depth_compare_func)); | ||
| 871 | } | ||
| 872 | |||
| 873 | if (const auto new_border_color = config.GetBorderColor(); border_color != new_border_color) { | ||
| 874 | border_color = new_border_color; | ||
| 875 | glSamplerParameterfv(sampler_id, GL_TEXTURE_BORDER_COLOR, border_color.data()); | ||
| 876 | } | ||
| 877 | |||
| 878 | if (const float anisotropic = config.GetMaxAnisotropy(); max_anisotropic != anisotropic) { | ||
| 879 | max_anisotropic = anisotropic; | ||
| 880 | if (GLAD_GL_ARB_texture_filter_anisotropic) { | ||
| 881 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropic); | ||
| 882 | } else if (GLAD_GL_EXT_texture_filter_anisotropic) { | ||
| 883 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropic); | ||
| 884 | } | ||
| 885 | } | ||
| 886 | |||
| 887 | if (const float min = config.GetMinLod(); min_lod != min) { | ||
| 888 | min_lod = min; | ||
| 889 | glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, min_lod); | ||
| 890 | } | ||
| 891 | if (const float max = config.GetMaxLod(); max_lod != max) { | ||
| 892 | max_lod = max; | ||
| 893 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, max_lod); | ||
| 894 | } | ||
| 895 | |||
| 896 | if (const float bias = config.GetLodBias(); lod_bias != bias) { | ||
| 897 | lod_bias = bias; | ||
| 898 | glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, lod_bias); | ||
| 899 | } | ||
| 900 | } | ||
| 901 | |||
| 902 | void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, | 810 | void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, |
| 903 | const Shader& shader, GLuint program_handle, | 811 | const Shader& shader, GLuint program_handle, |
| 904 | BaseBindings base_bindings) { | 812 | BaseBindings base_bindings) { |
| @@ -985,7 +893,7 @@ void RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, const Shader& s | |||
| 985 | } | 893 | } |
| 986 | const u32 current_bindpoint = base_bindings.sampler + bindpoint; | 894 | const u32 current_bindpoint = base_bindings.sampler + bindpoint; |
| 987 | 895 | ||
| 988 | texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); | 896 | state.texture_units[current_bindpoint].sampler = sampler_cache.GetSampler(texture.tsc); |
| 989 | 897 | ||
| 990 | if (Surface surface = res_cache.GetTextureSurface(texture, entry); surface) { | 898 | if (Surface surface = res_cache.GetTextureSurface(texture, entry); surface) { |
| 991 | state.texture_units[current_bindpoint].texture = | 899 | 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 d4c2cf80e..a0e056142 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include "video_core/renderer_opengl/gl_primitive_assembler.h" | 25 | #include "video_core/renderer_opengl/gl_primitive_assembler.h" |
| 26 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" | 26 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" |
| 27 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 27 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 28 | #include "video_core/renderer_opengl/gl_sampler_cache.h" | ||
| 28 | #include "video_core/renderer_opengl/gl_shader_cache.h" | 29 | #include "video_core/renderer_opengl/gl_shader_cache.h" |
| 29 | #include "video_core/renderer_opengl/gl_shader_manager.h" | 30 | #include "video_core/renderer_opengl/gl_shader_manager.h" |
| 30 | #include "video_core/renderer_opengl/gl_state.h" | 31 | #include "video_core/renderer_opengl/gl_state.h" |
| @@ -72,34 +73,6 @@ public: | |||
| 72 | "The maximum size of a constbuffer must be a multiple of the size of GLvec4"); | 73 | "The maximum size of a constbuffer must be a multiple of the size of GLvec4"); |
| 73 | 74 | ||
| 74 | private: | 75 | private: |
| 75 | class SamplerInfo { | ||
| 76 | public: | ||
| 77 | OGLSampler sampler; | ||
| 78 | |||
| 79 | /// Creates the sampler object, initializing its state so that it's in sync with the | ||
| 80 | /// SamplerInfo struct. | ||
| 81 | void Create(); | ||
| 82 | /// Syncs the sampler object with the config, updating any necessary state. | ||
| 83 | void SyncWithConfig(const Tegra::Texture::TSCEntry& info); | ||
| 84 | |||
| 85 | private: | ||
| 86 | Tegra::Texture::TextureFilter mag_filter = Tegra::Texture::TextureFilter::Nearest; | ||
| 87 | Tegra::Texture::TextureFilter min_filter = Tegra::Texture::TextureFilter::Nearest; | ||
| 88 | Tegra::Texture::TextureMipmapFilter mipmap_filter = | ||
| 89 | Tegra::Texture::TextureMipmapFilter::None; | ||
| 90 | Tegra::Texture::WrapMode wrap_u = Tegra::Texture::WrapMode::ClampToEdge; | ||
| 91 | Tegra::Texture::WrapMode wrap_v = Tegra::Texture::WrapMode::ClampToEdge; | ||
| 92 | Tegra::Texture::WrapMode wrap_p = Tegra::Texture::WrapMode::ClampToEdge; | ||
| 93 | bool use_depth_compare = false; | ||
| 94 | Tegra::Texture::DepthCompareFunc depth_compare_func = | ||
| 95 | Tegra::Texture::DepthCompareFunc::Always; | ||
| 96 | GLvec4 border_color = {}; | ||
| 97 | float min_lod = 0.0f; | ||
| 98 | float max_lod = 16.0f; | ||
| 99 | float lod_bias = 0.0f; | ||
| 100 | float max_anisotropic = 1.0f; | ||
| 101 | }; | ||
| 102 | |||
| 103 | struct FramebufferConfigState { | 76 | struct FramebufferConfigState { |
| 104 | bool using_color_fb{}; | 77 | bool using_color_fb{}; |
| 105 | bool using_depth_fb{}; | 78 | bool using_depth_fb{}; |
| @@ -204,6 +177,7 @@ private: | |||
| 204 | RasterizerCacheOpenGL res_cache; | 177 | RasterizerCacheOpenGL res_cache; |
| 205 | ShaderCacheOpenGL shader_cache; | 178 | ShaderCacheOpenGL shader_cache; |
| 206 | GlobalRegionCacheOpenGL global_cache; | 179 | GlobalRegionCacheOpenGL global_cache; |
| 180 | SamplerCacheOpenGL sampler_cache; | ||
| 207 | 181 | ||
| 208 | Core::System& system; | 182 | Core::System& system; |
| 209 | 183 | ||
| @@ -219,8 +193,6 @@ private: | |||
| 219 | FramebufferConfigState current_framebuffer_config_state; | 193 | FramebufferConfigState current_framebuffer_config_state; |
| 220 | std::pair<bool, bool> current_depth_stencil_usage{}; | 194 | std::pair<bool, bool> current_depth_stencil_usage{}; |
| 221 | 195 | ||
| 222 | std::array<SamplerInfo, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_samplers; | ||
| 223 | |||
| 224 | static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; | 196 | static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; |
| 225 | OGLBufferCache buffer_cache; | 197 | OGLBufferCache buffer_cache; |
| 226 | PrimitiveAssembler primitive_assembler{buffer_cache}; | 198 | 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 | ||