summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ameerj2021-09-10 01:10:59 -0400
committerGravatar Fernando Sahmkow2021-11-16 22:11:29 +0100
commitfcf2b2c78a3c45ddcda6594b2fd3df733ceb951c (patch)
tree172fc0c6c7c7bc78f00d986aa42a552692751f46 /src
parentRenderers: Unify post processing filter shaders (diff)
downloadyuzu-fcf2b2c78a3c45ddcda6594b2fd3df733ceb951c.tar.gz
yuzu-fcf2b2c78a3c45ddcda6594b2fd3df733ceb951c.tar.xz
yuzu-fcf2b2c78a3c45ddcda6594b2fd3df733ceb951c.zip
gl_texture_cache: Simplify scaling
We don't need to reconstruct new textures every time we ScaleUp/ScaleDown. We can scale up once, and revert to the original texture whenever scaling down. Fixes memory leaks due to glDeleteTextures being deferred for later handling on some drivers
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp67
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h3
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
884bool Image::Scale(bool scale_src, bool scale_dst) { 886bool 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
973bool Image::ScaleDown() { 975bool 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
981ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, 988ImageView::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;