rend/if: Logging/verification of MD5(ta command list data)
This allows for some very primitive auto-automated testing, by comparing known good frames. As this happens on the TA level, it doesn't actually require rendering (and thus it's server friendly) Two new config entries under the new [testing] namespace control behavior - ta.HashLogFile, file where data should be logged, empty if not logging - ta.HashCheckFile, past log to check against, empty if not checking The emu will crash via verify if the logs don't match, and exit(1) if they do
This commit is contained in:
parent
915d6b26d6
commit
7d951b7697
|
@ -5,10 +5,16 @@
|
|||
|
||||
#include "deps/zlib/zlib.h"
|
||||
|
||||
#include "deps/crypto/md5.h"
|
||||
|
||||
#if FEAT_HAS_NIXPROF
|
||||
#include "profiler/profiler.h"
|
||||
#endif
|
||||
|
||||
#define FRAME_MD5 0x1
|
||||
FILE* fLogFrames;
|
||||
FILE* fCheckFrames;
|
||||
|
||||
/*
|
||||
|
||||
rendv3 ideas
|
||||
|
@ -291,6 +297,48 @@ void rend_start_render()
|
|||
|
||||
if (ctx)
|
||||
{
|
||||
if (fLogFrames || fCheckFrames) {
|
||||
MD5Context md5;
|
||||
u8 digest[16];
|
||||
|
||||
MD5Init(&md5);
|
||||
MD5Update(&md5, ctx->tad.thd_root, ctx->tad.End() - ctx->tad.thd_root);
|
||||
MD5Final(digest, &md5);
|
||||
|
||||
if (fLogFrames) {
|
||||
fputc(FRAME_MD5, fLogFrames);
|
||||
fwrite(digest, 1, 16, fLogFrames);
|
||||
fflush(fLogFrames);
|
||||
}
|
||||
|
||||
if (fCheckFrames) {
|
||||
u8 v;
|
||||
u8 digest2[16];
|
||||
int ch = fgetc(fCheckFrames);
|
||||
|
||||
if (ch == EOF) {
|
||||
printf("Testing: TA Hash log matches, exiting\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
verify(ch == FRAME_MD5);
|
||||
|
||||
fread(digest2, 1, 16, fCheckFrames);
|
||||
|
||||
verify(memcmp(digest, digest2, 16) == 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
u8* dig = digest;
|
||||
printf("FRAME: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
|
||||
digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7],
|
||||
digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15]
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
if (!ctx->rend.Overrun)
|
||||
{
|
||||
//printf("REP: %.2f ms\n",render_end_pending_cycles/200000.0);
|
||||
|
@ -366,6 +414,13 @@ void rend_end_wait()
|
|||
|
||||
bool rend_init()
|
||||
{
|
||||
if (fLogFrames = fopen(settings.pvr.HashLogFile.c_str(), "wb")) {
|
||||
printf("Saving frame hashes to: '%s'\n", settings.pvr.HashLogFile.c_str());
|
||||
}
|
||||
|
||||
if (fCheckFrames = fopen(settings.pvr.HashCheckFile.c_str(), "rb")) {
|
||||
printf("Comparing frame hashes against: '%s'\n", settings.pvr.HashCheckFile.c_str());
|
||||
}
|
||||
|
||||
#ifdef NO_REND
|
||||
renderer = rend_norend();
|
||||
|
@ -435,6 +490,11 @@ bool rend_init()
|
|||
|
||||
void rend_term()
|
||||
{
|
||||
if (fCheckFrames)
|
||||
fclose(fCheckFrames);
|
||||
|
||||
if (fLogFrames)
|
||||
fclose(fLogFrames);
|
||||
}
|
||||
|
||||
void rend_vblank()
|
||||
|
|
|
@ -260,6 +260,8 @@ void LoadSettings()
|
|||
#endif
|
||||
|
||||
settings.bios.UseReios = cfgLoadInt("config", "bios.UseReios", 0);
|
||||
settings.pvr.HashLogFile = cfgLoadStr("testing", "ta.HashLogFile", "");
|
||||
settings.pvr.HashCheckFile = cfgLoadStr("testing", "ta.HashCheckFile", "");
|
||||
|
||||
#if (HOST_OS != OS_LINUX || defined(_ANDROID) || defined(TARGET_PANDORA))
|
||||
settings.aica.BufferSize=2048;
|
||||
|
|
|
@ -696,6 +696,9 @@ struct settings_t
|
|||
|
||||
u32 MaxThreads;
|
||||
u32 SynchronousRendering;
|
||||
|
||||
string HashLogFile;
|
||||
string HashCheckFile;
|
||||
} pvr;
|
||||
|
||||
struct {
|
||||
|
|
Loading…
Reference in New Issue