From 6b88a854a791ad94d5b4a31b0dccfba99d514dd3 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 19 Nov 2016 18:34:41 +1000 Subject: [PATCH 1/2] Vulkan: Handle strided XFB copies Where src_rect.width * 2 != dst_stride. --- Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp | 8 +++++--- Source/Core/VideoBackends/Vulkan/TextureCache.cpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp index 17dc9253cd..f01f8ac25b 100644 --- a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp @@ -1415,9 +1415,11 @@ void FramebufferManager::CopyToRealXFB(u32 xfb_addr, u32 fb_stride, u32 fb_heigh {static_cast(scaled_rc.GetWidth()), static_cast(scaled_rc.GetHeight())}}; Texture2D* src_texture = ResolveEFBColorTexture(scaled_rc_vk); - // 2 bytes per pixel, so divide fb_stride by 2 to get the width. - TextureCache::GetInstance()->EncodeYUYVTextureToMemory(xfb_ptr, fb_stride / 2, fb_stride, - fb_height, src_texture, scaled_rc); + // The destination stride can differ from the copy region width, in which case the pixels + // outside the copy region should not be written to. + TextureCache::GetInstance()->EncodeYUYVTextureToMemory( + xfb_ptr, static_cast(source_rc.GetWidth()), fb_stride, fb_height, src_texture, + scaled_rc); // If we sourced directly from the EFB framebuffer, restore it to a color attachment. if (src_texture == m_efb_color_texture.get()) diff --git a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp index d99200b203..d52ba671db 100644 --- a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp @@ -888,7 +888,7 @@ void TextureCache::EncodeYUYVTextureToMemory(void* dst_ptr, u32 dst_width, u32 d m_rgb_to_yuyv_shader); VkRect2D region = {{0, 0}, {output_width, dst_height}}; draw.BeginRenderPass(m_texture_encoder->GetEncodingTextureFramebuffer(), region); - draw.SetPSSampler(0, src_texture->GetView(), g_object_cache->GetPointSampler()); + draw.SetPSSampler(0, src_texture->GetView(), g_object_cache->GetLinearSampler()); draw.DrawQuad(0, 0, static_cast(output_width), static_cast(dst_height), src_rect.left, src_rect.top, 0, src_rect.GetWidth(), src_rect.GetHeight(), static_cast(src_texture->GetWidth()), From d6d33411834df82dea8e7c250925ccfe595e0cc2 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 19 Nov 2016 18:54:05 +1000 Subject: [PATCH 2/2] D3D: Fix strided XFB copies --- Source/Core/VideoBackends/D3D/FramebufferManager.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/FramebufferManager.cpp b/Source/Core/VideoBackends/D3D/FramebufferManager.cpp index 3f7ab4c528..e95b2ab70e 100644 --- a/Source/Core/VideoBackends/D3D/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/D3D/FramebufferManager.cpp @@ -275,8 +275,10 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma) { u8* dst = Memory::GetPointer(xfbAddr); - // below div2 due to dx using pixel width - s_xfbEncoder.Encode(dst, fbStride / 2, fbHeight, sourceRc, Gamma); + + // The destination stride can differ from the copy region width, in which case the pixels + // outside the copy region should not be written to. + s_xfbEncoder.Encode(dst, static_cast(sourceRc.GetWidth()), fbHeight, sourceRc, Gamma); } std::unique_ptr FramebufferManager::CreateXFBSource(unsigned int target_width,