Video: respect stride of efb copies to xfb

This commit is contained in:
booto
2015-07-07 21:09:25 +08:00
parent 9e4dae4a03
commit 2e28ed3291
12 changed files with 42 additions and 46 deletions

View File

@ -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)

View File

@ -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
{

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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 dstSize = dst_line_size * dstHeight;
int writeStride = bpmem.copyMipMapStrideChannels * 32;
int dstSize = dstWidth*dstHeight*4;
int readHeight = readStride / dstWidth / 4; // 4 bytes per pixel
int readLoops = dstHeight / readHeight;
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();

View File

@ -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);
}