فهرست منبع

gl_texture_cache: Rescale fixes for multi-layered textures

ameerj 5 سال پیش
والد
کامیت
0a6c895af7
2فایلهای تغییر یافته به همراه32 افزوده شده و 16 حذف شده
  1. 31 16
      src/video_core/renderer_opengl/gl_texture_cache.cpp
  2. 1 0
      src/video_core/renderer_opengl/gl_texture_cache.h

+ 31 - 16
src/video_core/renderer_opengl/gl_texture_cache.cpp

@@ -479,6 +479,9 @@ TextureCacheRuntime::~TextureCacheRuntime() = default;
 void TextureCacheRuntime::Init() {
 void TextureCacheRuntime::Init() {
     resolution = Settings::values.resolution_info;
     resolution = Settings::values.resolution_info;
     is_rescaling_on = resolution.up_scale != 1 || resolution.down_shift != 0;
     is_rescaling_on = resolution.up_scale != 1 || resolution.down_shift != 0;
+    if (is_rescaling_on) {
+        rescale_fbo.Create();
+    }
 }
 }
 
 
 void TextureCacheRuntime::Finish() {
 void TextureCacheRuntime::Finish() {
@@ -867,8 +870,10 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b
 }
 }
 
 
 void Image::Scale(u32 up, u32 down) {
 void Image::Scale(u32 up, u32 down) {
-    // TODO: Pass scaling factor?
-    if (gl_format == 0 || gl_type == 0) {
+    if (!runtime->is_rescaling_on) {
+        return;
+    }
+    if (gl_format == 0 && gl_type == 0) {
         // compressed textures
         // compressed textures
         return;
         return;
     }
     }
@@ -876,9 +881,7 @@ void Image::Scale(u32 up, u32 down) {
         UNIMPLEMENTED();
         UNIMPLEMENTED();
         return;
         return;
     }
     }
-    GLint prev_draw_fbo;
     GLint prev_read_fbo;
     GLint prev_read_fbo;
-    glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &prev_draw_fbo);
     glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prev_read_fbo);
     glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prev_read_fbo);
     const GLenum attachment = [this] {
     const GLenum attachment = [this] {
         switch (GetFormatType(info.format)) {
         switch (GetFormatType(info.format)) {
@@ -907,15 +910,10 @@ void Image::Scale(u32 up, u32 down) {
         }
         }
     }();
     }();
     const GLenum filter = (mask & GL_COLOR_BUFFER_BIT) != 0 ? GL_LINEAR : GL_NEAREST;
     const GLenum filter = (mask & GL_COLOR_BUFFER_BIT) != 0 ? GL_LINEAR : GL_NEAREST;
-    GLuint fbo_handle;
-    glGenFramebuffers(1, &fbo_handle);
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_handle);
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_handle);
-    glNamedFramebufferTexture(fbo_handle, attachment, texture.handle, 0);
-
     const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); };
     const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); };
+    const bool is_2d = info.type == ImageType::e2D;
     const u32 scaled_width = scale_up(info.size.width);
     const u32 scaled_width = scale_up(info.size.width);
-    const u32 scaled_height = scale_up(info.size.height);
+    const u32 scaled_height = is_2d ? scale_up(info.size.height) : info.size.height;
     const u32 original_width = info.size.width;
     const u32 original_width = info.size.width;
     const u32 original_height = info.size.height;
     const u32 original_height = info.size.height;
 
 
@@ -923,14 +921,31 @@ void Image::Scale(u32 up, u32 down) {
     scaled_info.size.width = scaled_width;
     scaled_info.size.width = scaled_width;
     scaled_info.size.height = scaled_height;
     scaled_info.size.height = scaled_height;
     auto scaled_texture = MakeImage(scaled_info, gl_internal_format);
     auto scaled_texture = MakeImage(scaled_info, gl_internal_format);
-
-    glBlitNamedFramebuffer(fbo_handle, fbo_handle, 0, 0, original_width, original_height, 0, 0,
-                           scaled_width, scaled_height, mask, filter);
-    glCopyTextureSubImage3D(scaled_texture.handle, 0, 0, 0, 0, 0, 0, scaled_width, scaled_height);
+    const auto& blit_fbo = runtime->rescale_fbo;
+    for (s32 level = 0; level < info.resources.levels; ++level) {
+        const u32 level_width = scaled_width >> level;
+        const u32 level_height = scaled_height >> level;
+        glBindFramebuffer(GL_READ_FRAMEBUFFER, blit_fbo.handle);
+        glNamedFramebufferTexture(blit_fbo.handle, attachment, texture.handle, level);
+        glBlitNamedFramebuffer(blit_fbo.handle, blit_fbo.handle, 0, 0, original_width,
+                               original_height, 0, 0, level_width, level_height, mask, filter);
+        switch (info.type) {
+        case ImageType::e1D:
+            glCopyTextureSubImage2D(scaled_texture.handle, level, 0, 0, 0, 0, level_width,
+                                    level_height);
+            break;
+        case ImageType::e2D:
+            glCopyTextureSubImage3D(scaled_texture.handle, level, 0, 0, 0, 0, 0, level_width,
+                                    level_height);
+            break;
+        case ImageType::e3D:
+        default:
+            UNREACHABLE();
+        }
+    }
     texture = std::move(scaled_texture);
     texture = std::move(scaled_texture);
 
 
     // Restore previous framebuffers
     // Restore previous framebuffers
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prev_draw_fbo);
     glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo);
     glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo);
 }
 }
 
 

+ 1 - 0
src/video_core/renderer_opengl/gl_texture_cache.h

@@ -155,6 +155,7 @@ private:
 
 
     std::array<GLuint, Shader::NUM_TEXTURE_TYPES> null_image_views{};
     std::array<GLuint, Shader::NUM_TEXTURE_TYPES> null_image_views{};
 
 
+    OGLFramebuffer rescale_fbo;
     Settings::ResolutionScalingInfo resolution;
     Settings::ResolutionScalingInfo resolution;
     bool is_rescaling_on{};
     bool is_rescaling_on{};
 };
 };