diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 73 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 4 | 
2 files changed, 61 insertions, 16 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 64bd88c3b..dc850e7b0 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -395,6 +395,33 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form      UNREACHABLE_MSG("Invalid image format={}", format);      return GL_R32UI;  } + +[[nodiscard]] bool IsPixelFormatInteger(PixelFormat format) { +    switch (format) { +    case PixelFormat::A8B8G8R8_SINT: +    case PixelFormat::A8B8G8R8_UINT: +    case PixelFormat::A2B10G10R10_UINT: +    case PixelFormat::R8_SINT: +    case PixelFormat::R8_UINT: +    case PixelFormat::R16G16B16A16_SINT: +    case PixelFormat::R16G16B16A16_UINT: +    case PixelFormat::R32G32B32A32_UINT: +    case PixelFormat::R32G32B32A32_SINT: +    case PixelFormat::R32G32_SINT: +    case PixelFormat::R16_UINT: +    case PixelFormat::R16_SINT: +    case PixelFormat::R16G16_UINT: +    case PixelFormat::R16G16_SINT: +    case PixelFormat::R8G8_SINT: +    case PixelFormat::R8G8_UINT: +    case PixelFormat::R32G32_UINT: +    case PixelFormat::R32_UINT: +    case PixelFormat::R32_SINT: +        return true; +    default: +        return false; +    } +}  } // Anonymous namespace  ImageBufferMap::~ImageBufferMap() { @@ -475,12 +502,14 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager&      resolution = Settings::values.resolution_info;      if (resolution.active) { -        rescale_draw_fbo.Create(); -        rescale_read_fbo.Create(); +        for (size_t i = 0; i < rescale_draw_fbos.size(); ++i) { +            rescale_draw_fbos[i].Create(); +            rescale_read_fbos[i].Create(); -        // Make sure the framebuffer is created without DSA -        glBindFramebuffer(GL_READ_FRAMEBUFFER, rescale_draw_fbo.handle); -        glBindFramebuffer(GL_READ_FRAMEBUFFER, rescale_read_fbo.handle); +            // Make sure the framebuffer is created without DSA +            glBindFramebuffer(GL_READ_FRAMEBUFFER, rescale_draw_fbos[i].handle); +            glBindFramebuffer(GL_READ_FRAMEBUFFER, rescale_read_fbos[i].handle); +        }      }  } @@ -888,8 +917,9 @@ bool Image::Scale() {          std::swap(texture, scale_backup);          return true;      } -    const GLenum attachment = [this] { -        switch (GetFormatType(info.format)) { +    const auto format_type = GetFormatType(info.format); +    const GLenum attachment = [format_type] { +        switch (format_type) {          case SurfaceType::ColorTexture:              return GL_COLOR_ATTACHMENT0;          case SurfaceType::Depth: @@ -901,8 +931,8 @@ bool Image::Scale() {              return GL_COLOR_ATTACHMENT0;          }      }(); -    const GLenum mask = [this] { -        switch (GetFormatType(info.format)) { +    const GLenum mask = [format_type] { +        switch (format_type) {          case SurfaceType::ColorTexture:              return GL_COLOR_BUFFER_BIT;          case SurfaceType::Depth: @@ -914,8 +944,25 @@ bool Image::Scale() {              return GL_COLOR_BUFFER_BIT;          }      }(); -    const GLenum filter = (mask & GL_COLOR_BUFFER_BIT) != 0 ? GL_LINEAR : GL_NEAREST; +    const size_t fbo_index = [format_type] { +        switch (format_type) { +        case SurfaceType::ColorTexture: +            return 0; +        case SurfaceType::Depth: +            return 1; +        case SurfaceType::DepthStencil: +            return 2; +        default: +            UNREACHABLE(); +            return 0; +        } +    }();      const bool is_2d = info.type == ImageType::e2D; +    const bool is_color{(mask & GL_COLOR_BUFFER_BIT) != 0}; +    // Integer formats must use NEAREST filter +    const bool linear_color_format{is_color && !IsPixelFormatInteger(info.format)}; +    const GLenum filter = linear_color_format ? GL_LINEAR : GL_NEAREST; +      const auto& resolution = runtime->resolution;      const u32 up = resolution.up_scale;      const u32 down = resolution.down_shift; @@ -931,8 +978,8 @@ bool Image::Scale() {      dst_info.size.height = scaled_height;      scale_backup = MakeImage(dst_info, gl_internal_format); -    const GLuint read_fbo = runtime->rescale_read_fbo.handle; -    const GLuint draw_fbo = runtime->rescale_draw_fbo.handle; +    const GLuint read_fbo = runtime->rescale_read_fbos[fbo_index].handle; +    const GLuint draw_fbo = runtime->rescale_draw_fbos[fbo_index].handle;      for (s32 layer = 0; layer < info.resources.layers; ++layer) {          for (s32 level = 0; level < info.resources.levels; ++level) {              const u32 src_level_width = std::max(1u, original_width >> level); @@ -944,8 +991,6 @@ bool Image::Scale() {              glNamedFramebufferTextureLayer(draw_fbo, attachment, scale_backup.handle, level, layer);              glBlitNamedFramebuffer(read_fbo, draw_fbo, 0, 0, src_level_width, src_level_height, 0,                                     0, dst_level_width, dst_level_height, mask, filter); -            glNamedFramebufferTextureLayer(read_fbo, attachment, 0, level, layer); -            glNamedFramebufferTextureLayer(draw_fbo, attachment, 0, level, layer);          }      }      std::swap(texture, scale_backup); diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 6c8033003..79448f670 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -153,8 +153,8 @@ private:      std::array<GLuint, Shader::NUM_TEXTURE_TYPES> null_image_views{}; -    OGLFramebuffer rescale_draw_fbo; -    OGLFramebuffer rescale_read_fbo; +    std::array<OGLFramebuffer, 3> rescale_draw_fbos; +    std::array<OGLFramebuffer, 3> rescale_read_fbos;      Settings::ResolutionScalingInfo resolution;  };  | 
