Fixed Frame dumping in VideoSoftware.

Old code dumped the efb, which was no-longer relevant since the
backend gained xfb support.
New code dumps the colour texture which is about to be rendered to
the screen so correctly reflects the bypassXFB option.
This commit is contained in:
Scott Mansell 2014-07-14 23:51:55 +12:00
parent 3ac4e9f171
commit 92eed47213
6 changed files with 26 additions and 33 deletions

View file

@ -11,6 +11,7 @@
#include "VideoBackends/Software/EfbInterface.h"
#include "VideoBackends/Software/HwRasterizer.h"
#include "VideoBackends/Software/SWCommandProcessor.h"
#include "VideoBackends/Software/SWRenderer.h"
#include "VideoBackends/Software/SWStatistics.h"
#include "VideoBackends/Software/SWVideoConfig.h"
#include "VideoBackends/Software/TextureSampler.h"
@ -66,7 +67,7 @@ static void SaveTexture(const std::string& filename, u32 texmap, s32 mip)
GetTextureRGBA(data, texmap, mip, width, height);
(void)TextureToPng(data, width*4, filename, width, height, true);
TextureToPng(data, width*4, filename, width, height, true);
delete[] data;
}
@ -150,30 +151,15 @@ static void DumpEfb(const std::string& filename)
}
}
(void)TextureToPng(data, EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true);
TextureToPng(data, EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true);
delete[] data;
}
static void DumpDepth(const std::string& filename)
static void DumpColorTexture(const std::string& filename, u32 width, u32 height)
{
u8 *data = new u8[EFB_WIDTH * EFB_HEIGHT * 4];
u8 *writePtr = data;
for (int y = 0; y < EFB_HEIGHT; y++)
{
for (int x = 0; x < EFB_WIDTH; x++)
{
u32 depth = EfbInterface::GetDepth(x, y);
// depth to rgba
*(writePtr++) = depth & 0xff;
*(writePtr++) = (depth >> 8) & 0xff;
*(writePtr++) = (depth >> 16) & 0xff;
*(writePtr++) = 255;
}
}
(void)TextureToPng(data, EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true);
delete[] data;
TextureToPng(SWRenderer::getCurrentColorTexture(), width * 4, filename, width, height, true);
}
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name)
@ -252,7 +238,7 @@ void OnObjectEnd()
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
swstats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]);
(void)TextureToPng((u8*)ObjectBuffer[i], EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true);
TextureToPng((u8*)ObjectBuffer[i], EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true);
memset(ObjectBuffer[i], 0, EFB_WIDTH * EFB_HEIGHT * sizeof(u32));
}
@ -262,16 +248,15 @@ void OnObjectEnd()
}
}
void OnFrameEnd()
// If frame dumping is enabled, dump whatever is drawn to the screen.
void OnFrameEnd(u32 width, u32 height)
{
if (!g_bSkipCurrentFrame)
{
if (g_SWVideoConfig.bDumpFrames)
{
DumpEfb(StringFromFormat("%sframe%i_color.png",
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount));
DumpDepth(StringFromFormat("%sframe%i_depth.png",
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount));
DumpColorTexture(StringFromFormat("%sframe%i_color.png",
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount), width, height);
}
}
}

View file

@ -16,7 +16,7 @@ namespace DebugUtil
void OnObjectBegin();
void OnObjectEnd();
void OnFrameEnd();
void OnFrameEnd(u32 width, u32 height);
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name);

View file

@ -44,7 +44,7 @@ namespace EfbCopy
else
{
// Ask SWRenderer for the next color texture
u8 *colorTexture = SWRenderer::getColorTexture();
u8 *colorTexture = SWRenderer::getNextColorTexture();
EfbInterface::BypassXFB(colorTexture, fbWidth, fbHeight, sourceRc, Gamma);

View file

@ -152,10 +152,14 @@ void SWRenderer::DrawDebugText()
SWRenderer::RenderText(debugtext.c_str(), 20, 20, 0xFFFFFF00);
}
u8* SWRenderer::getColorTexture() {
u8* SWRenderer::getNextColorTexture() {
return s_xfbColorTexture[!s_currentColorTexture];
}
u8* SWRenderer::getCurrentColorTexture() {
return s_xfbColorTexture[s_currentColorTexture];
}
void SWRenderer::swapColorTexture() {
s_currentColorTexture = !s_currentColorTexture;
}
@ -168,7 +172,7 @@ void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidt
}
u32 offset = 0;
u8 *TexturePointer = getColorTexture();
u8 *TexturePointer = getNextColorTexture();
for (u16 y = 0; y < fbHeight; y++)
{
@ -202,7 +206,7 @@ void SWRenderer::Swap(u32 fbWidth, u32 fbHeight)
{
GLInterface->Update(); // just updates the render window position and the backbuffer size
if (!g_SWVideoConfig.bHwRasterizer)
SWRenderer::DrawTexture(s_xfbColorTexture[s_currentColorTexture], fbWidth, fbHeight);
SWRenderer::DrawTexture(getCurrentColorTexture(), fbWidth, fbHeight);
swstats.frameCount++;
SWRenderer::SwapBuffer();

View file

@ -18,7 +18,8 @@ namespace SWRenderer
void RenderText(const char* pstr, int left, int top, u32 color);
void DrawDebugText();
u8* getColorTexture();
u8* getNextColorTexture();
u8* getCurrentColorTexture();
void swapColorTexture();
void UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidth, u32 fbHeight);
void DrawTexture(u8 *texture, int width, int height);

View file

@ -232,6 +232,9 @@ void VideoSoftware::Video_EndField()
}
}
// Dump frame if needed
DebugUtil::OnFrameEnd(s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight);
// Ideally we would just move all the OpenGL context stuff to the CPU thread,
// but this gets messy when the hardware rasterizer is enabled.
// And neobrain loves his hardware rasterizer.