Merge pull request #1102 from neobrain/tevreg_loading
GPU: Only load the relevant color components upon writes to the tev color registers
This commit is contained in:
commit
124df2e134
|
@ -13,6 +13,7 @@
|
||||||
// - Zero backwards/forwards compatibility
|
// - Zero backwards/forwards compatibility
|
||||||
// - Serialization code for anything complex has to be manually written.
|
// - Serialization code for anything complex has to be manually written.
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -159,6 +160,12 @@ public:
|
||||||
Do(x.second);
|
Do(x.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
void DoArray(std::array<T,N>& x)
|
||||||
|
{
|
||||||
|
DoArray(x.data(), (u32)x.size());
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void DoArray(T* x, u32 count)
|
void DoArray(T* x, u32 count)
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,7 +63,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
||||||
static std::thread g_save_thread;
|
static std::thread g_save_thread;
|
||||||
|
|
||||||
// Don't forget to increase this after doing changes on the savestate system
|
// Don't forget to increase this after doing changes on the savestate system
|
||||||
static const u32 STATE_VERSION = 31;
|
static const u32 STATE_VERSION = 32;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
|
@ -145,10 +145,10 @@ void SWBPWritten(int address, int newvalue)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BPMEM_TEV_REGISTER_L: // Reg 1
|
case BPMEM_TEV_COLOR_RA:
|
||||||
case BPMEM_TEV_REGISTER_L+2: // Reg 2
|
case BPMEM_TEV_COLOR_RA + 2:
|
||||||
case BPMEM_TEV_REGISTER_L+4: // Reg 3
|
case BPMEM_TEV_COLOR_RA + 4:
|
||||||
case BPMEM_TEV_REGISTER_L+6: // Reg 4
|
case BPMEM_TEV_COLOR_RA + 6:
|
||||||
{
|
{
|
||||||
int regNum = (address >> 1 ) & 0x3;
|
int regNum = (address >> 1 ) & 0x3;
|
||||||
TevReg& reg = bpmem.tevregs[regNum];
|
TevReg& reg = bpmem.tevregs[regNum];
|
||||||
|
@ -160,10 +160,10 @@ void SWBPWritten(int address, int newvalue)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BPMEM_TEV_REGISTER_H: // Reg 1
|
case BPMEM_TEV_COLOR_BG:
|
||||||
case BPMEM_TEV_REGISTER_H+2: // Reg 2
|
case BPMEM_TEV_COLOR_BG + 2:
|
||||||
case BPMEM_TEV_REGISTER_H+4: // Reg 3
|
case BPMEM_TEV_COLOR_BG + 4:
|
||||||
case BPMEM_TEV_REGISTER_H+6: // Reg 4
|
case BPMEM_TEV_COLOR_BG + 6:
|
||||||
{
|
{
|
||||||
int regNum = (address >> 1 ) & 0x3;
|
int regNum = (address >> 1 ) & 0x3;
|
||||||
TevReg& reg = bpmem.tevregs[regNum];
|
TevReg& reg = bpmem.tevregs[regNum];
|
||||||
|
|
|
@ -80,8 +80,8 @@
|
||||||
#define BPMEM_TX_SETTLUT_4 0xB8 // 0xB8 + 4
|
#define BPMEM_TX_SETTLUT_4 0xB8 // 0xB8 + 4
|
||||||
#define BPMEM_TEV_COLOR_ENV 0xC0 // 0xC0 + (2 * 16)
|
#define BPMEM_TEV_COLOR_ENV 0xC0 // 0xC0 + (2 * 16)
|
||||||
#define BPMEM_TEV_ALPHA_ENV 0xC1 // 0xC1 + (2 * 16)
|
#define BPMEM_TEV_ALPHA_ENV 0xC1 // 0xC1 + (2 * 16)
|
||||||
#define BPMEM_TEV_REGISTER_L 0xE0 // 0xE0 + (2 * 4)
|
#define BPMEM_TEV_COLOR_RA 0xE0 // 0xE0 + (2 * 4)
|
||||||
#define BPMEM_TEV_REGISTER_H 0xE1 // 0xE1 + (2 * 4)
|
#define BPMEM_TEV_COLOR_BG 0xE1 // 0xE1 + (2 * 4)
|
||||||
#define BPMEM_FOGRANGE 0xE8 // 0xE8 + 6
|
#define BPMEM_FOGRANGE 0xE8 // 0xE8 + 6
|
||||||
#define BPMEM_FOGPARAM0 0xEE
|
#define BPMEM_FOGPARAM0 0xEE
|
||||||
#define BPMEM_FOGBMAGNITUDE 0xEF
|
#define BPMEM_FOGBMAGNITUDE 0xEF
|
||||||
|
@ -853,6 +853,8 @@ union TevReg
|
||||||
BitField< 0, 32,u64> low;
|
BitField< 0, 32,u64> low;
|
||||||
BitField<32, 32,u64> high;
|
BitField<32, 32,u64> high;
|
||||||
|
|
||||||
|
// TODO: Check if Konst uses all 11 bits or just 8
|
||||||
|
|
||||||
// Low register
|
// Low register
|
||||||
BitField< 0,11,s64> red;
|
BitField< 0,11,s64> red;
|
||||||
|
|
||||||
|
|
|
@ -480,6 +480,55 @@ static void BPWritten(const BPCmd& bp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// Set the TEV Color
|
||||||
|
// ---------------------------------------------------
|
||||||
|
//
|
||||||
|
// NOTE: Each of these registers actually maps to two variables internally.
|
||||||
|
// There's a bit that specifies which one is currently written to.
|
||||||
|
//
|
||||||
|
// NOTE: Some games write only to the RA register (or only to the BG register).
|
||||||
|
// We may not assume that the unwritten register holds a valid value, hence
|
||||||
|
// both component pairs need to be loaded individually.
|
||||||
|
case BPMEM_TEV_COLOR_RA:
|
||||||
|
case BPMEM_TEV_COLOR_RA + 2:
|
||||||
|
case BPMEM_TEV_COLOR_RA + 4:
|
||||||
|
case BPMEM_TEV_COLOR_RA + 6:
|
||||||
|
{
|
||||||
|
int num = (bp.address >> 1) & 0x3;
|
||||||
|
if (bpmem.tevregs[num].type_ra)
|
||||||
|
{
|
||||||
|
PixelShaderManager::SetTevKonstColor(num, 0, (s32)bpmem.tevregs[num].red);
|
||||||
|
PixelShaderManager::SetTevKonstColor(num, 3, (s32)bpmem.tevregs[num].alpha);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PixelShaderManager::SetTevColor(num, 0, (s32)bpmem.tevregs[num].red);
|
||||||
|
PixelShaderManager::SetTevColor(num, 3, (s32)bpmem.tevregs[num].alpha);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case BPMEM_TEV_COLOR_BG:
|
||||||
|
case BPMEM_TEV_COLOR_BG + 2:
|
||||||
|
case BPMEM_TEV_COLOR_BG + 4:
|
||||||
|
case BPMEM_TEV_COLOR_BG + 6:
|
||||||
|
{
|
||||||
|
int num = (bp.address >> 1) & 0x3;
|
||||||
|
if (bpmem.tevregs[num].type_bg)
|
||||||
|
{
|
||||||
|
PixelShaderManager::SetTevKonstColor(num, 1, (s32)bpmem.tevregs[num].green);
|
||||||
|
PixelShaderManager::SetTevKonstColor(num, 2, (s32)bpmem.tevregs[num].blue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PixelShaderManager::SetTevColor(num, 1, (s32)bpmem.tevregs[num].green);
|
||||||
|
PixelShaderManager::SetTevColor(num, 2, (s32)bpmem.tevregs[num].blue);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -548,29 +597,6 @@ static void BPWritten(const BPCmd& bp)
|
||||||
case BPMEM_TX_SETTLUT_4:
|
case BPMEM_TX_SETTLUT_4:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// ---------------------------------------------------
|
|
||||||
// Set the TEV Color
|
|
||||||
// ---------------------------------------------------
|
|
||||||
case BPMEM_TEV_REGISTER_L: // Reg 1
|
|
||||||
case BPMEM_TEV_REGISTER_H:
|
|
||||||
case BPMEM_TEV_REGISTER_L+2: // Reg 2
|
|
||||||
case BPMEM_TEV_REGISTER_H+2:
|
|
||||||
case BPMEM_TEV_REGISTER_L+4: // Reg 3
|
|
||||||
case BPMEM_TEV_REGISTER_H+4:
|
|
||||||
case BPMEM_TEV_REGISTER_L+6: // Reg 4
|
|
||||||
case BPMEM_TEV_REGISTER_H+6:
|
|
||||||
// some games only send the _L part, so always update
|
|
||||||
// there actually are 2 register behind each of these
|
|
||||||
// addresses, selected by the type bit.
|
|
||||||
{
|
|
||||||
// don't compare with changes!
|
|
||||||
int num = (bp.address >> 1) & 0x3;
|
|
||||||
if ((bp.address & 1) == 0)
|
|
||||||
PixelShaderManager::SetColorChanged(static_cast<int>(bpmem.tevregs[num].type_ra), num);
|
|
||||||
else
|
|
||||||
PixelShaderManager::SetColorChanged(static_cast<int>(bpmem.tevregs[num].type_bg), num);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1213,19 +1239,19 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BPMEM_TEV_REGISTER_L: // 0xE0
|
case BPMEM_TEV_COLOR_RA: // 0xE0
|
||||||
case BPMEM_TEV_REGISTER_L+2:
|
case BPMEM_TEV_COLOR_RA + 2: // 0xE2
|
||||||
case BPMEM_TEV_REGISTER_L+4:
|
case BPMEM_TEV_COLOR_RA + 4: // 0xE4
|
||||||
case BPMEM_TEV_REGISTER_L+6:
|
case BPMEM_TEV_COLOR_RA + 6: // 0xE6
|
||||||
SetRegName(BPMEM_TEV_REGISTER_L);
|
SetRegName(BPMEM_TEV_COLOR_RA);
|
||||||
// TODO: Description
|
// TODO: Description
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BPMEM_TEV_REGISTER_H: // 0xE1
|
case BPMEM_TEV_COLOR_BG: // 0xE1
|
||||||
case BPMEM_TEV_REGISTER_H+2:
|
case BPMEM_TEV_COLOR_BG + 2: // 0xE3
|
||||||
case BPMEM_TEV_REGISTER_H+4:
|
case BPMEM_TEV_COLOR_BG + 4: // 0xE5
|
||||||
case BPMEM_TEV_REGISTER_H+6:
|
case BPMEM_TEV_COLOR_BG + 6: // 0xE7
|
||||||
SetRegName(BPMEM_TEV_REGISTER_H);
|
SetRegName(BPMEM_TEV_COLOR_BG);
|
||||||
// TODO: Description
|
// TODO: Description
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,11 @@
|
||||||
#include "VideoCommon/VideoCommon.h"
|
#include "VideoCommon/VideoCommon.h"
|
||||||
#include "VideoCommon/VideoConfig.h"
|
#include "VideoCommon/VideoConfig.h"
|
||||||
|
|
||||||
static bool s_bFogRangeAdjustChanged;
|
bool PixelShaderManager::s_bFogRangeAdjustChanged;
|
||||||
static bool s_bViewPortChanged;
|
bool PixelShaderManager::s_bViewPortChanged;
|
||||||
|
|
||||||
|
std::array<int4,4> PixelShaderManager::s_tev_color;
|
||||||
|
std::array<int4,4> PixelShaderManager::s_tev_konst_color;
|
||||||
|
|
||||||
PixelShaderConstants PixelShaderManager::constants;
|
PixelShaderConstants PixelShaderManager::constants;
|
||||||
bool PixelShaderManager::dirty;
|
bool PixelShaderManager::dirty;
|
||||||
|
@ -21,6 +24,9 @@ bool PixelShaderManager::dirty;
|
||||||
void PixelShaderManager::Init()
|
void PixelShaderManager::Init()
|
||||||
{
|
{
|
||||||
memset(&constants, 0, sizeof(constants));
|
memset(&constants, 0, sizeof(constants));
|
||||||
|
memset(s_tev_color.data(), 0, sizeof(s_tev_color));
|
||||||
|
memset(s_tev_konst_color.data(), 0, sizeof(s_tev_konst_color));
|
||||||
|
|
||||||
Dirty();
|
Dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,14 +35,15 @@ void PixelShaderManager::Dirty()
|
||||||
s_bFogRangeAdjustChanged = true;
|
s_bFogRangeAdjustChanged = true;
|
||||||
s_bViewPortChanged = true;
|
s_bViewPortChanged = true;
|
||||||
|
|
||||||
SetColorChanged(0, 0);
|
for (unsigned index = 0; index < s_tev_color.size(); ++index)
|
||||||
SetColorChanged(0, 1);
|
{
|
||||||
SetColorChanged(0, 2);
|
for (int comp = 0; comp < 4; ++comp)
|
||||||
SetColorChanged(0, 3);
|
{
|
||||||
SetColorChanged(1, 0);
|
SetTevColor(index, comp, s_tev_color[index][comp]);
|
||||||
SetColorChanged(1, 1);
|
SetTevKonstColor(index, comp, s_tev_konst_color[index][comp]);
|
||||||
SetColorChanged(1, 2);
|
}
|
||||||
SetColorChanged(1, 3);
|
}
|
||||||
|
|
||||||
SetAlpha();
|
SetAlpha();
|
||||||
SetDestAlpha();
|
SetDestAlpha();
|
||||||
SetZTextureBias();
|
SetZTextureBias();
|
||||||
|
@ -107,16 +114,22 @@ void PixelShaderManager::SetConstants()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderManager::SetColorChanged(int type, int num)
|
void PixelShaderManager::SetTevColor(int index, int component, s32 value)
|
||||||
{
|
{
|
||||||
int4* c = type ? constants.kcolors : constants.colors;
|
auto& c = constants.colors[index];
|
||||||
c[num][0] = static_cast<s32>(bpmem.tevregs[num].red);
|
c[component] = s_tev_color[index][component] = value;
|
||||||
c[num][3] = static_cast<s32>(bpmem.tevregs[num].alpha);
|
|
||||||
c[num][2] = static_cast<s32>(bpmem.tevregs[num].blue);
|
|
||||||
c[num][1] = static_cast<s32>(bpmem.tevregs[num].green);
|
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
PRIM_LOG("pixel %scolor%d: %d %d %d %d\n", type?"k":"", num, c[num][0], c[num][1], c[num][2], c[num][3]);
|
PRIM_LOG("tev color%d: %d %d %d %d\n", index, c[0], c[1], c[2], c[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PixelShaderManager::SetTevKonstColor(int index, int component, s32 value)
|
||||||
|
{
|
||||||
|
auto& c = constants.kcolors[index];
|
||||||
|
c[component] = s_tev_konst_color[index][component] = value;
|
||||||
|
dirty = true;
|
||||||
|
|
||||||
|
PRIM_LOG("tev konst color%d: %d %d %d %d\n", index, c[0], c[1], c[2], c[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderManager::SetAlpha()
|
void PixelShaderManager::SetAlpha()
|
||||||
|
@ -265,11 +278,13 @@ void PixelShaderManager::SetFogRangeAdjustChanged()
|
||||||
|
|
||||||
void PixelShaderManager::DoState(PointerWrap &p)
|
void PixelShaderManager::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.Do(constants);
|
p.DoArray(s_tev_color);
|
||||||
p.Do(dirty);
|
p.DoArray(s_tev_konst_color);
|
||||||
|
|
||||||
if (p.GetMode() == PointerWrap::MODE_READ)
|
if (p.GetMode() == PointerWrap::MODE_READ)
|
||||||
{
|
{
|
||||||
|
// Reload current state from global GPU state
|
||||||
|
// NOTE: This requires that all GPU memory has been loaded already.
|
||||||
Dirty();
|
Dirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "VideoCommon/BPMemory.h"
|
#include "VideoCommon/BPMemory.h"
|
||||||
#include "VideoCommon/ConstantManager.h"
|
#include "VideoCommon/ConstantManager.h"
|
||||||
#include "VideoCommon/PixelShaderGen.h"
|
#include "VideoCommon/PixelShaderGen.h"
|
||||||
|
@ -24,8 +26,11 @@ public:
|
||||||
|
|
||||||
static void SetConstants(); // sets pixel shader constants
|
static void SetConstants(); // sets pixel shader constants
|
||||||
|
|
||||||
// constant management, should be called after memory is committed
|
// constant management
|
||||||
static void SetColorChanged(int type, int index);
|
// Some of these functions grab the constant values from global state,
|
||||||
|
// so make sure to call them after memory is committed
|
||||||
|
static void SetTevColor(int index, int component, s32 value);
|
||||||
|
static void SetTevKonstColor(int index, int component, s32 value);
|
||||||
static void SetAlpha();
|
static void SetAlpha();
|
||||||
static void SetDestAlpha();
|
static void SetDestAlpha();
|
||||||
static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt);
|
static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt);
|
||||||
|
@ -42,4 +47,12 @@ public:
|
||||||
|
|
||||||
static PixelShaderConstants constants;
|
static PixelShaderConstants constants;
|
||||||
static bool dirty;
|
static bool dirty;
|
||||||
|
|
||||||
|
static bool s_bFogRangeAdjustChanged;
|
||||||
|
static bool s_bViewPortChanged;
|
||||||
|
|
||||||
|
// These colors aren't available from global BP state,
|
||||||
|
// hence we keep a copy of them around.
|
||||||
|
static std::array<int4,4> s_tev_color;
|
||||||
|
static std::array<int4,4> s_tev_konst_color;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue