diff options
| author | 2021-07-21 20:50:15 -0400 | |
|---|---|---|
| committer | 2021-11-16 22:11:27 +0100 | |
| commit | 0a6c895af76503e7658f8660cc1af097e5d9c11f (patch) | |
| tree | 277a0b1b7fe77680577907881307f805e2dccfb1 | |
| parent | Texture Cache: Implement Rescaling on Aliases and Blits. (diff) | |
| download | yuzu-0a6c895af76503e7658f8660cc1af097e5d9c11f.tar.gz yuzu-0a6c895af76503e7658f8660cc1af097e5d9c11f.tar.xz yuzu-0a6c895af76503e7658f8660cc1af097e5d9c11f.zip | |
gl_texture_cache: Rescale fixes for multi-layered textures
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 47 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 1 |
2 files changed, 32 insertions, 16 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index ecde5b600..53b5c0947 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -479,6 +479,9 @@ TextureCacheRuntime::~TextureCacheRuntime() = default; | |||
| 479 | void TextureCacheRuntime::Init() { | 479 | void TextureCacheRuntime::Init() { |
| 480 | resolution = Settings::values.resolution_info; | 480 | resolution = Settings::values.resolution_info; |
| 481 | is_rescaling_on = resolution.up_scale != 1 || resolution.down_shift != 0; | 481 | is_rescaling_on = resolution.up_scale != 1 || resolution.down_shift != 0; |
| 482 | if (is_rescaling_on) { | ||
| 483 | rescale_fbo.Create(); | ||
| 484 | } | ||
| 482 | } | 485 | } |
| 483 | 486 | ||
| 484 | void TextureCacheRuntime::Finish() { | 487 | void TextureCacheRuntime::Finish() { |
| @@ -867,8 +870,10 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b | |||
| 867 | } | 870 | } |
| 868 | 871 | ||
| 869 | void Image::Scale(u32 up, u32 down) { | 872 | void Image::Scale(u32 up, u32 down) { |
| 870 | // TODO: Pass scaling factor? | 873 | if (!runtime->is_rescaling_on) { |
| 871 | if (gl_format == 0 || gl_type == 0) { | 874 | return; |
| 875 | } | ||
| 876 | if (gl_format == 0 && gl_type == 0) { | ||
| 872 | // compressed textures | 877 | // compressed textures |
| 873 | return; | 878 | return; |
| 874 | } | 879 | } |
| @@ -876,9 +881,7 @@ void Image::Scale(u32 up, u32 down) { | |||
| 876 | UNIMPLEMENTED(); | 881 | UNIMPLEMENTED(); |
| 877 | return; | 882 | return; |
| 878 | } | 883 | } |
| 879 | GLint prev_draw_fbo; | ||
| 880 | GLint prev_read_fbo; | 884 | GLint prev_read_fbo; |
| 881 | glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &prev_draw_fbo); | ||
| 882 | glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prev_read_fbo); | 885 | glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prev_read_fbo); |
| 883 | const GLenum attachment = [this] { | 886 | const GLenum attachment = [this] { |
| 884 | switch (GetFormatType(info.format)) { | 887 | switch (GetFormatType(info.format)) { |
| @@ -907,15 +910,10 @@ void Image::Scale(u32 up, u32 down) { | |||
| 907 | } | 910 | } |
| 908 | }(); | 911 | }(); |
| 909 | const GLenum filter = (mask & GL_COLOR_BUFFER_BIT) != 0 ? GL_LINEAR : GL_NEAREST; | 912 | const GLenum filter = (mask & GL_COLOR_BUFFER_BIT) != 0 ? GL_LINEAR : GL_NEAREST; |
| 910 | GLuint fbo_handle; | ||
| 911 | glGenFramebuffers(1, &fbo_handle); | ||
| 912 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_handle); | ||
| 913 | glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_handle); | ||
| 914 | glNamedFramebufferTexture(fbo_handle, attachment, texture.handle, 0); | ||
| 915 | |||
| 916 | const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); }; | 913 | const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); }; |
| 914 | const bool is_2d = info.type == ImageType::e2D; | ||
| 917 | const u32 scaled_width = scale_up(info.size.width); | 915 | const u32 scaled_width = scale_up(info.size.width); |
| 918 | const u32 scaled_height = scale_up(info.size.height); | 916 | const u32 scaled_height = is_2d ? scale_up(info.size.height) : info.size.height; |
| 919 | const u32 original_width = info.size.width; | 917 | const u32 original_width = info.size.width; |
| 920 | const u32 original_height = info.size.height; | 918 | const u32 original_height = info.size.height; |
| 921 | 919 | ||
| @@ -923,14 +921,31 @@ void Image::Scale(u32 up, u32 down) { | |||
| 923 | scaled_info.size.width = scaled_width; | 921 | scaled_info.size.width = scaled_width; |
| 924 | scaled_info.size.height = scaled_height; | 922 | scaled_info.size.height = scaled_height; |
| 925 | auto scaled_texture = MakeImage(scaled_info, gl_internal_format); | 923 | auto scaled_texture = MakeImage(scaled_info, gl_internal_format); |
| 926 | 924 | const auto& blit_fbo = runtime->rescale_fbo; | |
| 927 | glBlitNamedFramebuffer(fbo_handle, fbo_handle, 0, 0, original_width, original_height, 0, 0, | 925 | for (s32 level = 0; level < info.resources.levels; ++level) { |
| 928 | scaled_width, scaled_height, mask, filter); | 926 | const u32 level_width = scaled_width >> level; |
| 929 | glCopyTextureSubImage3D(scaled_texture.handle, 0, 0, 0, 0, 0, 0, scaled_width, scaled_height); | 927 | const u32 level_height = scaled_height >> level; |
| 928 | glBindFramebuffer(GL_READ_FRAMEBUFFER, blit_fbo.handle); | ||
| 929 | glNamedFramebufferTexture(blit_fbo.handle, attachment, texture.handle, level); | ||
| 930 | glBlitNamedFramebuffer(blit_fbo.handle, blit_fbo.handle, 0, 0, original_width, | ||
| 931 | original_height, 0, 0, level_width, level_height, mask, filter); | ||
| 932 | switch (info.type) { | ||
| 933 | case ImageType::e1D: | ||
| 934 | glCopyTextureSubImage2D(scaled_texture.handle, level, 0, 0, 0, 0, level_width, | ||
| 935 | level_height); | ||
| 936 | break; | ||
| 937 | case ImageType::e2D: | ||
| 938 | glCopyTextureSubImage3D(scaled_texture.handle, level, 0, 0, 0, 0, 0, level_width, | ||
| 939 | level_height); | ||
| 940 | break; | ||
| 941 | case ImageType::e3D: | ||
| 942 | default: | ||
| 943 | UNREACHABLE(); | ||
| 944 | } | ||
| 945 | } | ||
| 930 | texture = std::move(scaled_texture); | 946 | texture = std::move(scaled_texture); |
| 931 | 947 | ||
| 932 | // Restore previous framebuffers | 948 | // Restore previous framebuffers |
| 933 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prev_draw_fbo); | ||
| 934 | glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo); | 949 | glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo); |
| 935 | } | 950 | } |
| 936 | 951 | ||
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 77ca14132..03de50ad5 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -155,6 +155,7 @@ private: | |||
| 155 | 155 | ||
| 156 | std::array<GLuint, Shader::NUM_TEXTURE_TYPES> null_image_views{}; | 156 | std::array<GLuint, Shader::NUM_TEXTURE_TYPES> null_image_views{}; |
| 157 | 157 | ||
| 158 | OGLFramebuffer rescale_fbo; | ||
| 158 | Settings::ResolutionScalingInfo resolution; | 159 | Settings::ResolutionScalingInfo resolution; |
| 159 | bool is_rescaling_on{}; | 160 | bool is_rescaling_on{}; |
| 160 | }; | 161 | }; |