diff options
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 97 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 5 | ||||
| -rw-r--r-- | src/video_core/textures/texture.h | 34 |
3 files changed, 72 insertions, 64 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 301562ff6..824863561 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -804,104 +804,87 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, | |||
| 804 | 804 | ||
| 805 | void RasterizerOpenGL::SamplerInfo::Create() { | 805 | void RasterizerOpenGL::SamplerInfo::Create() { |
| 806 | sampler.Create(); | 806 | sampler.Create(); |
| 807 | mag_filter = min_filter = Tegra::Texture::TextureFilter::Linear; | 807 | mag_filter = Tegra::Texture::TextureFilter::Linear; |
| 808 | wrap_u = wrap_v = wrap_p = Tegra::Texture::WrapMode::Wrap; | 808 | min_filter = Tegra::Texture::TextureFilter::Linear; |
| 809 | uses_depth_compare = false; | 809 | wrap_u = Tegra::Texture::WrapMode::Wrap; |
| 810 | wrap_v = Tegra::Texture::WrapMode::Wrap; | ||
| 811 | wrap_p = Tegra::Texture::WrapMode::Wrap; | ||
| 812 | use_depth_compare = false; | ||
| 810 | depth_compare_func = Tegra::Texture::DepthCompareFunc::Never; | 813 | depth_compare_func = Tegra::Texture::DepthCompareFunc::Never; |
| 811 | 814 | ||
| 812 | // default is GL_LINEAR_MIPMAP_LINEAR | 815 | // OpenGL's default is GL_LINEAR_MIPMAP_LINEAR |
| 813 | glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 816 | glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 814 | // Other attributes have correct defaults | ||
| 815 | glSamplerParameteri(sampler.handle, GL_TEXTURE_COMPARE_FUNC, GL_NEVER); | 817 | glSamplerParameteri(sampler.handle, GL_TEXTURE_COMPARE_FUNC, GL_NEVER); |
| 818 | |||
| 819 | // Other attributes have correct defaults | ||
| 816 | } | 820 | } |
| 817 | 821 | ||
| 818 | void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) { | 822 | void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) { |
| 819 | const GLuint s = sampler.handle; | 823 | const GLuint sampler_id = sampler.handle; |
| 820 | if (mag_filter != config.mag_filter) { | 824 | if (mag_filter != config.mag_filter) { |
| 821 | mag_filter = config.mag_filter; | 825 | mag_filter = config.mag_filter; |
| 822 | glSamplerParameteri( | 826 | glSamplerParameteri( |
| 823 | s, GL_TEXTURE_MAG_FILTER, | 827 | sampler_id, GL_TEXTURE_MAG_FILTER, |
| 824 | MaxwellToGL::TextureFilterMode(mag_filter, Tegra::Texture::TextureMipmapFilter::None)); | 828 | MaxwellToGL::TextureFilterMode(mag_filter, Tegra::Texture::TextureMipmapFilter::None)); |
| 825 | } | 829 | } |
| 826 | if (min_filter != config.min_filter || mip_filter != config.mip_filter) { | 830 | if (min_filter != config.min_filter || mipmap_filter != config.mipmap_filter) { |
| 827 | min_filter = config.min_filter; | 831 | min_filter = config.min_filter; |
| 828 | mip_filter = config.mip_filter; | 832 | mipmap_filter = config.mipmap_filter; |
| 829 | glSamplerParameteri(s, GL_TEXTURE_MIN_FILTER, | 833 | glSamplerParameteri(sampler_id, GL_TEXTURE_MIN_FILTER, |
| 830 | MaxwellToGL::TextureFilterMode(min_filter, mip_filter)); | 834 | MaxwellToGL::TextureFilterMode(min_filter, mipmap_filter)); |
| 831 | } | 835 | } |
| 832 | 836 | ||
| 833 | if (wrap_u != config.wrap_u) { | 837 | if (wrap_u != config.wrap_u) { |
| 834 | wrap_u = config.wrap_u; | 838 | wrap_u = config.wrap_u; |
| 835 | glSamplerParameteri(s, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(wrap_u)); | 839 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(wrap_u)); |
| 836 | } | 840 | } |
| 837 | if (wrap_v != config.wrap_v) { | 841 | if (wrap_v != config.wrap_v) { |
| 838 | wrap_v = config.wrap_v; | 842 | wrap_v = config.wrap_v; |
| 839 | glSamplerParameteri(s, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(wrap_v)); | 843 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(wrap_v)); |
| 840 | } | 844 | } |
| 841 | if (wrap_p != config.wrap_p) { | 845 | if (wrap_p != config.wrap_p) { |
| 842 | wrap_p = config.wrap_p; | 846 | wrap_p = config.wrap_p; |
| 843 | glSamplerParameteri(s, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(wrap_p)); | 847 | glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(wrap_p)); |
| 844 | } | 848 | } |
| 845 | 849 | ||
| 846 | if (uses_depth_compare != (config.depth_compare_enabled == 1)) { | 850 | if (const bool enabled = config.depth_compare_enabled == 1; use_depth_compare != enabled) { |
| 847 | uses_depth_compare = (config.depth_compare_enabled == 1); | 851 | use_depth_compare = enabled; |
| 848 | if (uses_depth_compare) { | 852 | glSamplerParameteri(sampler_id, GL_TEXTURE_COMPARE_MODE, |
| 849 | glSamplerParameteri(s, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); | 853 | use_depth_compare ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE); |
| 850 | } else { | ||
| 851 | glSamplerParameteri(s, GL_TEXTURE_COMPARE_MODE, GL_NONE); | ||
| 852 | } | ||
| 853 | } | 854 | } |
| 854 | 855 | ||
| 855 | if (depth_compare_func != config.depth_compare_func) { | 856 | if (depth_compare_func != config.depth_compare_func) { |
| 856 | depth_compare_func = config.depth_compare_func; | 857 | depth_compare_func = config.depth_compare_func; |
| 857 | glSamplerParameteri(s, GL_TEXTURE_COMPARE_FUNC, | 858 | glSamplerParameteri(sampler_id, GL_TEXTURE_COMPARE_FUNC, |
| 858 | MaxwellToGL::DepthCompareFunc(depth_compare_func)); | 859 | MaxwellToGL::DepthCompareFunc(depth_compare_func)); |
| 859 | } | 860 | } |
| 860 | 861 | ||
| 861 | GLvec4 new_border_color; | 862 | if (const auto new_border_color = config.GetBorderColor(); border_color != new_border_color) { |
| 862 | if (config.srgb_conversion) { | ||
| 863 | new_border_color[0] = config.srgb_border_color_r / 255.0f; | ||
| 864 | new_border_color[1] = config.srgb_border_color_g / 255.0f; | ||
| 865 | new_border_color[2] = config.srgb_border_color_g / 255.0f; | ||
| 866 | } else { | ||
| 867 | new_border_color[0] = config.border_color_r; | ||
| 868 | new_border_color[1] = config.border_color_g; | ||
| 869 | new_border_color[2] = config.border_color_b; | ||
| 870 | } | ||
| 871 | new_border_color[3] = config.border_color_a; | ||
| 872 | |||
| 873 | if (border_color != new_border_color) { | ||
| 874 | border_color = new_border_color; | 863 | border_color = new_border_color; |
| 875 | glSamplerParameterfv(s, GL_TEXTURE_BORDER_COLOR, border_color.data()); | 864 | glSamplerParameterfv(sampler_id, GL_TEXTURE_BORDER_COLOR, border_color.data()); |
| 876 | } | 865 | } |
| 877 | 866 | ||
| 878 | const float anisotropic_max = static_cast<float>(1 << config.max_anisotropy.Value()); | 867 | if (const float anisotropic = config.GetMaxAnisotropy(); max_anisotropic != anisotropic) { |
| 879 | if (anisotropic_max != max_anisotropic) { | 868 | max_anisotropic = anisotropic; |
| 880 | max_anisotropic = anisotropic_max; | ||
| 881 | if (GLAD_GL_ARB_texture_filter_anisotropic) { | 869 | if (GLAD_GL_ARB_texture_filter_anisotropic) { |
| 882 | glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropic); | 870 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropic); |
| 883 | } else if (GLAD_GL_EXT_texture_filter_anisotropic) { | 871 | } else if (GLAD_GL_EXT_texture_filter_anisotropic) { |
| 884 | glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropic); | 872 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropic); |
| 885 | } | 873 | } |
| 886 | } | 874 | } |
| 887 | const float lod_min = static_cast<float>(config.min_lod_clamp.Value()) / 256.0f; | ||
| 888 | if (lod_min != min_lod) { | ||
| 889 | min_lod = lod_min; | ||
| 890 | glSamplerParameterf(s, GL_TEXTURE_MIN_LOD, min_lod); | ||
| 891 | } | ||
| 892 | 875 | ||
| 893 | const float lod_max = static_cast<float>(config.max_lod_clamp.Value()) / 256.0f; | 876 | if (const float min = config.GetMinLod(); min_lod != min) { |
| 894 | if (lod_max != max_lod) { | 877 | min_lod = min; |
| 895 | max_lod = lod_max; | 878 | glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, min_lod); |
| 896 | glSamplerParameterf(s, GL_TEXTURE_MAX_LOD, max_lod); | ||
| 897 | } | 879 | } |
| 898 | const u32 bias = config.mip_lod_bias.Value(); | 880 | if (const float max = config.GetMaxLod(); max_lod != max) { |
| 899 | // Sign extend the 13-bit value. | 881 | max_lod = max; |
| 900 | constexpr u32 mask = 1U << (13 - 1); | 882 | glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, max_lod); |
| 901 | const float bias_lod = static_cast<s32>((bias ^ mask) - mask) / 256.f; | 883 | } |
| 902 | if (lod_bias != bias_lod) { | 884 | |
| 903 | lod_bias = bias_lod; | 885 | if (const float bias = config.GetLodBias(); lod_bias != bias) { |
| 904 | glSamplerParameterf(s, GL_TEXTURE_LOD_BIAS, lod_bias); | 886 | lod_bias = bias; |
| 887 | glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, lod_bias); | ||
| 905 | } | 888 | } |
| 906 | } | 889 | } |
| 907 | 890 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 2f0524f85..7e63f8008 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -94,11 +94,12 @@ private: | |||
| 94 | private: | 94 | private: |
| 95 | Tegra::Texture::TextureFilter mag_filter = Tegra::Texture::TextureFilter::Nearest; | 95 | Tegra::Texture::TextureFilter mag_filter = Tegra::Texture::TextureFilter::Nearest; |
| 96 | Tegra::Texture::TextureFilter min_filter = Tegra::Texture::TextureFilter::Nearest; | 96 | Tegra::Texture::TextureFilter min_filter = Tegra::Texture::TextureFilter::Nearest; |
| 97 | Tegra::Texture::TextureMipmapFilter mip_filter = Tegra::Texture::TextureMipmapFilter::None; | 97 | Tegra::Texture::TextureMipmapFilter mipmap_filter = |
| 98 | Tegra::Texture::TextureMipmapFilter::None; | ||
| 98 | Tegra::Texture::WrapMode wrap_u = Tegra::Texture::WrapMode::ClampToEdge; | 99 | Tegra::Texture::WrapMode wrap_u = Tegra::Texture::WrapMode::ClampToEdge; |
| 99 | Tegra::Texture::WrapMode wrap_v = Tegra::Texture::WrapMode::ClampToEdge; | 100 | Tegra::Texture::WrapMode wrap_v = Tegra::Texture::WrapMode::ClampToEdge; |
| 100 | Tegra::Texture::WrapMode wrap_p = Tegra::Texture::WrapMode::ClampToEdge; | 101 | Tegra::Texture::WrapMode wrap_p = Tegra::Texture::WrapMode::ClampToEdge; |
| 101 | bool uses_depth_compare = false; | 102 | bool use_depth_compare = false; |
| 102 | Tegra::Texture::DepthCompareFunc depth_compare_func = | 103 | Tegra::Texture::DepthCompareFunc depth_compare_func = |
| 103 | Tegra::Texture::DepthCompareFunc::Always; | 104 | Tegra::Texture::DepthCompareFunc::Always; |
| 104 | GLvec4 border_color = {}; | 105 | GLvec4 border_color = {}; |
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index 0fc5530f2..8c278c0e2 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 8 | #include "common/bit_field.h" | 9 | #include "common/bit_field.h" |
| 9 | #include "common/common_funcs.h" | 10 | #include "common/common_funcs.h" |
| @@ -293,7 +294,7 @@ struct TSCEntry { | |||
| 293 | union { | 294 | union { |
| 294 | BitField<0, 2, TextureFilter> mag_filter; | 295 | BitField<0, 2, TextureFilter> mag_filter; |
| 295 | BitField<4, 2, TextureFilter> min_filter; | 296 | BitField<4, 2, TextureFilter> min_filter; |
| 296 | BitField<6, 2, TextureMipmapFilter> mip_filter; | 297 | BitField<6, 2, TextureMipmapFilter> mipmap_filter; |
| 297 | BitField<9, 1, u32> cubemap_interface_filtering; | 298 | BitField<9, 1, u32> cubemap_interface_filtering; |
| 298 | BitField<12, 13, u32> mip_lod_bias; | 299 | BitField<12, 13, u32> mip_lod_bias; |
| 299 | }; | 300 | }; |
| @@ -306,10 +307,33 @@ struct TSCEntry { | |||
| 306 | BitField<12, 8, u32> srgb_border_color_g; | 307 | BitField<12, 8, u32> srgb_border_color_g; |
| 307 | BitField<20, 8, u32> srgb_border_color_b; | 308 | BitField<20, 8, u32> srgb_border_color_b; |
| 308 | }; | 309 | }; |
| 309 | float border_color_r; | 310 | std::array<f32, 4> border_color; |
| 310 | float border_color_g; | 311 | |
| 311 | float border_color_b; | 312 | float GetMaxAnisotropy() const { |
| 312 | float border_color_a; | 313 | return static_cast<float>(1U << max_anisotropy); |
| 314 | } | ||
| 315 | |||
| 316 | float GetMinLod() const { | ||
| 317 | return static_cast<float>(min_lod_clamp) / 256.0f; | ||
| 318 | } | ||
| 319 | |||
| 320 | float GetMaxLod() const { | ||
| 321 | return static_cast<float>(max_lod_clamp) / 256.0f; | ||
| 322 | } | ||
| 323 | |||
| 324 | float GetLodBias() const { | ||
| 325 | // Sign extend the 13-bit value. | ||
| 326 | constexpr u32 mask = 1U << (13 - 1); | ||
| 327 | return static_cast<float>((mip_lod_bias ^ mask) - mask) / 256.0f; | ||
| 328 | } | ||
| 329 | |||
| 330 | std::array<float, 4> GetBorderColor() const { | ||
| 331 | if (srgb_conversion) { | ||
| 332 | return {srgb_border_color_r / 255.0f, srgb_border_color_g / 255.0f, | ||
| 333 | srgb_border_color_b / 255.0f, border_color[3]}; | ||
| 334 | } | ||
| 335 | return border_color; | ||
| 336 | } | ||
| 313 | }; | 337 | }; |
| 314 | static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size"); | 338 | static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size"); |
| 315 | 339 | ||