diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 67 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 3 |
2 files changed, 39 insertions, 31 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index edb8503cb..22fffb19b 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -696,6 +696,7 @@ void Image::UploadMemory(const ImageBufferMap& map, | |||
| 696 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); | 696 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); |
| 697 | if (is_rescaled) { | 697 | if (is_rescaled) { |
| 698 | ScaleDown(); | 698 | ScaleDown(); |
| 699 | scale_backup.Release(); | ||
| 699 | } | 700 | } |
| 700 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, map.buffer); | 701 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, map.buffer); |
| 701 | glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, map.offset, unswizzled_size_bytes); | 702 | glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, map.offset, unswizzled_size_bytes); |
| @@ -727,6 +728,7 @@ void Image::DownloadMemory(ImageBufferMap& map, | |||
| 727 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); | 728 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); |
| 728 | if (is_rescaled) { | 729 | if (is_rescaled) { |
| 729 | ScaleDown(); | 730 | ScaleDown(); |
| 731 | scale_backup.Release(); | ||
| 730 | } | 732 | } |
| 731 | glBindBuffer(GL_PIXEL_PACK_BUFFER, map.buffer); | 733 | glBindBuffer(GL_PIXEL_PACK_BUFFER, map.buffer); |
| 732 | glPixelStorei(GL_PACK_ALIGNMENT, 1); | 734 | glPixelStorei(GL_PACK_ALIGNMENT, 1); |
| @@ -881,17 +883,11 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b | |||
| 881 | } | 883 | } |
| 882 | } | 884 | } |
| 883 | 885 | ||
| 884 | bool Image::Scale(bool scale_src, bool scale_dst) { | 886 | bool Image::Scale() { |
| 885 | if (!runtime->is_rescaling_on) { | 887 | if (scale_backup.handle) { |
| 886 | return false; | 888 | // This was a texture which was scaled previously, no need to repeat scaling |
| 887 | } | 889 | std::swap(texture, scale_backup); |
| 888 | if (gl_format == 0 && gl_type == 0) { | 890 | return true; |
| 889 | // compressed textures | ||
| 890 | return false; | ||
| 891 | } | ||
| 892 | if (info.type == ImageType::Linear) { | ||
| 893 | UNIMPLEMENTED(); | ||
| 894 | return false; | ||
| 895 | } | 891 | } |
| 896 | const GLenum attachment = [this] { | 892 | const GLenum attachment = [this] { |
| 897 | switch (GetFormatType(info.format)) { | 893 | switch (GetFormatType(info.format)) { |
| @@ -924,41 +920,36 @@ bool Image::Scale(bool scale_src, bool scale_dst) { | |||
| 924 | const auto& resolution = runtime->resolution; | 920 | const auto& resolution = runtime->resolution; |
| 925 | const u32 up = resolution.up_scale; | 921 | const u32 up = resolution.up_scale; |
| 926 | const u32 down = resolution.down_shift; | 922 | const u32 down = resolution.down_shift; |
| 923 | const auto scale = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); }; | ||
| 927 | 924 | ||
| 928 | const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); }; | 925 | const u32 scaled_width = scale(info.size.width); |
| 929 | const u32 scaled_width = scale_up(info.size.width); | 926 | const u32 scaled_height = is_2d ? scale(info.size.height) : info.size.height; |
| 930 | const u32 scaled_height = is_2d ? scale_up(info.size.height) : info.size.height; | ||
| 931 | const u32 original_width = info.size.width; | 927 | const u32 original_width = info.size.width; |
| 932 | const u32 original_height = info.size.height; | 928 | const u32 original_height = info.size.height; |
| 933 | 929 | ||
| 934 | const u32 src_width = scale_src ? scaled_width : original_width; | ||
| 935 | const u32 src_height = scale_src ? scaled_height : original_height; | ||
| 936 | const u32 dst_width = scale_dst ? scaled_width : original_width; | ||
| 937 | const u32 dst_height = scale_dst ? scaled_height : original_height; | ||
| 938 | |||
| 939 | auto dst_info = info; | 930 | auto dst_info = info; |
| 940 | dst_info.size.width = dst_width; | 931 | dst_info.size.width = scaled_width; |
| 941 | dst_info.size.height = dst_height; | 932 | dst_info.size.height = scaled_height; |
| 942 | auto dst_texture = MakeImage(dst_info, gl_internal_format); | 933 | scale_backup = MakeImage(dst_info, gl_internal_format); |
| 943 | 934 | ||
| 944 | const GLuint read_fbo = runtime->rescale_read_fbo.handle; | 935 | const GLuint read_fbo = runtime->rescale_read_fbo.handle; |
| 945 | const GLuint draw_fbo = runtime->rescale_draw_fbo.handle; | 936 | const GLuint draw_fbo = runtime->rescale_draw_fbo.handle; |
| 946 | for (s32 layer = 0; layer < info.resources.layers; ++layer) { | 937 | for (s32 layer = 0; layer < info.resources.layers; ++layer) { |
| 947 | for (s32 level = 0; level < info.resources.levels; ++level) { | 938 | for (s32 level = 0; level < info.resources.levels; ++level) { |
| 948 | const u32 src_level_width = std::max(1u, src_width >> level); | 939 | const u32 src_level_width = std::max(1u, original_width >> level); |
| 949 | const u32 src_level_height = std::max(1u, src_height >> level); | 940 | const u32 src_level_height = std::max(1u, original_height >> level); |
| 950 | const u32 dst_level_width = std::max(1u, dst_width >> level); | 941 | const u32 dst_level_width = std::max(1u, scaled_width >> level); |
| 951 | const u32 dst_level_height = std::max(1u, dst_height >> level); | 942 | const u32 dst_level_height = std::max(1u, scaled_height >> level); |
| 952 | 943 | ||
| 953 | glNamedFramebufferTextureLayer(read_fbo, attachment, texture.handle, level, layer); | 944 | glNamedFramebufferTextureLayer(read_fbo, attachment, texture.handle, level, layer); |
| 954 | glNamedFramebufferTextureLayer(draw_fbo, attachment, dst_texture.handle, level, layer); | 945 | glNamedFramebufferTextureLayer(draw_fbo, attachment, scale_backup.handle, level, layer); |
| 955 | glBlitNamedFramebuffer(read_fbo, draw_fbo, 0, 0, src_level_width, src_level_height, 0, | 946 | glBlitNamedFramebuffer(read_fbo, draw_fbo, 0, 0, src_level_width, src_level_height, 0, |
| 956 | 0, dst_level_width, dst_level_height, mask, filter); | 947 | 0, dst_level_width, dst_level_height, mask, filter); |
| 957 | glNamedFramebufferTextureLayer(read_fbo, attachment, 0, level, layer); | 948 | glNamedFramebufferTextureLayer(read_fbo, attachment, 0, level, layer); |
| 958 | glNamedFramebufferTextureLayer(draw_fbo, attachment, 0, level, layer); | 949 | glNamedFramebufferTextureLayer(draw_fbo, attachment, 0, level, layer); |
| 959 | } | 950 | } |
| 960 | } | 951 | } |
| 961 | texture = std::move(dst_texture); | 952 | std::swap(texture, scale_backup); |
| 962 | return true; | 953 | return true; |
| 963 | } | 954 | } |
| 964 | 955 | ||
| @@ -966,16 +957,32 @@ bool Image::ScaleUp() { | |||
| 966 | if (True(flags & ImageFlagBits::Rescaled)) { | 957 | if (True(flags & ImageFlagBits::Rescaled)) { |
| 967 | return false; | 958 | return false; |
| 968 | } | 959 | } |
| 960 | if (!runtime->is_rescaling_on) { | ||
| 961 | return false; | ||
| 962 | } | ||
| 963 | if (gl_format == 0 && gl_type == 0) { | ||
| 964 | // compressed textures | ||
| 965 | return false; | ||
| 966 | } | ||
| 967 | if (info.type == ImageType::Linear) { | ||
| 968 | UNIMPLEMENTED(); | ||
| 969 | return false; | ||
| 970 | } | ||
| 969 | flags |= ImageFlagBits::Rescaled; | 971 | flags |= ImageFlagBits::Rescaled; |
| 970 | return Scale(false, true); | 972 | return Scale(); |
| 971 | } | 973 | } |
| 972 | 974 | ||
| 973 | bool Image::ScaleDown() { | 975 | bool Image::ScaleDown() { |
| 974 | if (False(flags & ImageFlagBits::Rescaled)) { | 976 | if (False(flags & ImageFlagBits::Rescaled)) { |
| 975 | return false; | 977 | return false; |
| 976 | } | 978 | } |
| 979 | if (!scale_backup.handle) { | ||
| 980 | LOG_ERROR(Render_OpenGL, "Downscaling an upscaled texture that didn't backup original"); | ||
| 981 | return false; | ||
| 982 | } | ||
| 977 | flags &= ~ImageFlagBits::Rescaled; | 983 | flags &= ~ImageFlagBits::Rescaled; |
| 978 | return Scale(true, false); | 984 | std::swap(texture, scale_backup); |
| 985 | return true; | ||
| 979 | } | 986 | } |
| 980 | 987 | ||
| 981 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, | 988 | 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 28c91b368..f4dcc6f9b 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -203,9 +203,10 @@ 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 | bool Scale(bool scale_src, bool scale_dst); | 206 | bool Scale(); |
| 207 | 207 | ||
| 208 | OGLTexture texture; | 208 | OGLTexture texture; |
| 209 | OGLTexture scale_backup; | ||
| 209 | OGLTextureView store_view; | 210 | OGLTextureView store_view; |
| 210 | GLenum gl_internal_format = GL_NONE; | 211 | GLenum gl_internal_format = GL_NONE; |
| 211 | GLenum gl_format = GL_NONE; | 212 | GLenum gl_format = GL_NONE; |