From 79387dddb24ddf035b70cd9379a42368dcd49e93 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Mon, 29 May 2017 17:02:09 -0500 Subject: Add support for hybrid XFB --- .../Core/VideoBackends/Software/EfbInterface.cpp | 34 ++++------------------ 1 file changed, 5 insertions(+), 29 deletions(-) (limited to 'Source/Core/VideoBackends/Software/EfbInterface.cpp') diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp index 9f6af90c0d..411839c852 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.cpp +++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp @@ -520,15 +520,6 @@ void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRe // Scanline buffer, leave room for borders yuv444 scanline[EFB_WIDTH + 2]; - // our internal yuv444 type is not normalized, so black is {0, 0, 0} instead of {16, 128, 128} - yuv444 black; - black.Y = 0; - black.U = 0; - black.V = 0; - - scanline[0] = black; // black border at start - scanline[right + 1] = black; // black border at end - for (u16 y = sourceRc.top; y < sourceRc.bottom; y++) { // Get a scanline of YUV pixels in 4:4:4 format @@ -538,6 +529,10 @@ void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRe scanline[i] = GetColorYUV(x, y); } + // Flipper clamps the border colors + scanline[0] = scanline[1]; + scanline[right + 1] = scanline[right]; + // And Downsample them to 4:2:2 for (int i = 1, x = left; x < right; i += 2, x += 2) { @@ -562,26 +557,7 @@ void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRe // main memory or doing a yuyv conversion void BypassXFB(u8* texture, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma) { - if (fbWidth * fbHeight > MAX_XFB_WIDTH * MAX_XFB_HEIGHT) - { - ERROR_LOG(VIDEO, "Framebuffer is too large: %ix%i", fbWidth, fbHeight); - return; - } - - size_t textureAddress = 0; - const int left = sourceRc.left; - const int right = sourceRc.right; - - for (u16 y = sourceRc.top; y < sourceRc.bottom; y++) - { - for (u16 x = left; x < right; x++) - { - const u32 color = Common::swap32(GetColor(x, y) | 0xFF); - - std::memcpy(&texture[textureAddress], &color, sizeof(u32)); - textureAddress += sizeof(u32); - } - } + // TODO: Upload directly to texture cache. } bool ZCompare(u16 x, u16 y, u32 z) -- cgit v1.2.3 From 4d13f69dc146bff6e9f1debf4f51d38e6b1e19db Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 6 Aug 2017 23:06:03 -0500 Subject: Remove TODOs --- Source/Core/VideoBackends/Software/EfbInterface.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'Source/Core/VideoBackends/Software/EfbInterface.cpp') diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp index 411839c852..d80bd02f5b 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.cpp +++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp @@ -553,13 +553,6 @@ void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRe } } -// Like CopyToXFB, but we copy directly into the OpenGL color texture without going via GameCube -// main memory or doing a yuyv conversion -void BypassXFB(u8* texture, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma) -{ - // TODO: Upload directly to texture cache. -} - bool ZCompare(u16 x, u16 y, u32 z) { u32 offset = GetDepthOffset(x, y); -- cgit v1.2.3 From 6e686f6ea10c486a6271a6ca7cd084e124776b5a Mon Sep 17 00:00:00 2001 From: iwubcode Date: Wed, 23 Aug 2017 21:46:23 -0500 Subject: Software Backend: Fix xfb output and add vertical scaling support --- .../Core/VideoBackends/Software/EfbInterface.cpp | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'Source/Core/VideoBackends/Software/EfbInterface.cpp') diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp index d80bd02f5b..2ca20b3997 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.cpp +++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp @@ -7,11 +7,13 @@ #include #include #include +#include #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" #include "Common/Swap.h" +#include "VideoBackends/Software/CopyRegion.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/LookUpTables.h" #include "VideoCommon/PerfQueryBase.h" @@ -495,19 +497,16 @@ u8* GetPixelPointer(u16 x, u16 y, bool depth) return &efb[GetColorOffset(x, y)]; } -void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, - float Gamma) +void EncodeXFB(yuv422_packed* xfb_in_ram, u32 memory_stride, const EFBRectangle& source_rect, float y_scale) { - // FIXME: We should do Gamma correction - if (!xfb_in_ram) { WARN_LOG(VIDEO, "Tried to copy to invalid XFB address"); return; } - int left = sourceRc.left; - int right = sourceRc.right; + int left = source_rect.left; + int right = source_rect.right; // this assumes copies will always start on an even (YU) pixel and the // copy always has an even width, which might not be true. @@ -520,7 +519,11 @@ void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRe // Scanline buffer, leave room for borders yuv444 scanline[EFB_WIDTH + 2]; - for (u16 y = sourceRc.top; y < sourceRc.bottom; y++) + static std::vector source; + source.resize(EFB_WIDTH * EFB_HEIGHT); + yuv422_packed* src_ptr = &source[0]; + + for (float y = source_rect.top; y < source_rect.bottom; y++) { // Get a scanline of YUV pixels in 4:4:4 format @@ -537,20 +540,23 @@ void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRe for (int i = 1, x = left; x < right; i += 2, x += 2) { // YU pixel - xfb_in_ram[x].Y = scanline[i].Y + 16; + src_ptr[x].Y = scanline[i].Y + 16; // we mix our color differences in 10 bit space so it will round more accurately // U[i] = 1/4 * U[i-1] + 1/2 * U[i] + 1/4 * U[i+1] - xfb_in_ram[x].UV = + src_ptr[x].UV = 128 + ((scanline[i - 1].U + (scanline[i].U << 1) + scanline[i + 1].U) >> 2); // YV pixel - xfb_in_ram[x + 1].Y = scanline[i + 1].Y + 16; + src_ptr[x + 1].Y = scanline[i + 1].Y + 16; // V[i] = 1/4 * V[i-1] + 1/2 * V[i] + 1/4 * V[i+1] - xfb_in_ram[x + 1].UV = + src_ptr[x + 1].UV = 128 + ((scanline[i].V + (scanline[i + 1].V << 1) + scanline[i + 2].V) >> 2); } - xfb_in_ram += fbWidth; + src_ptr += memory_stride; } + + // Apply y scaling and copy to the xfb memory location + SW::copy_region(source.data(), source_rect, xfb_in_ram, EFBRectangle{ source_rect.left, source_rect.top, source_rect.right, static_cast(static_cast(source_rect.bottom) * y_scale) }); } bool ZCompare(u16 x, u16 y, u32 z) -- cgit v1.2.3 From 53684701fa1f9a787f8d089d864c5c1c97effa8c Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 2 Sep 2017 21:30:34 -0500 Subject: HybridXFB: Fix lint errors --- Source/Core/VideoBackends/Software/EfbInterface.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'Source/Core/VideoBackends/Software/EfbInterface.cpp') diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp index 2ca20b3997..e667a7e584 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.cpp +++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp @@ -497,7 +497,8 @@ u8* GetPixelPointer(u16 x, u16 y, bool depth) return &efb[GetColorOffset(x, y)]; } -void EncodeXFB(yuv422_packed* xfb_in_ram, u32 memory_stride, const EFBRectangle& source_rect, float y_scale) +void EncodeXFB(yuv422_packed* xfb_in_ram, u32 memory_stride, const EFBRectangle& source_rect, + float y_scale) { if (!xfb_in_ram) { @@ -543,8 +544,7 @@ void EncodeXFB(yuv422_packed* xfb_in_ram, u32 memory_stride, const EFBRectangle& src_ptr[x].Y = scanline[i].Y + 16; // we mix our color differences in 10 bit space so it will round more accurately // U[i] = 1/4 * U[i-1] + 1/2 * U[i] + 1/4 * U[i+1] - src_ptr[x].UV = - 128 + ((scanline[i - 1].U + (scanline[i].U << 1) + scanline[i + 1].U) >> 2); + src_ptr[x].UV = 128 + ((scanline[i - 1].U + (scanline[i].U << 1) + scanline[i + 1].U) >> 2); // YV pixel src_ptr[x + 1].Y = scanline[i + 1].Y + 16; @@ -556,7 +556,9 @@ void EncodeXFB(yuv422_packed* xfb_in_ram, u32 memory_stride, const EFBRectangle& } // Apply y scaling and copy to the xfb memory location - SW::copy_region(source.data(), source_rect, xfb_in_ram, EFBRectangle{ source_rect.left, source_rect.top, source_rect.right, static_cast(static_cast(source_rect.bottom) * y_scale) }); + SW::copy_region(source.data(), source_rect, xfb_in_ram, + EFBRectangle{source_rect.left, source_rect.top, source_rect.right, + static_cast(static_cast(source_rect.bottom) * y_scale)}); } bool ZCompare(u16 x, u16 y, u32 z) -- cgit v1.2.3 From 1a1c3560ceb9c6d1db7b460e843998d504871bb1 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Mon, 2 Oct 2017 00:33:47 -0500 Subject: Software Backend: Rename 'copy_region' to 'CopyRegion' --- Source/Core/VideoBackends/Software/EfbInterface.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoBackends/Software/EfbInterface.cpp') diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp index e667a7e584..55462ce33f 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.cpp +++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp @@ -556,9 +556,9 @@ void EncodeXFB(yuv422_packed* xfb_in_ram, u32 memory_stride, const EFBRectangle& } // Apply y scaling and copy to the xfb memory location - SW::copy_region(source.data(), source_rect, xfb_in_ram, - EFBRectangle{source_rect.left, source_rect.top, source_rect.right, - static_cast(static_cast(source_rect.bottom) * y_scale)}); + SW::CopyRegion(source.data(), source_rect, xfb_in_ram, + EFBRectangle{source_rect.left, source_rect.top, source_rect.right, + static_cast(static_cast(source_rect.bottom) * y_scale)}); } bool ZCompare(u16 x, u16 y, u32 z) -- cgit v1.2.3 From bf7db3f88835d3b69800c9ed5596e31c7ba96346 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Tue, 24 Oct 2017 00:44:14 -0500 Subject: Software Backend: Remove reinterpret_cast which violates the strict aliasing rule --- Source/Core/VideoBackends/Software/EfbInterface.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'Source/Core/VideoBackends/Software/EfbInterface.cpp') diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp index 55462ce33f..a94ac467b8 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.cpp +++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp @@ -497,8 +497,7 @@ u8* GetPixelPointer(u16 x, u16 y, bool depth) return &efb[GetColorOffset(x, y)]; } -void EncodeXFB(yuv422_packed* xfb_in_ram, u32 memory_stride, const EFBRectangle& source_rect, - float y_scale) +void EncodeXFB(u8* xfb_in_ram, u32 memory_stride, const EFBRectangle& source_rect, float y_scale) { if (!xfb_in_ram) { @@ -555,10 +554,16 @@ void EncodeXFB(yuv422_packed* xfb_in_ram, u32 memory_stride, const EFBRectangle& src_ptr += memory_stride; } - // Apply y scaling and copy to the xfb memory location - SW::CopyRegion(source.data(), source_rect, xfb_in_ram, - EFBRectangle{source_rect.left, source_rect.top, source_rect.right, - static_cast(static_cast(source_rect.bottom) * y_scale)}); + auto dest_rect = EFBRectangle{source_rect.left, source_rect.top, source_rect.right, + static_cast(static_cast(source_rect.bottom) * y_scale)}; + + const std::size_t destination_size = dest_rect.GetWidth() * dest_rect.GetHeight() * 2; + static std::vector destination; + destination.resize(dest_rect.GetWidth() * dest_rect.GetHeight()); + + SW::CopyRegion(source.data(), source_rect, destination.data(), dest_rect); + + memcpy(xfb_in_ram, destination.data(), destination_size); } bool ZCompare(u16 x, u16 y, u32 z) -- cgit v1.2.3