summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ameerj2021-07-21 00:02:35 -0400
committerGravatar Fernando Sahmkow2021-11-16 22:11:27 +0100
commitde66a69ed4b556ad96f38570ea0a31cb2a1870f1 (patch)
tree1ccad15e5a9a202494a72fdf6edf2b0abb6fa2b5
parentTextureCache: Fix rescaling of ImageCopies (diff)
downloadyuzu-de66a69ed4b556ad96f38570ea0a31cb2a1870f1.tar.gz
yuzu-de66a69ed4b556ad96f38570ea0a31cb2a1870f1.tar.xz
yuzu-de66a69ed4b556ad96f38570ea0a31cb2a1870f1.zip
renderer_gl: Resolution scaling fixes
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp23
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp136
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h9
3 files changed, 107 insertions, 61 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index a6d9f7c43..b91e7edf8 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -577,6 +577,14 @@ void RasterizerOpenGL::SyncViewport() {
577 const bool force = flags[Dirty::ViewportTransform]; 577 const bool force = flags[Dirty::ViewportTransform];
578 flags[Dirty::ViewportTransform] = false; 578 flags[Dirty::ViewportTransform] = false;
579 579
580 const auto& resolution = Settings::values.resolution_info;
581 const auto scale_up = [&](u32 value) -> u32 {
582 if (value == 0) {
583 return 0U;
584 }
585 const u32 converted_value = (value * resolution.up_scale) >> resolution.down_shift;
586 return std::max<u32>(converted_value, 1U);
587 };
580 for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) { 588 for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) {
581 if (!force && !flags[Dirty::Viewport0 + i]) { 589 if (!force && !flags[Dirty::Viewport0 + i]) {
582 continue; 590 continue;
@@ -585,8 +593,8 @@ void RasterizerOpenGL::SyncViewport() {
585 593
586 const auto& src = regs.viewport_transform[i]; 594 const auto& src = regs.viewport_transform[i];
587 const Common::Rectangle<f32> rect{src.GetRect()}; 595 const Common::Rectangle<f32> rect{src.GetRect()};
588 glViewportIndexedf(static_cast<GLuint>(i), rect.left, rect.bottom, rect.GetWidth(), 596 glViewportIndexedf(static_cast<GLuint>(i), rect.left, rect.bottom,
589 rect.GetHeight()); 597 scale_up(rect.GetWidth()), scale_up(rect.GetHeight()));
590 598
591 const GLdouble reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne; 599 const GLdouble reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne;
592 const GLdouble near_depth = src.translate_z - src.scale_z * reduce_z; 600 const GLdouble near_depth = src.translate_z - src.scale_z * reduce_z;
@@ -909,6 +917,15 @@ void RasterizerOpenGL::SyncScissorTest() {
909 flags[Dirty::Scissors] = false; 917 flags[Dirty::Scissors] = false;
910 918
911 const auto& regs = maxwell3d.regs; 919 const auto& regs = maxwell3d.regs;
920
921 const auto& resolution = Settings::values.resolution_info;
922 const auto scale_up = [&](u32 value) -> u32 {
923 if (value == 0) {
924 return 0U;
925 }
926 const u32 converted_value = (value * resolution.up_scale) >> resolution.down_shift;
927 return std::max<u32>(converted_value, 1U);
928 };
912 for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) { 929 for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) {
913 if (!flags[Dirty::Scissor0 + index]) { 930 if (!flags[Dirty::Scissor0 + index]) {
914 continue; 931 continue;
@@ -919,7 +936,7 @@ void RasterizerOpenGL::SyncScissorTest() {
919 if (src.enable) { 936 if (src.enable) {
920 glEnablei(GL_SCISSOR_TEST, static_cast<GLuint>(index)); 937 glEnablei(GL_SCISSOR_TEST, static_cast<GLuint>(index));
921 glScissorIndexed(static_cast<GLuint>(index), src.min_x, src.min_y, 938 glScissorIndexed(static_cast<GLuint>(index), src.min_x, src.min_y,
922 src.max_x - src.min_x, src.max_y - src.min_y); 939 scale_up(src.max_x - src.min_x), scale_up(src.max_y - src.min_y));
923 } else { 940 } else {
924 glDisablei(GL_SCISSOR_TEST, static_cast<GLuint>(index)); 941 glDisablei(GL_SCISSOR_TEST, static_cast<GLuint>(index));
925 } 942 }
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 2d9f770cd..ecde5b600 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -316,6 +316,52 @@ void AttachTexture(GLuint fbo, GLenum attachment, const ImageView* image_view) {
316 } 316 }
317} 317}
318 318
319OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_format) {
320 const GLenum target = ImageTarget(info);
321 const GLsizei width = info.size.width;
322 const GLsizei height = info.size.height;
323 const GLsizei depth = info.size.depth;
324 const int max_host_mip_levels = std::bit_width(info.size.width);
325 const GLsizei num_levels = std::min(info.resources.levels, max_host_mip_levels);
326 const GLsizei num_layers = info.resources.layers;
327 const GLsizei num_samples = info.num_samples;
328
329 GLuint handle = 0;
330 OGLTexture texture;
331 if (target != GL_TEXTURE_BUFFER) {
332 texture.Create(target);
333 handle = texture.handle;
334 }
335 switch (target) {
336 case GL_TEXTURE_1D_ARRAY:
337 glTextureStorage2D(handle, num_levels, gl_internal_format, width, num_layers);
338 break;
339 case GL_TEXTURE_2D_ARRAY:
340 glTextureStorage3D(handle, num_levels, gl_internal_format, width, height, num_layers);
341 break;
342 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: {
343 // TODO: Where should 'fixedsamplelocations' come from?
344 const auto [samples_x, samples_y] = SamplesLog2(info.num_samples);
345 glTextureStorage3DMultisample(handle, num_samples, gl_internal_format, width >> samples_x,
346 height >> samples_y, num_layers, GL_FALSE);
347 break;
348 }
349 case GL_TEXTURE_RECTANGLE:
350 glTextureStorage2D(handle, num_levels, gl_internal_format, width, height);
351 break;
352 case GL_TEXTURE_3D:
353 glTextureStorage3D(handle, num_levels, gl_internal_format, width, height, depth);
354 break;
355 case GL_TEXTURE_BUFFER:
356 UNREACHABLE();
357 break;
358 default:
359 UNREACHABLE_MSG("Invalid target=0x{:x}", target);
360 break;
361 }
362 return texture;
363}
364
319[[nodiscard]] bool IsPixelFormatBGR(PixelFormat format) { 365[[nodiscard]] bool IsPixelFormatBGR(PixelFormat format) {
320 switch (format) { 366 switch (format) {
321 case PixelFormat::B5G6R5_UNORM: 367 case PixelFormat::B5G6R5_UNORM:
@@ -430,6 +476,11 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager&
430 476
431TextureCacheRuntime::~TextureCacheRuntime() = default; 477TextureCacheRuntime::~TextureCacheRuntime() = default;
432 478
479void TextureCacheRuntime::Init() {
480 resolution = Settings::values.resolution_info;
481 is_rescaling_on = resolution.up_scale != 1 || resolution.down_shift != 0;
482}
483
433void TextureCacheRuntime::Finish() { 484void TextureCacheRuntime::Finish() {
434 glFinish(); 485 glFinish();
435} 486}
@@ -605,13 +656,13 @@ std::optional<size_t> TextureCacheRuntime::StagingBuffers::FindBuffer(size_t req
605 return found; 656 return found;
606} 657}
607 658
608Image::Image(TextureCacheRuntime& runtime, const VideoCommon::ImageInfo& info_, GPUVAddr gpu_addr_, 659Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_, GPUVAddr gpu_addr_,
609 VAddr cpu_addr_) 660 VAddr cpu_addr_)
610 : VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_) { 661 : VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), runtime{&runtime_} {
611 if (CanBeAccelerated(runtime, info)) { 662 if (CanBeAccelerated(*runtime, info)) {
612 flags |= ImageFlagBits::AcceleratedUpload; 663 flags |= ImageFlagBits::AcceleratedUpload;
613 } 664 }
614 if (IsConverted(runtime.device, info.format, info.type)) { 665 if (IsConverted(runtime->device, info.format, info.type)) {
615 flags |= ImageFlagBits::Converted; 666 flags |= ImageFlagBits::Converted;
616 gl_internal_format = IsPixelFormatSRGB(info.format) ? GL_SRGB8_ALPHA8 : GL_RGBA8; 667 gl_internal_format = IsPixelFormatSRGB(info.format) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
617 gl_format = GL_RGBA; 668 gl_format = GL_RGBA;
@@ -622,51 +673,11 @@ Image::Image(TextureCacheRuntime& runtime, const VideoCommon::ImageInfo& info_,
622 gl_format = tuple.format; 673 gl_format = tuple.format;
623 gl_type = tuple.type; 674 gl_type = tuple.type;
624 } 675 }
625 const GLenum target = ImageTarget(info); 676 texture = MakeImage(info, gl_internal_format);
626 const GLsizei width = info.size.width; 677 if (runtime->device.HasDebuggingToolAttached()) {
627 const GLsizei height = info.size.height;
628 const GLsizei depth = info.size.depth;
629 const int max_host_mip_levels = std::bit_width(info.size.width);
630 const GLsizei num_levels = std::min(info.resources.levels, max_host_mip_levels);
631 const GLsizei num_layers = info.resources.layers;
632 const GLsizei num_samples = info.num_samples;
633
634 GLuint handle = 0;
635 if (target != GL_TEXTURE_BUFFER) {
636 texture.Create(target);
637 handle = texture.handle;
638 }
639 switch (target) {
640 case GL_TEXTURE_1D_ARRAY:
641 glTextureStorage2D(handle, num_levels, gl_internal_format, width, num_layers);
642 break;
643 case GL_TEXTURE_2D_ARRAY:
644 glTextureStorage3D(handle, num_levels, gl_internal_format, width, height, num_layers);
645 break;
646 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: {
647 // TODO: Where should 'fixedsamplelocations' come from?
648 const auto [samples_x, samples_y] = SamplesLog2(info.num_samples);
649 glTextureStorage3DMultisample(handle, num_samples, gl_internal_format, width >> samples_x,
650 height >> samples_y, num_layers, GL_FALSE);
651 break;
652 }
653 case GL_TEXTURE_RECTANGLE:
654 glTextureStorage2D(handle, num_levels, gl_internal_format, width, height);
655 break;
656 case GL_TEXTURE_3D:
657 glTextureStorage3D(handle, num_levels, gl_internal_format, width, height, depth);
658 break;
659 case GL_TEXTURE_BUFFER:
660 UNREACHABLE();
661 break;
662 default:
663 UNREACHABLE_MSG("Invalid target=0x{:x}", target);
664 break;
665 }
666 if (runtime.device.HasDebuggingToolAttached()) {
667 const std::string name = VideoCommon::Name(*this); 678 const std::string name = VideoCommon::Name(*this);
668 glObjectLabel(target == GL_TEXTURE_BUFFER ? GL_BUFFER : GL_TEXTURE, handle, 679 glObjectLabel(ImageTarget(info) == GL_TEXTURE_BUFFER ? GL_BUFFER : GL_TEXTURE,
669 static_cast<GLsizei>(name.size()), name.data()); 680 texture.handle, static_cast<GLsizei>(name.size()), name.data());
670 } 681 }
671} 682}
672 683
@@ -855,7 +866,7 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b
855 } 866 }
856} 867}
857 868
858void Image::Scale() { 869void Image::Scale(u32 up, u32 down) {
859 // TODO: Pass scaling factor? 870 // TODO: Pass scaling factor?
860 if (gl_format == 0 || gl_type == 0) { 871 if (gl_format == 0 || gl_type == 0) {
861 // compressed textures 872 // compressed textures
@@ -902,12 +913,22 @@ void Image::Scale() {
902 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_handle); 913 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_handle);
903 glNamedFramebufferTexture(fbo_handle, attachment, texture.handle, 0); 914 glNamedFramebufferTexture(fbo_handle, attachment, texture.handle, 0);
904 915
905 const size_t scaled_width = info.size.width; 916 const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); };
906 const size_t scaled_height = info.size.height * 2; 917 const u32 scaled_width = scale_up(info.size.width);
907 glBlitNamedFramebuffer(fbo_handle, fbo_handle, 0, 0, info.size.width, info.size.height, 0, 0, 918 const u32 scaled_height = scale_up(info.size.height);
919 const u32 original_width = info.size.width;
920 const u32 original_height = info.size.height;
921
922 auto scaled_info = info;
923 scaled_info.size.width = scaled_width;
924 scaled_info.size.height = scaled_height;
925 auto scaled_texture = MakeImage(scaled_info, gl_internal_format);
926
927 glBlitNamedFramebuffer(fbo_handle, fbo_handle, 0, 0, original_width, original_height, 0, 0,
908 scaled_width, scaled_height, mask, filter); 928 scaled_width, scaled_height, mask, filter);
909 // TODO: resize texture? 929 glCopyTextureSubImage3D(scaled_texture.handle, 0, 0, 0, 0, 0, 0, scaled_width, scaled_height);
910 glCopyTextureSubImage3D(texture.handle, 0, 0, 0, 0, 0, 0, scaled_width, scaled_height / 2); 930 texture = std::move(scaled_texture);
931
911 // Restore previous framebuffers 932 // Restore previous framebuffers
912 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prev_draw_fbo); 933 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prev_draw_fbo);
913 glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo); 934 glBindFramebuffer(GL_READ_FRAMEBUFFER, prev_read_fbo);
@@ -918,7 +939,8 @@ bool Image::ScaleUp() {
918 return false; 939 return false;
919 } 940 }
920 flags |= ImageFlagBits::Rescaled; 941 flags |= ImageFlagBits::Rescaled;
921 //Scale(); 942 const auto& resolution = runtime->resolution;
943 Scale(resolution.up_scale, resolution.down_shift);
922 return true; 944 return true;
923} 945}
924 946
@@ -927,7 +949,9 @@ bool Image::ScaleDown() {
927 return false; 949 return false;
928 } 950 }
929 flags &= ~ImageFlagBits::Rescaled; 951 flags &= ~ImageFlagBits::Rescaled;
930 //Scale(); 952 UNIMPLEMENTED();
953 // const auto& resolution = runtime->resolution;
954 // Scale();
931 return true; 955 return true;
932} 956}
933 957
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 324a0f1cb..77ca14132 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -9,6 +9,7 @@
9 9
10#include <glad/glad.h> 10#include <glad/glad.h>
11 11
12#include "common/settings.h"
12#include "shader_recompiler/shader_info.h" 13#include "shader_recompiler/shader_info.h"
13#include "video_core/renderer_opengl/gl_resource_manager.h" 14#include "video_core/renderer_opengl/gl_resource_manager.h"
14#include "video_core/renderer_opengl/util_shaders.h" 15#include "video_core/renderer_opengl/util_shaders.h"
@@ -72,7 +73,7 @@ public:
72 StateTracker& state_tracker); 73 StateTracker& state_tracker);
73 ~TextureCacheRuntime(); 74 ~TextureCacheRuntime();
74 75
75 void Init() {} 76 void Init();
76 77
77 void Finish(); 78 void Finish();
78 79
@@ -153,6 +154,9 @@ private:
153 OGLTextureView null_image_view_cube; 154 OGLTextureView null_image_view_cube;
154 155
155 std::array<GLuint, Shader::NUM_TEXTURE_TYPES> null_image_views{}; 156 std::array<GLuint, Shader::NUM_TEXTURE_TYPES> null_image_views{};
157
158 Settings::ResolutionScalingInfo resolution;
159 bool is_rescaling_on{};
156}; 160};
157 161
158class Image : public VideoCommon::ImageBase { 162class Image : public VideoCommon::ImageBase {
@@ -198,13 +202,14 @@ private:
198 202
199 void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset); 203 void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset);
200 204
201 void Scale(); 205 void Scale(u32 up, u32 down);
202 206
203 OGLTexture texture; 207 OGLTexture texture;
204 OGLTextureView store_view; 208 OGLTextureView store_view;
205 GLenum gl_internal_format = GL_NONE; 209 GLenum gl_internal_format = GL_NONE;
206 GLenum gl_format = GL_NONE; 210 GLenum gl_format = GL_NONE;
207 GLenum gl_type = GL_NONE; 211 GLenum gl_type = GL_NONE;
212 TextureCacheRuntime* runtime;
208}; 213};
209 214
210class ImageView : public VideoCommon::ImageViewBase { 215class ImageView : public VideoCommon::ImageViewBase {