diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 60 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 2 |
2 files changed, 36 insertions, 26 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 53b5c0947..34f74e37d 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -869,17 +869,17 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b | |||
| 869 | } | 869 | } |
| 870 | } | 870 | } |
| 871 | 871 | ||
| 872 | void Image::Scale(u32 up, u32 down) { | 872 | bool Image::Scale(bool scale_src, bool scale_dst) { |
| 873 | if (!runtime->is_rescaling_on) { | 873 | if (!runtime->is_rescaling_on) { |
| 874 | return; | 874 | return false; |
| 875 | } | 875 | } |
| 876 | if (gl_format == 0 && gl_type == 0) { | 876 | if (gl_format == 0 && gl_type == 0) { |
| 877 | // compressed textures | 877 | // compressed textures |
| 878 | return; | 878 | return false; |
| 879 | } | 879 | } |
| 880 | if (info.type == ImageType::Linear) { | 880 | if (info.type == ImageType::Linear) { |
| 881 | UNIMPLEMENTED(); | 881 | UNIMPLEMENTED(); |
| 882 | return; | 882 | return false; |
| 883 | } | 883 | } |
| 884 | GLint prev_read_fbo; | 884 | GLint prev_read_fbo; |
| 885 | glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prev_read_fbo); | 885 | glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prev_read_fbo); |
| @@ -910,43 +910,58 @@ void Image::Scale(u32 up, u32 down) { | |||
| 910 | } | 910 | } |
| 911 | }(); | 911 | }(); |
| 912 | 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; |
| 913 | const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); }; | ||
| 914 | const bool is_2d = info.type == ImageType::e2D; | 913 | const bool is_2d = info.type == ImageType::e2D; |
| 914 | const auto& resolution = runtime->resolution; | ||
| 915 | const u32 up = resolution.up_scale; | ||
| 916 | const u32 down = resolution.down_shift; | ||
| 917 | |||
| 918 | const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); }; | ||
| 915 | const u32 scaled_width = scale_up(info.size.width); | 919 | const u32 scaled_width = scale_up(info.size.width); |
| 916 | const u32 scaled_height = is_2d ? scale_up(info.size.height) : info.size.height; | 920 | const u32 scaled_height = is_2d ? scale_up(info.size.height) : info.size.height; |
| 917 | const u32 original_width = info.size.width; | 921 | const u32 original_width = info.size.width; |
| 918 | const u32 original_height = info.size.height; | 922 | const u32 original_height = info.size.height; |
| 919 | 923 | ||
| 920 | auto scaled_info = info; | 924 | const u32 src_width = scale_src ? scaled_width : original_width; |
| 921 | scaled_info.size.width = scaled_width; | 925 | const u32 src_height = scale_src ? scaled_height : original_height; |
| 922 | scaled_info.size.height = scaled_height; | 926 | const u32 dst_width = scale_dst ? scaled_width : original_width; |
| 923 | auto scaled_texture = MakeImage(scaled_info, gl_internal_format); | 927 | const u32 dst_height = scale_dst ? scaled_height : original_height; |
| 928 | |||
| 929 | auto dst_info = info; | ||
| 930 | dst_info.size.width = dst_width; | ||
| 931 | dst_info.size.height = dst_height; | ||
| 932 | auto dst_texture = MakeImage(dst_info, gl_internal_format); | ||
| 933 | |||
| 924 | const auto& blit_fbo = runtime->rescale_fbo; | 934 | const auto& blit_fbo = runtime->rescale_fbo; |
| 925 | for (s32 level = 0; level < info.resources.levels; ++level) { | 935 | for (s32 level = 0; level < info.resources.levels; ++level) { |
| 926 | const u32 level_width = scaled_width >> level; | 936 | const u32 src_level_width = std::max(1u, src_width >> level); |
| 927 | const u32 level_height = scaled_height >> level; | 937 | const u32 src_level_height = std::max(1u, src_height >> level); |
| 938 | const u32 dst_level_width = std::max(1u, dst_width >> level); | ||
| 939 | const u32 dst_level_height = std::max(1u, dst_height >> level); | ||
| 940 | |||
| 928 | glBindFramebuffer(GL_READ_FRAMEBUFFER, blit_fbo.handle); | 941 | glBindFramebuffer(GL_READ_FRAMEBUFFER, blit_fbo.handle); |
| 929 | glNamedFramebufferTexture(blit_fbo.handle, attachment, texture.handle, level); | 942 | glNamedFramebufferTexture(blit_fbo.handle, attachment, texture.handle, level); |
| 930 | glBlitNamedFramebuffer(blit_fbo.handle, blit_fbo.handle, 0, 0, original_width, | 943 | glBlitNamedFramebuffer(blit_fbo.handle, blit_fbo.handle, 0, 0, src_level_width, |
| 931 | original_height, 0, 0, level_width, level_height, mask, filter); | 944 | src_level_height, 0, 0, dst_level_width, dst_level_height, mask, |
| 945 | filter); | ||
| 932 | switch (info.type) { | 946 | switch (info.type) { |
| 933 | case ImageType::e1D: | 947 | case ImageType::e1D: |
| 934 | glCopyTextureSubImage2D(scaled_texture.handle, level, 0, 0, 0, 0, level_width, | 948 | glCopyTextureSubImage2D(dst_texture.handle, level, 0, 0, 0, 0, dst_level_width, |
| 935 | level_height); | 949 | dst_level_height); |
| 936 | break; | 950 | break; |
| 937 | case ImageType::e2D: | 951 | case ImageType::e2D: |
| 938 | glCopyTextureSubImage3D(scaled_texture.handle, level, 0, 0, 0, 0, 0, level_width, | 952 | glCopyTextureSubImage3D(dst_texture.handle, level, 0, 0, 0, 0, 0, dst_level_width, |
| 939 | level_height); | 953 | dst_level_height); |
| 940 | break; | 954 | break; |
| 941 | case ImageType::e3D: | 955 | case ImageType::e3D: |
| 942 | default: | 956 | default: |
| 943 | UNREACHABLE(); | 957 | UNREACHABLE(); |
| 944 | } | 958 | } |
| 945 | } | 959 | } |
| 946 | texture = std::move(scaled_texture); | 960 | texture = std::move(dst_texture); |
| 947 | 961 | ||
| 948 | // Restore previous framebuffers | 962 | // Restore previous framebuffers |
| 949 | glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo); | 963 | glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo); |
| 964 | return true; | ||
| 950 | } | 965 | } |
| 951 | 966 | ||
| 952 | bool Image::ScaleUp() { | 967 | bool Image::ScaleUp() { |
| @@ -954,9 +969,7 @@ bool Image::ScaleUp() { | |||
| 954 | return false; | 969 | return false; |
| 955 | } | 970 | } |
| 956 | flags |= ImageFlagBits::Rescaled; | 971 | flags |= ImageFlagBits::Rescaled; |
| 957 | const auto& resolution = runtime->resolution; | 972 | return Scale(false, true); |
| 958 | Scale(resolution.up_scale, resolution.down_shift); | ||
| 959 | return true; | ||
| 960 | } | 973 | } |
| 961 | 974 | ||
| 962 | bool Image::ScaleDown() { | 975 | bool Image::ScaleDown() { |
| @@ -964,10 +977,7 @@ bool Image::ScaleDown() { | |||
| 964 | return false; | 977 | return false; |
| 965 | } | 978 | } |
| 966 | flags &= ~ImageFlagBits::Rescaled; | 979 | flags &= ~ImageFlagBits::Rescaled; |
| 967 | UNIMPLEMENTED(); | 980 | return Scale(true, false); |
| 968 | // const auto& resolution = runtime->resolution; | ||
| 969 | // Scale(); | ||
| 970 | return true; | ||
| 971 | } | 981 | } |
| 972 | 982 | ||
| 973 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, | 983 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 03de50ad5..f2e48b4c7 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -203,7 +203,7 @@ private: | |||
| 203 | 203 | ||
| 204 | void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset); | 204 | void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset); |
| 205 | 205 | ||
| 206 | void Scale(u32 up, u32 down); | 206 | bool Scale(bool scale_src, bool scale_dst); |
| 207 | 207 | ||
| 208 | OGLTexture texture; | 208 | OGLTexture texture; |
| 209 | OGLTextureView store_view; | 209 | OGLTextureView store_view; |