gl_texture_cache: Implement ScaleDown

This commit is contained in:
ameerj 2021-07-21 21:23:00 -04:00 committed by Fernando Sahmkow
parent 0a6c895af7
commit fddf372c68
2 changed files with 36 additions and 26 deletions

View File

@ -869,17 +869,17 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b
} }
} }
void Image::Scale(u32 up, u32 down) { bool Image::Scale(bool scale_src, bool scale_dst) {
if (!runtime->is_rescaling_on) { if (!runtime->is_rescaling_on) {
return; return false;
} }
if (gl_format == 0 && gl_type == 0) { if (gl_format == 0 && gl_type == 0) {
// compressed textures // compressed textures
return; return false;
} }
if (info.type == ImageType::Linear) { if (info.type == ImageType::Linear) {
UNIMPLEMENTED(); UNIMPLEMENTED();
return; return false;
} }
GLint prev_read_fbo; GLint prev_read_fbo;
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prev_read_fbo); glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prev_read_fbo);
@ -910,43 +910,58 @@ 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;
const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); };
const bool is_2d = info.type == ImageType::e2D; const bool is_2d = info.type == ImageType::e2D;
const auto& resolution = runtime->resolution;
const u32 up = resolution.up_scale;
const u32 down = resolution.down_shift;
const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); };
const u32 scaled_width = scale_up(info.size.width); const u32 scaled_width = scale_up(info.size.width);
const u32 scaled_height = is_2d ? scale_up(info.size.height) : 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;
auto scaled_info = info; const u32 src_width = scale_src ? scaled_width : original_width;
scaled_info.size.width = scaled_width; const u32 src_height = scale_src ? scaled_height : original_height;
scaled_info.size.height = scaled_height; const u32 dst_width = scale_dst ? scaled_width : original_width;
auto scaled_texture = MakeImage(scaled_info, gl_internal_format); const u32 dst_height = scale_dst ? scaled_height : original_height;
auto dst_info = info;
dst_info.size.width = dst_width;
dst_info.size.height = dst_height;
auto dst_texture = MakeImage(dst_info, gl_internal_format);
const auto& blit_fbo = runtime->rescale_fbo; const auto& blit_fbo = runtime->rescale_fbo;
for (s32 level = 0; level < info.resources.levels; ++level) { for (s32 level = 0; level < info.resources.levels; ++level) {
const u32 level_width = scaled_width >> level; const u32 src_level_width = std::max(1u, src_width >> level);
const u32 level_height = scaled_height >> level; const u32 src_level_height = std::max(1u, src_height >> level);
const u32 dst_level_width = std::max(1u, dst_width >> level);
const u32 dst_level_height = std::max(1u, dst_height >> level);
glBindFramebuffer(GL_READ_FRAMEBUFFER, blit_fbo.handle); glBindFramebuffer(GL_READ_FRAMEBUFFER, blit_fbo.handle);
glNamedFramebufferTexture(blit_fbo.handle, attachment, texture.handle, level); glNamedFramebufferTexture(blit_fbo.handle, attachment, texture.handle, level);
glBlitNamedFramebuffer(blit_fbo.handle, blit_fbo.handle, 0, 0, original_width, glBlitNamedFramebuffer(blit_fbo.handle, blit_fbo.handle, 0, 0, src_level_width,
original_height, 0, 0, level_width, level_height, mask, filter); src_level_height, 0, 0, dst_level_width, dst_level_height, mask,
filter);
switch (info.type) { switch (info.type) {
case ImageType::e1D: case ImageType::e1D:
glCopyTextureSubImage2D(scaled_texture.handle, level, 0, 0, 0, 0, level_width, glCopyTextureSubImage2D(dst_texture.handle, level, 0, 0, 0, 0, dst_level_width,
level_height); dst_level_height);
break; break;
case ImageType::e2D: case ImageType::e2D:
glCopyTextureSubImage3D(scaled_texture.handle, level, 0, 0, 0, 0, 0, level_width, glCopyTextureSubImage3D(dst_texture.handle, level, 0, 0, 0, 0, 0, dst_level_width,
level_height); dst_level_height);
break; break;
case ImageType::e3D: case ImageType::e3D:
default: default:
UNREACHABLE(); UNREACHABLE();
} }
} }
texture = std::move(scaled_texture); texture = std::move(dst_texture);
// Restore previous framebuffers // Restore previous framebuffers
glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo); glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo);
return true;
} }
bool Image::ScaleUp() { bool Image::ScaleUp() {
@ -954,9 +969,7 @@ bool Image::ScaleUp() {
return false; return false;
} }
flags |= ImageFlagBits::Rescaled; flags |= ImageFlagBits::Rescaled;
const auto& resolution = runtime->resolution; return Scale(false, true);
Scale(resolution.up_scale, resolution.down_shift);
return true;
} }
bool Image::ScaleDown() { bool Image::ScaleDown() {
@ -964,10 +977,7 @@ bool Image::ScaleDown() {
return false; return false;
} }
flags &= ~ImageFlagBits::Rescaled; flags &= ~ImageFlagBits::Rescaled;
UNIMPLEMENTED(); return Scale(true, false);
// const auto& resolution = runtime->resolution;
// Scale();
return true;
} }
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,

View File

@ -203,7 +203,7 @@ private:
void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset); void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset);
void Scale(u32 up, u32 down); bool Scale(bool scale_src, bool scale_dst);
OGLTexture texture; OGLTexture texture;
OGLTextureView store_view; OGLTextureView store_view;