fixed some graphics problems with loading savestates (for example, wrong colors on title screen of metroid prime 3)
This commit is contained in:
parent
19b0b02ad7
commit
2be579e8ba
|
@ -39,7 +39,7 @@ void FlushPipeline()
|
||||||
VertexManager::Flush();
|
VertexManager::Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGenerationMode(const BPCmd &bp)
|
void SetGenerationMode()
|
||||||
{
|
{
|
||||||
g_renderer->SetGenerationMode();
|
g_renderer->SetGenerationMode();
|
||||||
}
|
}
|
||||||
|
@ -64,30 +64,30 @@ void SetScissor()
|
||||||
g_renderer->SetScissorRect(trc);
|
g_renderer->SetScissorRect(trc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetLineWidth(const BPCmd &bp)
|
void SetLineWidth()
|
||||||
{
|
{
|
||||||
g_renderer->SetLineWidth();
|
g_renderer->SetLineWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDepthMode(const BPCmd &bp)
|
void SetDepthMode()
|
||||||
{
|
{
|
||||||
g_renderer->SetDepthMode();
|
g_renderer->SetDepthMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBlendMode(const BPCmd &bp)
|
void SetBlendMode()
|
||||||
{
|
{
|
||||||
g_renderer->SetBlendMode(false);
|
g_renderer->SetBlendMode(false);
|
||||||
}
|
}
|
||||||
void SetDitherMode(const BPCmd &bp)
|
void SetDitherMode()
|
||||||
{
|
{
|
||||||
g_renderer->SetDitherMode();
|
g_renderer->SetDitherMode();
|
||||||
}
|
}
|
||||||
void SetLogicOpMode(const BPCmd &bp)
|
void SetLogicOpMode()
|
||||||
{
|
{
|
||||||
g_renderer->SetLogicOpMode();
|
g_renderer->SetLogicOpMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetColorMask(const BPCmd &bp)
|
void SetColorMask()
|
||||||
{
|
{
|
||||||
g_renderer->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 RGBA8 color to RGBA6/RGB8/RGB565 and convert it to RGBA8 again
|
||||||
- convert the Z24 depth value to Z16 and back to Z24
|
- 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 colorEnable = bpmem.blendmode.colorupdate;
|
||||||
bool alphaEnable = bpmem.blendmode.alphaupdate;
|
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;
|
int convtype = -1;
|
||||||
|
|
||||||
|
|
|
@ -37,18 +37,18 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
void FlushPipeline();
|
void FlushPipeline();
|
||||||
void SetGenerationMode(const BPCmd &bp);
|
void SetGenerationMode();
|
||||||
void SetScissor();
|
void SetScissor();
|
||||||
void SetLineWidth(const BPCmd &bp);
|
void SetLineWidth();
|
||||||
void SetDepthMode(const BPCmd &bp);
|
void SetDepthMode();
|
||||||
void SetBlendMode(const BPCmd &bp);
|
void SetBlendMode();
|
||||||
void SetDitherMode(const BPCmd &bp);
|
void SetDitherMode();
|
||||||
void SetLogicOpMode(const BPCmd &bp);
|
void SetLogicOpMode();
|
||||||
void SetColorMask(const BPCmd &bp);
|
void SetColorMask();
|
||||||
void CopyEFB(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
void CopyEFB(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
||||||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);
|
||||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc);
|
void ClearScreen(const EFBRectangle &rc);
|
||||||
void OnPixelFormatChange(const BPCmd &bp);
|
void OnPixelFormatChange();
|
||||||
u8 *GetPointer(const u32 &address);
|
u8 *GetPointer(const u32 &address);
|
||||||
bool GetConfig(const int &type);
|
bool GetConfig(const int &type);
|
||||||
void SetTextureMode(const BPCmd &bp);
|
void SetTextureMode(const BPCmd &bp);
|
||||||
|
|
|
@ -43,31 +43,6 @@ void LoadBPReg(u32 value0)
|
||||||
BPWritten(bp);
|
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)
|
void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size_t desc_size)
|
||||||
{
|
{
|
||||||
const char* no_yes[2] = { "No", "Yes" };
|
const char* no_yes[2] = { "No", "Yes" };
|
||||||
|
|
|
@ -160,7 +160,7 @@ void BPWritten(const BPCmd& bp)
|
||||||
bpmem.genMode.numtexgens, bpmem.genMode.numcolchans,
|
bpmem.genMode.numtexgens, bpmem.genMode.numcolchans,
|
||||||
bpmem.genMode.ms_en, bpmem.genMode.numtevstages+1, bpmem.genMode.cullmode,
|
bpmem.genMode.ms_en, bpmem.genMode.numtevstages+1, bpmem.genMode.cullmode,
|
||||||
bpmem.genMode.numindstages, bpmem.genMode.zfreeze);
|
bpmem.genMode.numindstages, bpmem.genMode.zfreeze);
|
||||||
SetGenerationMode(bp);
|
SetGenerationMode();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BPMEM_IND_MTXA: // Index Matrix Changed
|
case BPMEM_IND_MTXA: // Index Matrix Changed
|
||||||
|
@ -188,12 +188,12 @@ void BPWritten(const BPCmd& bp)
|
||||||
SetScissor();
|
SetScissor();
|
||||||
break;
|
break;
|
||||||
case BPMEM_LINEPTWIDTH: // Line Width
|
case BPMEM_LINEPTWIDTH: // Line Width
|
||||||
SetLineWidth(bp);
|
SetLineWidth();
|
||||||
break;
|
break;
|
||||||
case BPMEM_ZMODE: // Depth Control
|
case BPMEM_ZMODE: // Depth Control
|
||||||
PRIM_LOG("zmode: test=%d, func=%d, upd=%d", bpmem.zmode.testenable, bpmem.zmode.func,
|
PRIM_LOG("zmode: test=%d, func=%d, upd=%d", bpmem.zmode.testenable, bpmem.zmode.func,
|
||||||
bpmem.zmode.updateenable);
|
bpmem.zmode.updateenable);
|
||||||
SetDepthMode(bp);
|
SetDepthMode();
|
||||||
break;
|
break;
|
||||||
case BPMEM_BLENDMODE: // Blending Control
|
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);
|
bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode);
|
||||||
// Set LogicOp Blending Mode
|
// Set LogicOp Blending Mode
|
||||||
if (bp.changes & 2)
|
if (bp.changes & 2)
|
||||||
SetLogicOpMode(bp);
|
SetLogicOpMode();
|
||||||
// Set Dithering Mode
|
// Set Dithering Mode
|
||||||
if (bp.changes & 4)
|
if (bp.changes & 4)
|
||||||
SetDitherMode(bp);
|
SetDitherMode();
|
||||||
// Set Blending Mode
|
// Set Blending Mode
|
||||||
if (bp.changes & 0xFE1)
|
if (bp.changes & 0xFE1)
|
||||||
SetBlendMode(bp);
|
SetBlendMode();
|
||||||
// Set Color Mask
|
// Set Color Mask
|
||||||
if (bp.changes & 0x18)
|
if (bp.changes & 0x18)
|
||||||
SetColorMask(bp);
|
SetColorMask();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -306,7 +306,7 @@ void BPWritten(const BPCmd& bp)
|
||||||
// Clear the rectangular region after copying it.
|
// Clear the rectangular region after copying it.
|
||||||
if (PE_copy.clear)
|
if (PE_copy.clear)
|
||||||
{
|
{
|
||||||
ClearScreen(bp, rc);
|
ClearScreen(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -455,7 +455,7 @@ void BPWritten(const BPCmd& bp)
|
||||||
|
|
||||||
case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
|
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
|
g_renderer->SetColorMask(); // alpha writing needs to be disabled if the new pixel format doesn't have an alpha channel
|
||||||
OnPixelFormatChange(bp);
|
OnPixelFormatChange();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BPMEM_MIPMAP_STRIDE: // MipMap Stride Channel
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -185,10 +185,6 @@ void VideoBackendHardware::InitializeShared()
|
||||||
// Run from the CPU thread
|
// Run from the CPU thread
|
||||||
void VideoBackendHardware::DoState(PointerWrap& p)
|
void VideoBackendHardware::DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
// Clear all caches that touch RAM
|
|
||||||
TextureCache::Invalidate(false);
|
|
||||||
VertexLoaderManager::MarkAllDirty();
|
|
||||||
|
|
||||||
VideoCommon_DoState(p);
|
VideoCommon_DoState(p);
|
||||||
|
|
||||||
// Refresh state.
|
// Refresh state.
|
||||||
|
@ -196,6 +192,11 @@ void VideoBackendHardware::DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
BPReload();
|
BPReload();
|
||||||
RecomputeCachedArraybases();
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -465,3 +465,16 @@ void PixelShaderManager::SetMaterialColorChanged(int index)
|
||||||
{
|
{
|
||||||
nMaterialsChanged |= (1 << 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include "XFMemory.h"
|
#include "XFMemory.h"
|
||||||
#include "PixelShaderGen.h"
|
#include "PixelShaderGen.h"
|
||||||
|
|
||||||
|
class PointerWrap;
|
||||||
|
|
||||||
// The non-API dependent parts.
|
// The non-API dependent parts.
|
||||||
class PixelShaderManager
|
class PixelShaderManager
|
||||||
{
|
{
|
||||||
|
@ -30,6 +32,7 @@ public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Dirty();
|
static void Dirty();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
static void DoState(PointerWrap &p);
|
||||||
|
|
||||||
static void SetConstants(); // sets pixel shader constants
|
static void SetConstants(); // sets pixel shader constants
|
||||||
|
|
||||||
|
|
|
@ -616,3 +616,18 @@ void VertexShaderManager::ResetView()
|
||||||
|
|
||||||
bProjectionChanged = true;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
|
|
||||||
|
class PointerWrap;
|
||||||
|
|
||||||
struct ProjectionHack
|
struct ProjectionHack
|
||||||
{
|
{
|
||||||
float sign;
|
float sign;
|
||||||
|
@ -38,7 +40,8 @@ public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Dirty();
|
static void Dirty();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
static void DoState(PointerWrap &p);
|
||||||
|
;
|
||||||
// constant management
|
// constant management
|
||||||
static void SetConstants();
|
static void SetConstants();
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
#include "CommandProcessor.h"
|
#include "CommandProcessor.h"
|
||||||
#include "PixelEngine.h"
|
#include "PixelEngine.h"
|
||||||
|
#include "PixelShaderManager.h"
|
||||||
|
#include "VertexShaderManager.h"
|
||||||
|
|
||||||
static void DoState(PointerWrap &p)
|
static void DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
|
@ -48,12 +50,17 @@ static void DoState(PointerWrap &p)
|
||||||
|
|
||||||
CommandProcessor::DoState(p);
|
CommandProcessor::DoState(p);
|
||||||
PixelEngine::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)
|
void VideoCommon_DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
DoState(p);
|
DoState(p);
|
||||||
//TODO: search for more data that should be saved and add it here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoCommon_RunLoop(bool enable)
|
void VideoCommon_RunLoop(bool enable)
|
||||||
|
|
Loading…
Reference in New Issue