From 11de7700aa60609d8223ffcd6bb80d324030845f Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 9 Oct 2022 14:05:44 +0300 Subject: [PATCH] video_core: Fix renderpass cache bug and introduce RGBA -> BGR converter --- src/video_core/renderer_opengl/gl_texture_runtime.cpp | 8 ++++++-- src/video_core/renderer_vulkan/vk_renderpass_cache.cpp | 2 +- src/video_core/renderer_vulkan/vk_texture_runtime.cpp | 8 +++++++- src/video_core/texture/texture_decode.cpp | 10 ++++++++++ src/video_core/texture/texture_decode.h | 2 ++ 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.cpp b/src/video_core/renderer_opengl/gl_texture_runtime.cpp index 2c3925d02..c13b19579 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.cpp +++ b/src/video_core/renderer_opengl/gl_texture_runtime.cpp @@ -142,8 +142,12 @@ void TextureRuntime::FormatConvert(const Surface& surface, bool upload, std::spa } else if (format == VideoCore::PixelFormat::RGB8 && driver.IsOpenGLES()) { return Pica::Texture::ConvertBGRToRGB(source, dest); } else { - ASSERT(dest.size() >= source.size()); - std::memcpy(dest.data(), source.data(), source.size()); + // Sometimes the source size might be larger than the destination. + // This can happen during texture downloads when FromInterval aligns + // the flush range to scanline boundaries. In that case only copy + // what we need + const std::size_t copy_size = std::min(source.size(), dest.size()); + std::memcpy(dest.data(), source.data(), copy_size); } } diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp index a0bf5046c..2d9b14fb5 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp @@ -30,7 +30,7 @@ VideoCore::PixelFormat ToFormatDepth(u32 index) { switch (index) { case 0: return VideoCore::PixelFormat::D16; - case 1: + case 2: return VideoCore::PixelFormat::D24; case 3: return VideoCore::PixelFormat::D24S8; diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp index a8dc43948..f4a2aea78 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp @@ -222,7 +222,11 @@ void TextureRuntime::FormatConvert(const Surface& surface, bool upload, std::spa // Handle simple D24S8 interleave case if (surface.GetInternalFormat() == vk::Format::eD24UnormS8Uint) { - return Pica::Texture::InterleaveD24S8(source, dest); + if (!upload) { + return Pica::Texture::InterleaveD24S8(source, dest); + } else { + UNREACHABLE(); + } } if (upload) { @@ -242,6 +246,8 @@ void TextureRuntime::FormatConvert(const Surface& surface, bool upload, std::spa return Pica::Texture::ConvertD32S8ToD24S8(source, dest); case VideoCore::PixelFormat::RGBA4: return Pica::Texture::ConvertRGBA8ToRGBA4(source, dest); + case VideoCore::PixelFormat::RGB8: + return Pica::Texture::ConvertRGBAToBGR(source, dest); default: break; } diff --git a/src/video_core/texture/texture_decode.cpp b/src/video_core/texture/texture_decode.cpp index 99c467999..82c0faf34 100644 --- a/src/video_core/texture/texture_decode.cpp +++ b/src/video_core/texture/texture_decode.cpp @@ -242,6 +242,16 @@ void ConvertBGRToRGBA(std::span source, std::span de } } +void ConvertRGBAToBGR(std::span source, std::span dest) { + u32 j = 0; + for (std::size_t i = 0; i < dest.size(); i += 3) { + dest[i] = source[j + 2]; + dest[i + 1] = source[j + 1]; + dest[i + 2] = source[j]; + j += 4; + } +} + void ConvertABGRToRGBA(std::span source, std::span dest) { for (u32 i = 0; i < dest.size(); i += 4) { u32 abgr; diff --git a/src/video_core/texture/texture_decode.h b/src/video_core/texture/texture_decode.h index afdc3f429..a7158e351 100644 --- a/src/video_core/texture/texture_decode.h +++ b/src/video_core/texture/texture_decode.h @@ -71,6 +71,8 @@ void ConvertBGRToRGB(std::span source, std::span des */ void ConvertBGRToRGBA(std::span source, std::span dest); +void ConvertRGBAToBGR(std::span source, std::span dest); + /** * Converts pixel data encoded in ABGR format to RGBA *