Merge pull request #622 from phire/sw-fix-frame-dump
Fixed Frame dumping in VideoSoftware.
This commit is contained in:
commit
51dff5a74e
|
@ -11,6 +11,7 @@
|
||||||
#include "VideoBackends/Software/EfbInterface.h"
|
#include "VideoBackends/Software/EfbInterface.h"
|
||||||
#include "VideoBackends/Software/HwRasterizer.h"
|
#include "VideoBackends/Software/HwRasterizer.h"
|
||||||
#include "VideoBackends/Software/SWCommandProcessor.h"
|
#include "VideoBackends/Software/SWCommandProcessor.h"
|
||||||
|
#include "VideoBackends/Software/SWRenderer.h"
|
||||||
#include "VideoBackends/Software/SWStatistics.h"
|
#include "VideoBackends/Software/SWStatistics.h"
|
||||||
#include "VideoBackends/Software/SWVideoConfig.h"
|
#include "VideoBackends/Software/SWVideoConfig.h"
|
||||||
#include "VideoBackends/Software/TextureSampler.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);
|
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;
|
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;
|
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];
|
TextureToPng(SWRenderer::getCurrentColorTexture(), width * 4, filename, width, height, true);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name)
|
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(),
|
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
|
||||||
swstats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]);
|
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));
|
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_bSkipCurrentFrame)
|
||||||
{
|
{
|
||||||
if (g_SWVideoConfig.bDumpFrames)
|
if (g_SWVideoConfig.bDumpFrames)
|
||||||
{
|
{
|
||||||
DumpEfb(StringFromFormat("%sframe%i_color.png",
|
DumpColorTexture(StringFromFormat("%sframe%i_color.png",
|
||||||
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount));
|
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount), width, height);
|
||||||
DumpDepth(StringFromFormat("%sframe%i_depth.png",
|
|
||||||
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace DebugUtil
|
||||||
void OnObjectBegin();
|
void OnObjectBegin();
|
||||||
void OnObjectEnd();
|
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);
|
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace EfbCopy
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Ask SWRenderer for the next color texture
|
// Ask SWRenderer for the next color texture
|
||||||
u8 *colorTexture = SWRenderer::getColorTexture();
|
u8 *colorTexture = SWRenderer::getNextColorTexture();
|
||||||
|
|
||||||
EfbInterface::BypassXFB(colorTexture, fbWidth, fbHeight, sourceRc, Gamma);
|
EfbInterface::BypassXFB(colorTexture, fbWidth, fbHeight, sourceRc, Gamma);
|
||||||
|
|
||||||
|
|
|
@ -152,10 +152,14 @@ void SWRenderer::DrawDebugText()
|
||||||
SWRenderer::RenderText(debugtext.c_str(), 20, 20, 0xFFFFFF00);
|
SWRenderer::RenderText(debugtext.c_str(), 20, 20, 0xFFFFFF00);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* SWRenderer::getColorTexture() {
|
u8* SWRenderer::getNextColorTexture() {
|
||||||
return s_xfbColorTexture[!s_currentColorTexture];
|
return s_xfbColorTexture[!s_currentColorTexture];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8* SWRenderer::getCurrentColorTexture() {
|
||||||
|
return s_xfbColorTexture[s_currentColorTexture];
|
||||||
|
}
|
||||||
|
|
||||||
void SWRenderer::swapColorTexture() {
|
void SWRenderer::swapColorTexture() {
|
||||||
s_currentColorTexture = !s_currentColorTexture;
|
s_currentColorTexture = !s_currentColorTexture;
|
||||||
}
|
}
|
||||||
|
@ -168,7 +172,7 @@ void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidt
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 offset = 0;
|
u32 offset = 0;
|
||||||
u8 *TexturePointer = getColorTexture();
|
u8 *TexturePointer = getNextColorTexture();
|
||||||
|
|
||||||
for (u16 y = 0; y < fbHeight; y++)
|
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
|
GLInterface->Update(); // just updates the render window position and the backbuffer size
|
||||||
if (!g_SWVideoConfig.bHwRasterizer)
|
if (!g_SWVideoConfig.bHwRasterizer)
|
||||||
SWRenderer::DrawTexture(s_xfbColorTexture[s_currentColorTexture], fbWidth, fbHeight);
|
SWRenderer::DrawTexture(getCurrentColorTexture(), fbWidth, fbHeight);
|
||||||
|
|
||||||
swstats.frameCount++;
|
swstats.frameCount++;
|
||||||
SWRenderer::SwapBuffer();
|
SWRenderer::SwapBuffer();
|
||||||
|
|
|
@ -18,7 +18,8 @@ namespace SWRenderer
|
||||||
void RenderText(const char* pstr, int left, int top, u32 color);
|
void RenderText(const char* pstr, int left, int top, u32 color);
|
||||||
void DrawDebugText();
|
void DrawDebugText();
|
||||||
|
|
||||||
u8* getColorTexture();
|
u8* getNextColorTexture();
|
||||||
|
u8* getCurrentColorTexture();
|
||||||
void swapColorTexture();
|
void swapColorTexture();
|
||||||
void UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidth, u32 fbHeight);
|
void UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidth, u32 fbHeight);
|
||||||
void DrawTexture(u8 *texture, int width, int height);
|
void DrawTexture(u8 *texture, int width, int height);
|
||||||
|
|
|
@ -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,
|
// Ideally we would just move all the OpenGL context stuff to the CPU thread,
|
||||||
// but this gets messy when the hardware rasterizer is enabled.
|
// but this gets messy when the hardware rasterizer is enabled.
|
||||||
// And neobrain loves his hardware rasterizer.
|
// And neobrain loves his hardware rasterizer.
|
||||||
|
|
Loading…
Reference in New Issue