More state save code, "proper" fix for the quantizer problem
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@382 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
ff0a613427
commit
5ac5a04982
|
@ -413,15 +413,11 @@ EState GetState()
|
|||
}
|
||||
|
||||
void SaveState() {
|
||||
CCPU::EnableStepping(true);
|
||||
State_Save("state.dlp");
|
||||
CCPU::EnableStepping(false);
|
||||
}
|
||||
|
||||
void LoadState() {
|
||||
CCPU::EnableStepping(true);
|
||||
State_Load("state.dlp");
|
||||
CCPU::EnableStepping(false);
|
||||
}
|
||||
|
||||
const SCoreStartupParameter& GetStartupParameter()
|
||||
|
|
|
@ -89,6 +89,7 @@ namespace HW
|
|||
|
||||
void DoState(PointerWrap &p)
|
||||
{
|
||||
Memory::DoState(p);
|
||||
PixelEngine::DoState(p);
|
||||
CommandProcessor::DoState(p);
|
||||
VideoInterface::DoState(p);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "Common.h"
|
||||
#include "MemoryUtil.h"
|
||||
#include "MemArena.h"
|
||||
#include "ChunkFile.h"
|
||||
|
||||
#include "Memmap.h"
|
||||
#include "../Core.h"
|
||||
|
@ -143,7 +144,6 @@ template <class T, u8* P> void HWCALL HW_Write_Memory(T _Data, const u32 _Addres
|
|||
#define AUDIO_START 0x1B
|
||||
#define GP_START 0x20
|
||||
|
||||
|
||||
void InitHWMemFuncs()
|
||||
{
|
||||
for (int i = 0; i < NUMHWMEMFUN; i++)
|
||||
|
@ -523,6 +523,15 @@ bool Init()
|
|||
return true;
|
||||
}
|
||||
|
||||
void DoState(PointerWrap &p)
|
||||
{
|
||||
bool wii = Core::GetStartupParameter().bWii;
|
||||
p.DoArray(m_pRAM, RAM_SIZE);
|
||||
p.DoArray(m_pEFB, EFB_SIZE);
|
||||
p.DoArray(m_pL1Cache, L1_CACHE_SIZE);
|
||||
if (wii)
|
||||
p.DoArray(m_pEXRAM, EXRAM_SIZE);
|
||||
}
|
||||
|
||||
bool Shutdown()
|
||||
{
|
||||
|
|
|
@ -370,6 +370,7 @@ namespace Jit64
|
|||
js.fifoBytesThisBlock = 0;
|
||||
js.curBlock = &b;
|
||||
js.blockSetsQuantizers = false;
|
||||
js.block_flags = 0;
|
||||
|
||||
//Analyze the block, collect all instructions it is made of (including inlining,
|
||||
//if that is enabled), reorder instructions for optimal performance, and join joinable instructions.
|
||||
|
@ -415,7 +416,8 @@ namespace Jit64
|
|||
js.compilerPC = ops[i].address;
|
||||
js.op = &ops[i];
|
||||
js.instructionNumber = i;
|
||||
if (i == (int)size - 1) js.isLastInstruction = true;
|
||||
if (i == (int)size - 1)
|
||||
js.isLastInstruction = true;
|
||||
|
||||
// const GekkoOpInfo *info = GetOpInfo();
|
||||
// if (js.isLastInstruction)
|
||||
|
@ -435,6 +437,7 @@ namespace Jit64
|
|||
}
|
||||
js.compilerPC += 4;
|
||||
|
||||
b.flags = js.block_flags;
|
||||
b.codeSize = (u32)(GetCodePtr() - start);
|
||||
b.originalSize = js.compilerPC - emaddress;
|
||||
return normalEntry;
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace Jit64
|
|||
int blockSize;
|
||||
int instructionNumber;
|
||||
int downcountAmount;
|
||||
int block_flags;
|
||||
|
||||
bool isLastInstruction;
|
||||
bool blockSetsQuantizers;
|
||||
|
|
|
@ -118,6 +118,15 @@ namespace Jit64
|
|||
SetCodePtr(codeCache);
|
||||
}
|
||||
|
||||
void DestroyBlocksWithFlag(BlockFlag death_flag)
|
||||
{
|
||||
for (int i = 0; i < numBlocks; i++) {
|
||||
if (blocks[i].flags & death_flag) {
|
||||
DestroyBlock(i, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ResetCache()
|
||||
{
|
||||
ShutdownCache();
|
||||
|
@ -338,8 +347,11 @@ namespace Jit64
|
|||
//for something else, then it's fine.
|
||||
LOG(MASTER_LOG, "WARNING - ClearCache detected code overwrite @ %08x", blocks[blocknum].originalAddress);
|
||||
}
|
||||
// TODO: Unlink block.
|
||||
|
||||
// We don't unlink blocks, we just send anyone who tries to run them back to the dispatcher.
|
||||
// Not entirely ideal, but .. pretty good.
|
||||
|
||||
// TODO - make sure that the below stuff really is safe.
|
||||
u8 *prev_code = GetWritableCodePtr();
|
||||
// Spurious entrances from previously linked blocks can only come through checkedEntry
|
||||
SetCodePtr((u8*)b.checkedEntry);
|
||||
|
|
|
@ -28,6 +28,18 @@ namespace Jit64
|
|||
|
||||
//Code pointers are stored separately, they will be accessed much more frequently
|
||||
|
||||
enum BlockFlag
|
||||
{
|
||||
BLOCK_USE_GQR0 = 0x1,
|
||||
BLOCK_USE_GQR1 = 0x2,
|
||||
BLOCK_USE_GQR2 = 0x4,
|
||||
BLOCK_USE_GQR3 = 0x8,
|
||||
BLOCK_USE_GQR4 = 0x10,
|
||||
BLOCK_USE_GQR5 = 0x20,
|
||||
BLOCK_USE_GQR6 = 0x40,
|
||||
BLOCK_USE_GQR7 = 0x80,
|
||||
};
|
||||
|
||||
// TODO(ector) - optimize this struct for size
|
||||
struct JitBlock
|
||||
{
|
||||
|
@ -42,6 +54,7 @@ namespace Jit64
|
|||
int runCount; // for profiling.
|
||||
const u8 *checkedEntry;
|
||||
bool invalid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
void PrintStats();
|
||||
|
@ -62,6 +75,9 @@ namespace Jit64
|
|||
u8 **GetCodePointers();
|
||||
|
||||
u8 *Jit(u32 emaddress);
|
||||
|
||||
void DestroyBlocksWithFlag(BlockFlag death_flag);
|
||||
|
||||
void LinkBlocks();
|
||||
void ClearCache();
|
||||
|
||||
|
|
|
@ -107,6 +107,8 @@ const double GC_ALIGNED16(m_dequantizeTableD[]) =
|
|||
void psq_st(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START;
|
||||
js.block_flags |= BLOCK_USE_GQR0 << inst.I;
|
||||
|
||||
if (js.blockSetsQuantizers || !Core::GetStartupParameter().bOptimizeQuantizers)
|
||||
{
|
||||
Default(inst);
|
||||
|
@ -118,6 +120,7 @@ void psq_st(UGeckoInstruction inst)
|
|||
Default(inst);
|
||||
return;
|
||||
}
|
||||
|
||||
const UGQR gqr(rSPR(SPR_GQR0 + inst.I));
|
||||
const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
|
||||
int stScale = gqr.ST_SCALE;
|
||||
|
@ -281,11 +284,14 @@ const u8 GC_ALIGNED16(pbswapShuffleNoop[16]) = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
|
|||
void psq_l(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START;
|
||||
js.block_flags |= BLOCK_USE_GQR0 << inst.I;
|
||||
|
||||
if (js.blockSetsQuantizers || !Core::GetStartupParameter().bOptimizeQuantizers)
|
||||
{
|
||||
Default(inst);
|
||||
return;
|
||||
}
|
||||
|
||||
const UGQR gqr(rSPR(SPR_GQR0 + inst.I));
|
||||
const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
|
||||
int ldScale = gqr.LD_SCALE;
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "../PowerPC.h"
|
||||
#include "../PPCTables.h"
|
||||
#include "x64Emitter.h"
|
||||
#include "ABI.h"
|
||||
#include "Thunk.h"
|
||||
|
||||
#include "Jit.h"
|
||||
#include "JitCache.h"
|
||||
|
@ -55,7 +57,16 @@ namespace Jit64
|
|||
case SPR_GQR0 + 7:
|
||||
js.blockSetsQuantizers = true;
|
||||
// Prevent recompiler from compiling in old quantizer values.
|
||||
// TODO - actually save the set state and use it in following quantizer ops.
|
||||
// If the value changed, destroy all blocks using this quantizer
|
||||
// This will create a little bit of block churn, but hopefully not too bad.
|
||||
{
|
||||
MOV(32, R(EAX), M(&PowerPC::ppcState.spr[iIndex])); // Load old value
|
||||
CMP(32, R(EAX), gpr.R(inst.RD));
|
||||
FixupBranch skip_destroy = J_CC(CC_E, false);
|
||||
int gqr = iIndex - SPR_GQR0;
|
||||
ABI_CallFunctionC(ProtectFunction(&Jit64::DestroyBlocksWithFlag, 1), (u32)BLOCK_USE_GQR0 << gqr);
|
||||
SetJumpTarget(skip_destroy);
|
||||
}
|
||||
break;
|
||||
// TODO - break block if quantizers are written to.
|
||||
default:
|
||||
|
|
|
@ -1,11 +1,30 @@
|
|||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include "State.h"
|
||||
#include "CoreTiming.h"
|
||||
#include "HW/HW.h"
|
||||
#include "PowerPC/PowerPC.h"
|
||||
#include "PowerPC/Jit64/JitCache.h"
|
||||
|
||||
#include "Plugins/Plugin_Video.h"
|
||||
#include "Plugins/Plugin_DSP.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -18,11 +37,14 @@ void DoState(PointerWrap &p)
|
|||
{
|
||||
PowerPC::DoState(p);
|
||||
HW::DoState(p);
|
||||
CoreTiming::DoState(p);
|
||||
PluginVideo::Video_DoState(p.GetPPtr(), p.GetMode());
|
||||
}
|
||||
|
||||
void SaveStateCallback(u64 userdata, int cyclesLate)
|
||||
{
|
||||
Jit64::ClearCache();
|
||||
|
||||
u8 *ptr = 0;
|
||||
PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
|
||||
DoState(p);
|
||||
|
@ -39,7 +61,8 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
|
|||
|
||||
void LoadStateCallback(u64 userdata, int cyclesLate)
|
||||
{
|
||||
// ChunkFile f(cur_filename.c_str(), ChunkFile::MODE_READ);
|
||||
Jit64::ClearCache();
|
||||
|
||||
FILE *f = fopen(cur_filename.c_str(), "r");
|
||||
fseek(f, 0, SEEK_END);
|
||||
int sz = ftell(f);
|
||||
|
|
|
@ -1,11 +1,27 @@
|
|||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _STATE_H
|
||||
#define _STATE_H
|
||||
|
||||
// None of these happen instantly - they get scheduled as an event.
|
||||
|
||||
void State_Init();
|
||||
void State_Shutdown();
|
||||
|
||||
// These don't happen instantly - they get scheduled as events.
|
||||
void State_Save(const char *filename);
|
||||
void State_Load(const char *filename);
|
||||
|
||||
|
|
|
@ -170,24 +170,25 @@ void CFrame::CreateMenu()
|
|||
fileMenu->Append(wxID_OPEN, _T("&Open..."));
|
||||
fileMenu->Append(wxID_REFRESH, _T("&Refresh"));
|
||||
fileMenu->Append(IDM_BROWSE, _T("&Browse for ISOs..."));
|
||||
fileMenu->AppendSeparator();
|
||||
m_pMenuItemPlay = new wxMenuItem(fileMenu, IDM_PLAY, _T("&Play"));
|
||||
fileMenu->Append(m_pMenuItemPlay);
|
||||
m_pMenuItemStop = new wxMenuItem(fileMenu, IDM_STOP, _T("&Stop"));
|
||||
fileMenu->Append(m_pMenuItemStop);
|
||||
|
||||
fileMenu->AppendSeparator();
|
||||
m_pMenuItemLoad = new wxMenuItem(fileMenu, IDM_LOADSTATE, _T("&Load State... (AKA Russian Roulette)"));
|
||||
fileMenu->Append(m_pMenuItemLoad);
|
||||
m_pMenuItemLoad->Enable(false);
|
||||
m_pMenuItemSave = new wxMenuItem(fileMenu, IDM_SAVESTATE, _T("Sa&ve State... (Use at your own risk)"));
|
||||
fileMenu->Append(m_pMenuItemSave);
|
||||
m_pMenuItemSave->Enable(false);
|
||||
|
||||
fileMenu->AppendSeparator();
|
||||
fileMenu->Append(wxID_EXIT, _T("E&xit"), _T(""));
|
||||
m_pMenuBar->Append(fileMenu, _T("&File"));
|
||||
|
||||
// emulation menu
|
||||
wxMenu* emulationMenu = new wxMenu;
|
||||
m_pMenuItemPlay = new wxMenuItem(fileMenu, IDM_PLAY, _T("&Play"));
|
||||
emulationMenu->Append(m_pMenuItemPlay);
|
||||
m_pMenuItemStop = new wxMenuItem(fileMenu, IDM_STOP, _T("&Stop"));
|
||||
emulationMenu->Append(m_pMenuItemStop);
|
||||
emulationMenu->AppendSeparator();
|
||||
|
||||
m_pMenuItemLoad = new wxMenuItem(fileMenu, IDM_LOADSTATE, _T("&Load State"));
|
||||
emulationMenu->Append(m_pMenuItemLoad);
|
||||
m_pMenuItemSave = new wxMenuItem(fileMenu, IDM_SAVESTATE, _T("Sa&ve State"));
|
||||
emulationMenu->Append(m_pMenuItemSave);
|
||||
m_pMenuBar->Append(emulationMenu, _T("&Emulation"));
|
||||
|
||||
// options menu
|
||||
wxMenu* pOptionsMenu = new wxMenu;
|
||||
m_pPluginOptions = new wxMenuItem(pOptionsMenu, IDM_PLUGIN_OPTIONS, _T("&Select plugins"));
|
||||
|
|
Loading…
Reference in New Issue