summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp70
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h2
2 files changed, 69 insertions, 3 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index cdd352aef..9b2a09007 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -698,7 +698,10 @@ void Image::UploadMemory(const ImageBufferMap& map,
698void Image::DownloadMemory(ImageBufferMap& map, 698void Image::DownloadMemory(ImageBufferMap& map,
699 std::span<const VideoCommon::BufferImageCopy> copies) { 699 std::span<const VideoCommon::BufferImageCopy> copies) {
700 glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); // TODO: Move this to its own API 700 glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); // TODO: Move this to its own API
701 701 const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
702 if (is_rescaled) {
703 ScaleDown();
704 }
702 glBindBuffer(GL_PIXEL_PACK_BUFFER, map.buffer); 705 glBindBuffer(GL_PIXEL_PACK_BUFFER, map.buffer);
703 glPixelStorei(GL_PACK_ALIGNMENT, 1); 706 glPixelStorei(GL_PACK_ALIGNMENT, 1);
704 707
@@ -716,6 +719,9 @@ void Image::DownloadMemory(ImageBufferMap& map,
716 } 719 }
717 CopyImageToBuffer(copy, map.offset); 720 CopyImageToBuffer(copy, map.offset);
718 } 721 }
722 if (is_rescaled) {
723 ScaleUp();
724 }
719} 725}
720 726
721GLuint Image::StorageHandle() noexcept { 727GLuint Image::StorageHandle() noexcept {
@@ -849,12 +855,70 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b
849 } 855 }
850} 856}
851 857
858void Image::Scale() {
859 // TODO: Pass scaling factor?
860 if (gl_format == 0 || gl_type == 0) {
861 // compressed textures
862 return;
863 }
864 if (info.type == ImageType::Linear) {
865 UNIMPLEMENTED();
866 return;
867 }
868 GLint prev_draw_fbo;
869 GLint prev_read_fbo;
870 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &prev_draw_fbo);
871 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prev_read_fbo);
872 const GLenum attachment = [this] {
873 switch (GetFormatType(info.format)) {
874 case SurfaceType::ColorTexture:
875 return GL_COLOR_ATTACHMENT0;
876 case SurfaceType::Depth:
877 return GL_DEPTH_ATTACHMENT;
878 case SurfaceType::DepthStencil:
879 return GL_DEPTH_STENCIL_ATTACHMENT;
880 default:
881 UNREACHABLE();
882 return GL_COLOR_ATTACHMENT0;
883 }
884 }();
885 const GLenum mask = [this] {
886 switch (GetFormatType(info.format)) {
887 case SurfaceType::ColorTexture:
888 return GL_COLOR_BUFFER_BIT;
889 case SurfaceType::Depth:
890 return GL_DEPTH_BUFFER_BIT;
891 case SurfaceType::DepthStencil:
892 return GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
893 default:
894 UNREACHABLE();
895 return GL_COLOR_BUFFER_BIT;
896 }
897 }();
898 const GLenum filter = (mask & GL_COLOR_BUFFER_BIT) != 0 ? GL_LINEAR : GL_NEAREST;
899 GLuint fbo_handle;
900 glGenFramebuffers(1, &fbo_handle);
901 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_handle);
902 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_handle);
903 glNamedFramebufferTexture(fbo_handle, attachment, texture.handle, 0);
904
905 const size_t scaled_width = info.size.width;
906 const size_t scaled_height = info.size.height * 2;
907 glBlitNamedFramebuffer(fbo_handle, fbo_handle, 0, 0, info.size.width, info.size.height, 0, 0,
908 scaled_width, scaled_height, mask, filter);
909 // TODO: resize texture?
910 glCopyTextureSubImage3D(texture.handle, 0, 0, 0, 0, 0, 0, scaled_width, scaled_height / 2);
911 // Restore previous framebuffers
912 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prev_draw_fbo);
913 glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo);
914}
915
852bool Image::ScaleUp() { 916bool Image::ScaleUp() {
853 if (True(flags & ImageFlagBits::Rescaled)) { 917 if (True(flags & ImageFlagBits::Rescaled)) {
854 return false; 918 return false;
855 } 919 }
856 flags |= ImageFlagBits::Rescaled; 920 flags |= ImageFlagBits::Rescaled;
857 UNIMPLEMENTED(); 921 Scale();
858 return true; 922 return true;
859} 923}
860 924
@@ -863,7 +927,7 @@ bool Image::ScaleDown() {
863 return false; 927 return false;
864 } 928 }
865 flags &= ~ImageFlagBits::Rescaled; 929 flags &= ~ImageFlagBits::Rescaled;
866 UNIMPLEMENTED(); 930 Scale();
867 return true; 931 return true;
868} 932}
869 933
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 58b36494b..324a0f1cb 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -198,6 +198,8 @@ private:
198 198
199 void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset); 199 void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset);
200 200
201 void Scale();
202
201 OGLTexture texture; 203 OGLTexture texture;
202 OGLTextureView store_view; 204 OGLTextureView store_view;
203 GLenum gl_internal_format = GL_NONE; 205 GLenum gl_internal_format = GL_NONE;