diff options
| author | 2021-09-18 19:15:10 -0400 | |
|---|---|---|
| committer | 2021-11-16 22:11:30 +0100 | |
| commit | 27af298e78ffa976bf126d7f276fa95c4f4f1363 (patch) | |
| tree | 8d743afc63bbbdb905f9fa1fb55cb5852c839399 /src | |
| parent | gl_texture_cache/rescaling_pass: minor cleanup (diff) | |
| download | yuzu-27af298e78ffa976bf126d7f276fa95c4f4f1363.tar.gz yuzu-27af298e78ffa976bf126d7f276fa95c4f4f1363.tar.xz yuzu-27af298e78ffa976bf126d7f276fa95c4f4f1363.zip | |
gl_texture_cache: Fix depth and integer format scaling blits
Diffstat (limited to 'src')
| -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 | |||
| 395 | UNREACHABLE_MSG("Invalid image format={}", format); | 395 | UNREACHABLE_MSG("Invalid image format={}", format); |
| 396 | return GL_R32UI; | 396 | return GL_R32UI; |
| 397 | } | 397 | } |
| 398 | |||
| 399 | [[nodiscard]] bool IsPixelFormatInteger(PixelFormat format) { | ||
| 400 | switch (format) { | ||
| 401 | case PixelFormat::A8B8G8R8_SINT: | ||
| 402 | case PixelFormat::A8B8G8R8_UINT: | ||
| 403 | case PixelFormat::A2B10G10R10_UINT: | ||
| 404 | case PixelFormat::R8_SINT: | ||
| 405 | case PixelFormat::R8_UINT: | ||
| 406 | case PixelFormat::R16G16B16A16_SINT: | ||
| 407 | case PixelFormat::R16G16B16A16_UINT: | ||
| 408 | case PixelFormat::R32G32B32A32_UINT: | ||
| 409 | case PixelFormat::R32G32B32A32_SINT: | ||
| 410 | case PixelFormat::R32G32_SINT: | ||
| 411 | case PixelFormat::R16_UINT: | ||
| 412 | case PixelFormat::R16_SINT: | ||
| 413 | case PixelFormat::R16G16_UINT: | ||
| 414 | case PixelFormat::R16G16_SINT: | ||
| 415 | case PixelFormat::R8G8_SINT: | ||
| 416 | case PixelFormat::R8G8_UINT: | ||
| 417 | case PixelFormat::R32G32_UINT: | ||
| 418 | case PixelFormat::R32_UINT: | ||
| 419 | case PixelFormat::R32_SINT: | ||
| 420 | return true; | ||
| 421 | default: | ||
| 422 | return false; | ||
| 423 | } | ||
| 424 | } | ||
| 398 | } // Anonymous namespace | 425 | } // Anonymous namespace |
| 399 | 426 | ||
| 400 | ImageBufferMap::~ImageBufferMap() { | 427 | ImageBufferMap::~ImageBufferMap() { |
| @@ -475,12 +502,14 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& | |||
| 475 | 502 | ||
| 476 | resolution = Settings::values.resolution_info; | 503 | resolution = Settings::values.resolution_info; |
| 477 | if (resolution.active) { | 504 | if (resolution.active) { |
| 478 | rescale_draw_fbo.Create(); | 505 | for (size_t i = 0; i < rescale_draw_fbos.size(); ++i) { |
| 479 | rescale_read_fbo.Create(); | 506 | rescale_draw_fbos[i].Create(); |
| 507 | rescale_read_fbos[i].Create(); | ||
| 480 | 508 | ||
| 481 | // Make sure the framebuffer is created without DSA | 509 | // Make sure the framebuffer is created without DSA |
| 482 | glBindFramebuffer(GL_READ_FRAMEBUFFER, rescale_draw_fbo.handle); | 510 | glBindFramebuffer(GL_READ_FRAMEBUFFER, rescale_draw_fbos[i].handle); |
| 483 | glBindFramebuffer(GL_READ_FRAMEBUFFER, rescale_read_fbo.handle); | 511 | glBindFramebuffer(GL_READ_FRAMEBUFFER, rescale_read_fbos[i].handle); |
| 512 | } | ||
| 484 | } | 513 | } |
| 485 | } | 514 | } |
| 486 | 515 | ||
| @@ -888,8 +917,9 @@ bool Image::Scale() { | |||
| 888 | std::swap(texture, scale_backup); | 917 | std::swap(texture, scale_backup); |
| 889 | return true; | 918 | return true; |
| 890 | } | 919 | } |
| 891 | const GLenum attachment = [this] { | 920 | const auto format_type = GetFormatType(info.format); |
| 892 | switch (GetFormatType(info.format)) { | 921 | const GLenum attachment = [format_type] { |
| 922 | switch (format_type) { | ||
| 893 | case SurfaceType::ColorTexture: | 923 | case SurfaceType::ColorTexture: |
| 894 | return GL_COLOR_ATTACHMENT0; | 924 | return GL_COLOR_ATTACHMENT0; |
| 895 | case SurfaceType::Depth: | 925 | case SurfaceType::Depth: |
| @@ -901,8 +931,8 @@ bool Image::Scale() { | |||
| 901 | return GL_COLOR_ATTACHMENT0; | 931 | return GL_COLOR_ATTACHMENT0; |
| 902 | } | 932 | } |
| 903 | }(); | 933 | }(); |
| 904 | const GLenum mask = [this] { | 934 | const GLenum mask = [format_type] { |
| 905 | switch (GetFormatType(info.format)) { | 935 | switch (format_type) { |
| 906 | case SurfaceType::ColorTexture: | 936 | case SurfaceType::ColorTexture: |
| 907 | return GL_COLOR_BUFFER_BIT; | 937 | return GL_COLOR_BUFFER_BIT; |
| 908 | case SurfaceType::Depth: | 938 | case SurfaceType::Depth: |
| @@ -914,8 +944,25 @@ bool Image::Scale() { | |||
| 914 | return GL_COLOR_BUFFER_BIT; | 944 | return GL_COLOR_BUFFER_BIT; |
| 915 | } | 945 | } |
| 916 | }(); | 946 | }(); |
| 917 | const GLenum filter = (mask & GL_COLOR_BUFFER_BIT) != 0 ? GL_LINEAR : GL_NEAREST; | 947 | const size_t fbo_index = [format_type] { |
| 948 | switch (format_type) { | ||
| 949 | case SurfaceType::ColorTexture: | ||
| 950 | return 0; | ||
| 951 | case SurfaceType::Depth: | ||
| 952 | return 1; | ||
| 953 | case SurfaceType::DepthStencil: | ||
| 954 | return 2; | ||
| 955 | default: | ||
| 956 | UNREACHABLE(); | ||
| 957 | return 0; | ||
| 958 | } | ||
| 959 | }(); | ||
| 918 | const bool is_2d = info.type == ImageType::e2D; | 960 | const bool is_2d = info.type == ImageType::e2D; |
| 961 | const bool is_color{(mask & GL_COLOR_BUFFER_BIT) != 0}; | ||
| 962 | // Integer formats must use NEAREST filter | ||
| 963 | const bool linear_color_format{is_color && !IsPixelFormatInteger(info.format)}; | ||
| 964 | const GLenum filter = linear_color_format ? GL_LINEAR : GL_NEAREST; | ||
| 965 | |||
| 919 | const auto& resolution = runtime->resolution; | 966 | const auto& resolution = runtime->resolution; |
| 920 | const u32 up = resolution.up_scale; | 967 | const u32 up = resolution.up_scale; |
| 921 | const u32 down = resolution.down_shift; | 968 | const u32 down = resolution.down_shift; |
| @@ -931,8 +978,8 @@ bool Image::Scale() { | |||
| 931 | dst_info.size.height = scaled_height; | 978 | dst_info.size.height = scaled_height; |
| 932 | scale_backup = MakeImage(dst_info, gl_internal_format); | 979 | scale_backup = MakeImage(dst_info, gl_internal_format); |
| 933 | 980 | ||
| 934 | const GLuint read_fbo = runtime->rescale_read_fbo.handle; | 981 | const GLuint read_fbo = runtime->rescale_read_fbos[fbo_index].handle; |
| 935 | const GLuint draw_fbo = runtime->rescale_draw_fbo.handle; | 982 | const GLuint draw_fbo = runtime->rescale_draw_fbos[fbo_index].handle; |
| 936 | for (s32 layer = 0; layer < info.resources.layers; ++layer) { | 983 | for (s32 layer = 0; layer < info.resources.layers; ++layer) { |
| 937 | for (s32 level = 0; level < info.resources.levels; ++level) { | 984 | for (s32 level = 0; level < info.resources.levels; ++level) { |
| 938 | const u32 src_level_width = std::max(1u, original_width >> level); | 985 | const u32 src_level_width = std::max(1u, original_width >> level); |
| @@ -944,8 +991,6 @@ bool Image::Scale() { | |||
| 944 | glNamedFramebufferTextureLayer(draw_fbo, attachment, scale_backup.handle, level, layer); | 991 | glNamedFramebufferTextureLayer(draw_fbo, attachment, scale_backup.handle, level, layer); |
| 945 | glBlitNamedFramebuffer(read_fbo, draw_fbo, 0, 0, src_level_width, src_level_height, 0, | 992 | glBlitNamedFramebuffer(read_fbo, draw_fbo, 0, 0, src_level_width, src_level_height, 0, |
| 946 | 0, dst_level_width, dst_level_height, mask, filter); | 993 | 0, dst_level_width, dst_level_height, mask, filter); |
| 947 | glNamedFramebufferTextureLayer(read_fbo, attachment, 0, level, layer); | ||
| 948 | glNamedFramebufferTextureLayer(draw_fbo, attachment, 0, level, layer); | ||
| 949 | } | 994 | } |
| 950 | } | 995 | } |
| 951 | std::swap(texture, scale_backup); | 996 | 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: | |||
| 153 | 153 | ||
| 154 | std::array<GLuint, Shader::NUM_TEXTURE_TYPES> null_image_views{}; | 154 | std::array<GLuint, Shader::NUM_TEXTURE_TYPES> null_image_views{}; |
| 155 | 155 | ||
| 156 | OGLFramebuffer rescale_draw_fbo; | 156 | std::array<OGLFramebuffer, 3> rescale_draw_fbos; |
| 157 | OGLFramebuffer rescale_read_fbo; | 157 | std::array<OGLFramebuffer, 3> rescale_read_fbos; |
| 158 | Settings::ResolutionScalingInfo resolution; | 158 | Settings::ResolutionScalingInfo resolution; |
| 159 | }; | 159 | }; |
| 160 | 160 | ||