summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorbooto <remornicus@gmail.com>2015-07-07 21:09:25 +0800
committerbooto <remornicus@gmail.com>2015-07-25 01:52:12 +0800
commit2e28ed3291bc531ba5d0cd4057aa9cefdbf128be (patch)
tree670a913b5e6a6a3cddb7d325a1b3f6a51108cb08 /Source
parent9e4dae4a036fdc2f0a78e04a4215cd24c5c3ca0f (diff)
Video: respect stride of efb copies to xfb
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/VideoBackends/D3D/FramebufferManager.cpp4
-rw-r--r--Source/Core/VideoBackends/D3D/FramebufferManager.h2
-rw-r--r--Source/Core/VideoBackends/OGL/FramebufferManager.cpp4
-rw-r--r--Source/Core/VideoBackends/OGL/FramebufferManager.h2
-rw-r--r--Source/Core/VideoBackends/OGL/TextureCache.cpp3
-rw-r--r--Source/Core/VideoBackends/OGL/TextureConverter.cpp40
-rw-r--r--Source/Core/VideoBackends/OGL/TextureConverter.h4
-rw-r--r--Source/Core/VideoCommon/BPStructs.cpp7
-rw-r--r--Source/Core/VideoCommon/FramebufferManagerBase.cpp8
-rw-r--r--Source/Core/VideoCommon/FramebufferManagerBase.h4
-rw-r--r--Source/Core/VideoCommon/RenderBase.cpp8
-rw-r--r--Source/Core/VideoCommon/RenderBase.h2
12 files changed, 42 insertions, 46 deletions
diff --git a/Source/Core/VideoBackends/D3D/FramebufferManager.cpp b/Source/Core/VideoBackends/D3D/FramebufferManager.cpp
index 03cea928f0..85fa9a122c 100644
--- a/Source/Core/VideoBackends/D3D/FramebufferManager.cpp
+++ b/Source/Core/VideoBackends/D3D/FramebufferManager.cpp
@@ -159,10 +159,10 @@ FramebufferManager::~FramebufferManager()
SAFE_RELEASE(m_efb.resolved_depth_tex);
}
-void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
+void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
{
u8* dst = Memory::GetPointer(xfbAddr);
- s_xfbEncoder.Encode(dst, fbWidth, fbHeight, sourceRc, Gamma);
+ s_xfbEncoder.Encode(dst, fbStride, fbHeight, sourceRc, Gamma);
}
XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers)
diff --git a/Source/Core/VideoBackends/D3D/FramebufferManager.h b/Source/Core/VideoBackends/D3D/FramebufferManager.h
index 11ee646b4c..9151c7ef56 100644
--- a/Source/Core/VideoBackends/D3D/FramebufferManager.h
+++ b/Source/Core/VideoBackends/D3D/FramebufferManager.h
@@ -83,7 +83,7 @@ private:
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers) override;
void GetTargetSize(unsigned int *width, unsigned int *height) override;
- void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma) override;
+ void CopyToRealXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma) override;
static struct Efb
{
diff --git a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp
index 3fee033c57..a4489a67ff 100644
--- a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp
+++ b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp
@@ -481,7 +481,7 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc)
}
}
-void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
+void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
{
u8* xfb_in_ram = Memory::GetPointer(xfbAddr);
if (!xfb_in_ram)
@@ -491,7 +491,7 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c
}
TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc);
- TextureConverter::EncodeToRamYUYV(ResolveAndGetRenderTarget(sourceRc), targetRc, xfb_in_ram, fbWidth, fbHeight);
+ TextureConverter::EncodeToRamYUYV(ResolveAndGetRenderTarget(sourceRc), targetRc, xfb_in_ram, sourceRc.GetWidth(), fbStride, fbHeight);
}
void FramebufferManager::SetFramebuffer(GLuint fb)
diff --git a/Source/Core/VideoBackends/OGL/FramebufferManager.h b/Source/Core/VideoBackends/OGL/FramebufferManager.h
index bf04b41536..d0aa6a2c18 100644
--- a/Source/Core/VideoBackends/OGL/FramebufferManager.h
+++ b/Source/Core/VideoBackends/OGL/FramebufferManager.h
@@ -97,7 +97,7 @@ private:
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers) override;
void GetTargetSize(unsigned int *width, unsigned int *height) override;
- void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma) override;
+ void CopyToRealXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma) override;
static int m_targetWidth;
static int m_targetHeight;
diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp
index ebc3a672f1..92f2b8a788 100644
--- a/Source/Core/VideoBackends/OGL/TextureCache.cpp
+++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp
@@ -269,7 +269,8 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
isIntensity,
dstFormat,
scaleByHalf,
- srcRect);
+ srcRect,
+ copyMipMapStrideChannels * 32);
u8* dst = Memory::GetPointer(dstAddr);
u64 const new_hash = GetHash64(dst,encoded_size,g_ActiveConfig.iSafeTextureCache_ColorSamples);
diff --git a/Source/Core/VideoBackends/OGL/TextureConverter.cpp b/Source/Core/VideoBackends/OGL/TextureConverter.cpp
index c696ccf687..c25d30d088 100644
--- a/Source/Core/VideoBackends/OGL/TextureConverter.cpp
+++ b/Source/Core/VideoBackends/OGL/TextureConverter.cpp
@@ -213,12 +213,12 @@ void Shutdown()
s_texConvFrameBuffer[1] = 0;
}
+// dst_line_size, writeStride in bytes
+
static void EncodeToRamUsingShader(GLuint srcTexture,
- u8* destAddr, int dstWidth, int dstHeight, int readStride,
- bool linearFilter)
+ u8* destAddr, u32 dst_line_size, u32 dstHeight,
+ u32 writeStride, bool linearFilter)
{
-
-
// switch to texture converter frame buffer
// attach render buffer as color destination
FramebufferManager::SetFramebuffer(s_texConvFrameBuffer[0]);
@@ -234,19 +234,13 @@ static void EncodeToRamUsingShader(GLuint srcTexture,
else
g_sampler_cache->BindNearestSampler(9);
- glViewport(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight);
+ glViewport(0, 0, (GLsizei)(dst_line_size / 4), (GLsizei)dstHeight);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- // .. and then read back the results.
- // TODO: make this less slow.
-
- int writeStride = bpmem.copyMipMapStrideChannels * 32;
- int dstSize = dstWidth*dstHeight*4;
- int readHeight = readStride / dstWidth / 4; // 4 bytes per pixel
- int readLoops = dstHeight / readHeight;
+ int dstSize = dst_line_size * dstHeight;
- if (writeStride != readStride && readLoops > 1)
+ if ((writeStride != dst_line_size) && (dstHeight > 1))
{
// writing to a texture of a different size
// also copy more then one block line, so the different strides matters
@@ -255,13 +249,13 @@ static void EncodeToRamUsingShader(GLuint srcTexture,
// CPU overhead because of the pbo
glBindBuffer(GL_PIXEL_PACK_BUFFER, s_PBO);
glBufferData(GL_PIXEL_PACK_BUFFER, dstSize, nullptr, GL_STREAM_READ);
- glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
+ glReadPixels(0, 0, (GLsizei)(dst_line_size / 4), (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
u8* pbo = (u8*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, dstSize, GL_MAP_READ_BIT);
- for (int i = 0; i < readLoops; i++)
+ for (size_t i = 0; i < dstHeight; ++i)
{
- memcpy(destAddr, pbo, readStride);
- pbo += readStride;
+ memcpy(destAddr, pbo, dst_line_size);
+ pbo += dst_line_size;
destAddr += writeStride;
}
@@ -270,11 +264,11 @@ static void EncodeToRamUsingShader(GLuint srcTexture,
}
else
{
- glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
+ glReadPixels(0, 0, (GLsizei)(dst_line_size / 4), (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
}
}
-int EncodeToRamFromTexture(u32 address,GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
+int EncodeToRamFromTexture(u32 address,GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source, u32 writeStride)
{
u32 format = copyfmt;
@@ -323,13 +317,13 @@ int EncodeToRamFromTexture(u32 address,GLuint source_texture, bool bFromZBuffer,
cacheLinesPerRow = numBlocksX;
EncodeToRamUsingShader(source_texture,
- dest_ptr, cacheLinesPerRow * 8, numBlocksY, cacheLinesPerRow * 32,
- bScaleByHalf > 0 && !bFromZBuffer);
+ dest_ptr, cacheLinesPerRow * 32, numBlocksY,
+ writeStride, bScaleByHalf > 0 && !bFromZBuffer);
return size_in_bytes; // TODO: D3D11 is calculating this value differently!
}
-void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight)
+void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, u32 dstWidth, u32 dstStride, u32 dstHeight)
{
g_renderer->ResetAPIState();
@@ -341,7 +335,7 @@ void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* des
// We enable linear filtering, because the GameCube does filtering in the vertical direction when
// yscale is enabled.
// Otherwise we get jaggies when a game uses yscaling (most PAL games)
- EncodeToRamUsingShader(srcTexture, destAddr, dstWidth / 2, dstHeight, dstWidth*dstHeight*2, true);
+ EncodeToRamUsingShader(srcTexture, destAddr, dstWidth * 2, dstHeight, dstStride * 2, true);
FramebufferManager::SetFramebuffer(0);
TextureCache::DisableStage(0);
g_renderer->RestoreAPIState();
diff --git a/Source/Core/VideoBackends/OGL/TextureConverter.h b/Source/Core/VideoBackends/OGL/TextureConverter.h
index e0c6cbd5fb..c41dfe10ac 100644
--- a/Source/Core/VideoBackends/OGL/TextureConverter.h
+++ b/Source/Core/VideoBackends/OGL/TextureConverter.h
@@ -19,12 +19,12 @@ void Init();
void Shutdown();
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
- u8* destAddr, int dstWidth, int dstHeight);
+ u8* destAddr, u32 dstWidth, u32 dstStride, u32 dstHeight);
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture);
// returns size of the encoded data (in bytes)
-int EncodeToRamFromTexture(u32 address, GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
+int EncodeToRamFromTexture(u32 address, GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source, u32 writeStride);
}
diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp
index 410d4d44cc..92ab0bf63f 100644
--- a/Source/Core/VideoCommon/BPStructs.cpp
+++ b/Source/Core/VideoCommon/BPStructs.cpp
@@ -251,9 +251,10 @@ static void BPWritten(const BPCmd& bp)
height = MAX_XFB_HEIGHT;
}
- u32 width = bpmem.copyMipMapStrideChannels << 4;
-
- Renderer::RenderToXFB(destAddr, srcRect, width, height, s_gammaLUT[PE_copy.gamma]);
+ u32 stride = bpmem.copyMipMapStrideChannels << 4;
+ WARN_LOG(VIDEO, "RenderToXFB: destAddr: %08x | srcRect {%d %d %d %d} | fbWidth: %u | fbStride: %u | fbHeight: %u",
+ destAddr, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom, bpmem.copyTexSrcWH.x + 1, stride, height);
+ Renderer::RenderToXFB(destAddr, srcRect, stride, height, s_gammaLUT[PE_copy.gamma]);
}
// Clear the rectangular region after copying it.
diff --git a/Source/Core/VideoCommon/FramebufferManagerBase.cpp b/Source/Core/VideoCommon/FramebufferManagerBase.cpp
index 10d1cfa414..711b117ef6 100644
--- a/Source/Core/VideoCommon/FramebufferManagerBase.cpp
+++ b/Source/Core/VideoCommon/FramebufferManagerBase.cpp
@@ -115,15 +115,15 @@ const XFBSourceBase* const* FramebufferManagerBase::GetVirtualXFBSource(u32 xfbA
return &m_overlappingXFBArray[0];
}
-void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
+void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma)
{
if (g_ActiveConfig.bUseRealXFB)
- g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc,Gamma);
+ g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma);
else
- CopyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc,Gamma);
+ CopyToVirtualXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma);
}
-void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
+void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma)
{
VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, fbWidth, fbHeight);
diff --git a/Source/Core/VideoCommon/FramebufferManagerBase.h b/Source/Core/VideoCommon/FramebufferManagerBase.h
index bd6360877c..6127037268 100644
--- a/Source/Core/VideoCommon/FramebufferManagerBase.h
+++ b/Source/Core/VideoCommon/FramebufferManagerBase.h
@@ -45,7 +45,7 @@ public:
FramebufferManagerBase();
virtual ~FramebufferManagerBase();
- static void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma);
+ static void CopyToXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma);
static const XFBSourceBase* const* GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32* xfbCount);
static void SetLastXfbWidth(unsigned int width) { s_last_xfb_width = width; }
@@ -87,7 +87,7 @@ private:
static void ReplaceVirtualXFB();
// TODO: merge these virtual funcs, they are nearly all the same
- virtual void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma = 1.0f) = 0;
+ virtual void CopyToRealXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma = 1.0f) = 0;
static void CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma = 1.0f);
static const XFBSourceBase* const* GetRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32* xfbCount);
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp
index a688c86792..cd98f5dbf0 100644
--- a/Source/Core/VideoCommon/RenderBase.cpp
+++ b/Source/Core/VideoCommon/RenderBase.cpp
@@ -112,22 +112,22 @@ Renderer::~Renderer()
#endif
}
-void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbWidth, u32 fbHeight, float Gamma)
+void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStride, u32 fbHeight, float Gamma)
{
CheckFifoRecording();
- if (!fbWidth || !fbHeight)
+ if (!fbStride || !fbHeight)
return;
XFBWrited = true;
if (g_ActiveConfig.bUseXFB)
{
- FramebufferManagerBase::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc, Gamma);
+ FramebufferManagerBase::CopyToXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma);
}
else
{
- Swap(xfbAddr, fbWidth, fbWidth, fbHeight, sourceRc, Gamma);
+ Swap(xfbAddr, sourceRc.GetWidth(), fbStride, fbHeight, sourceRc, Gamma);
}
}
diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h
index a17525ca2e..c717483d1e 100644
--- a/Source/Core/VideoCommon/RenderBase.h
+++ b/Source/Core/VideoCommon/RenderBase.h
@@ -109,7 +109,7 @@ public:
virtual void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) = 0;
virtual void ReinterpretPixelData(unsigned int convtype) = 0;
- static void RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbWidth, u32 fbHeight, float Gamma = 1.0f);
+ static void RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStride, u32 fbHeight, float Gamma = 1.0f);
virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) = 0;
virtual void PokeEFB(EFBAccessType type, const std::vector<EfbPokeData>& data);