fixed some graphics problems with loading savestates (for example, wrong colors on title screen of metroid prime 3)

This commit is contained in:
nitsuja 2012-01-01 12:46:02 -08:00 committed by skidau
parent 19b0b02ad7
commit 2be579e8ba
10 changed files with 107 additions and 58 deletions

View File

@ -39,7 +39,7 @@ void FlushPipeline()
VertexManager::Flush();
}
void SetGenerationMode(const BPCmd &bp)
void SetGenerationMode()
{
g_renderer->SetGenerationMode();
}
@ -64,30 +64,30 @@ void SetScissor()
g_renderer->SetScissorRect(trc);
}
void SetLineWidth(const BPCmd &bp)
void SetLineWidth()
{
g_renderer->SetLineWidth();
}
void SetDepthMode(const BPCmd &bp)
void SetDepthMode()
{
g_renderer->SetDepthMode();
}
void SetBlendMode(const BPCmd &bp)
void SetBlendMode()
{
g_renderer->SetBlendMode(false);
}
void SetDitherMode(const BPCmd &bp)
void SetDitherMode()
{
g_renderer->SetDitherMode();
}
void SetLogicOpMode(const BPCmd &bp)
void SetLogicOpMode()
{
g_renderer->SetLogicOpMode();
}
void SetColorMask(const BPCmd &bp)
void SetColorMask()
{
g_renderer->SetColorMask();
}
@ -119,7 +119,7 @@ void CopyEFB(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
- convert the RGBA8 color to RGBA6/RGB8/RGB565 and convert it to RGBA8 again
- convert the Z24 depth value to Z16 and back to Z24
*/
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
void ClearScreen(const EFBRectangle &rc)
{
bool colorEnable = bpmem.blendmode.colorupdate;
bool alphaEnable = bpmem.blendmode.alphaupdate;
@ -152,7 +152,7 @@ void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
}
}
void OnPixelFormatChange(const BPCmd &bp)
void OnPixelFormatChange()
{
int convtype = -1;

View File

@ -37,18 +37,18 @@ enum
};
void FlushPipeline();
void SetGenerationMode(const BPCmd &bp);
void SetGenerationMode();
void SetScissor();
void SetLineWidth(const BPCmd &bp);
void SetDepthMode(const BPCmd &bp);
void SetBlendMode(const BPCmd &bp);
void SetDitherMode(const BPCmd &bp);
void SetLogicOpMode(const BPCmd &bp);
void SetColorMask(const BPCmd &bp);
void SetLineWidth();
void SetDepthMode();
void SetBlendMode();
void SetDitherMode();
void SetLogicOpMode();
void SetColorMask();
void CopyEFB(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc);
void OnPixelFormatChange(const BPCmd &bp);
void ClearScreen(const EFBRectangle &rc);
void OnPixelFormatChange();
u8 *GetPointer(const u32 &address);
bool GetConfig(const int &type);
void SetTextureMode(const BPCmd &bp);

View File

@ -43,31 +43,6 @@ void LoadBPReg(u32 value0)
BPWritten(bp);
}
// Called when loading a saved state.
// Needs more testing though.
void BPReload()
{
for (int i = 0; i < 254; i++)
{
switch (i)
{
case BPMEM_BLENDMODE:
case BPMEM_SETDRAWDONE:
case BPMEM_TRIGGER_EFB_COPY:
case BPMEM_LOADTLUT1:
case BPMEM_PERF1:
case BPMEM_PE_TOKEN_ID:
case BPMEM_PE_TOKEN_INT_ID:
// Cases in which we DON'T want to reload the BP
continue;
default:
BPCmd bp = {i, 0xFFFFFF, static_cast<int>(((u32*)&bpmem)[i])};
BPWritten(bp);
}
}
}
void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size_t desc_size)
{
const char* no_yes[2] = { "No", "Yes" };

View File

@ -160,7 +160,7 @@ void BPWritten(const BPCmd& bp)
bpmem.genMode.numtexgens, bpmem.genMode.numcolchans,
bpmem.genMode.ms_en, bpmem.genMode.numtevstages+1, bpmem.genMode.cullmode,
bpmem.genMode.numindstages, bpmem.genMode.zfreeze);
SetGenerationMode(bp);
SetGenerationMode();
break;
}
case BPMEM_IND_MTXA: // Index Matrix Changed
@ -188,12 +188,12 @@ void BPWritten(const BPCmd& bp)
SetScissor();
break;
case BPMEM_LINEPTWIDTH: // Line Width
SetLineWidth(bp);
SetLineWidth();
break;
case BPMEM_ZMODE: // Depth Control
PRIM_LOG("zmode: test=%d, func=%d, upd=%d", bpmem.zmode.testenable, bpmem.zmode.func,
bpmem.zmode.updateenable);
SetDepthMode(bp);
SetDepthMode();
break;
case BPMEM_BLENDMODE: // Blending Control
{
@ -204,16 +204,16 @@ void BPWritten(const BPCmd& bp)
bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode);
// Set LogicOp Blending Mode
if (bp.changes & 2)
SetLogicOpMode(bp);
SetLogicOpMode();
// Set Dithering Mode
if (bp.changes & 4)
SetDitherMode(bp);
SetDitherMode();
// Set Blending Mode
if (bp.changes & 0xFE1)
SetBlendMode(bp);
SetBlendMode();
// Set Color Mask
if (bp.changes & 0x18)
SetColorMask(bp);
SetColorMask();
}
break;
}
@ -306,7 +306,7 @@ void BPWritten(const BPCmd& bp)
// Clear the rectangular region after copying it.
if (PE_copy.clear)
{
ClearScreen(bp, rc);
ClearScreen(rc);
}
break;
@ -455,7 +455,7 @@ void BPWritten(const BPCmd& bp)
case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
g_renderer->SetColorMask(); // alpha writing needs to be disabled if the new pixel format doesn't have an alpha channel
OnPixelFormatChange(bp);
OnPixelFormatChange();
break;
case BPMEM_MIPMAP_STRIDE: // MipMap Stride Channel
@ -680,3 +680,35 @@ void BPWritten(const BPCmd& bp)
}
}
// Called when loading a saved state.
void BPReload()
{
// restore anything that goes straight to the renderer.
// let's not risk actually replaying any writes.
// note that PixelShaderManager is already covered since it has its own DoState.
SetGenerationMode();
SetScissor();
SetLineWidth();
SetDepthMode();
SetLogicOpMode();
SetDitherMode();
SetBlendMode();
SetColorMask();
OnPixelFormatChange();
{
BPCmd bp = {BPMEM_TX_SETMODE0, 0xFFFFFF, ((u32*)&bpmem)[BPMEM_TX_SETMODE0]};
SetTextureMode(bp);
}
{
BPCmd bp = {BPMEM_TX_SETMODE0_4, 0xFFFFFF, ((u32*)&bpmem)[BPMEM_TX_SETMODE0_4]};
SetTextureMode(bp);
}
{
BPCmd bp = {BPMEM_FIELDMASK, 0xFFFFFF, ((u32*)&bpmem)[BPMEM_FIELDMASK]};
SetInterlacingMode(bp);
}
{
BPCmd bp = {BPMEM_FIELDMODE, 0xFFFFFF, ((u32*)&bpmem)[BPMEM_FIELDMODE]};
SetInterlacingMode(bp);
}
}

View File

@ -185,10 +185,6 @@ void VideoBackendHardware::InitializeShared()
// Run from the CPU thread
void VideoBackendHardware::DoState(PointerWrap& p)
{
// Clear all caches that touch RAM
TextureCache::Invalidate(false);
VertexLoaderManager::MarkAllDirty();
VideoCommon_DoState(p);
// Refresh state.
@ -196,6 +192,11 @@ void VideoBackendHardware::DoState(PointerWrap& p)
{
BPReload();
RecomputeCachedArraybases();
// Clear all caches that touch RAM
// (? these don't appear to touch any emulation state that gets saved. moved to on load only.)
TextureCache::Invalidate(false);
VertexLoaderManager::MarkAllDirty();
}
}

View File

@ -465,3 +465,16 @@ void PixelShaderManager::SetMaterialColorChanged(int index)
{
nMaterialsChanged |= (1 << index);
}
void PixelShaderManager::DoState(PointerWrap &p)
{
p.Do(lastRGBAfull);
p.Do(lastAlpha);
p.Do(lastTexDims);
p.Do(lastZBias);
if (p.GetMode() == PointerWrap::MODE_READ)
{
Dirty();
}
}

View File

@ -22,6 +22,8 @@
#include "XFMemory.h"
#include "PixelShaderGen.h"
class PointerWrap;
// The non-API dependent parts.
class PixelShaderManager
{
@ -30,6 +32,7 @@ public:
static void Init();
static void Dirty();
static void Shutdown();
static void DoState(PointerWrap &p);
static void SetConstants(); // sets pixel shader constants

View File

@ -616,3 +616,18 @@ void VertexShaderManager::ResetView()
bProjectionChanged = true;
}
void VertexShaderManager::DoState(PointerWrap &p)
{
p.Do(g_fProjectionMatrix);
p.Do(s_viewportCorrection);
p.Do(s_viewRotationMatrix);
p.Do(s_viewInvRotationMatrix);
p.Do(s_fViewTranslationVector);
p.Do(s_fViewRotation);
if (p.GetMode() == PointerWrap::MODE_READ)
{
Dirty();
}
}

View File

@ -20,6 +20,8 @@
#include "VertexShaderGen.h"
class PointerWrap;
struct ProjectionHack
{
float sign;
@ -38,7 +40,8 @@ public:
static void Init();
static void Dirty();
static void Shutdown();
static void DoState(PointerWrap &p);
;
// constant management
static void SetConstants();

View File

@ -24,6 +24,8 @@
#include "Fifo.h"
#include "CommandProcessor.h"
#include "PixelEngine.h"
#include "PixelShaderManager.h"
#include "VertexShaderManager.h"
static void DoState(PointerWrap &p)
{
@ -48,12 +50,17 @@ static void DoState(PointerWrap &p)
CommandProcessor::DoState(p);
PixelEngine::DoState(p);
// the old way of replaying current bpmem as writes to push side effects to pixel shader manager doesn't really work.
PixelShaderManager::DoState(p);
VertexShaderManager::DoState(p);
// TODO: search for more data that should be saved and add it here
}
void VideoCommon_DoState(PointerWrap &p)
{
DoState(p);
//TODO: search for more data that should be saved and add it here
}
void VideoCommon_RunLoop(bool enable)