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
|
||||
// - Serialization code for anything complex has to be manually written.
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
|
@ -159,6 +160,12 @@ public:
|
|||
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>
|
||||
void DoArray(T* x, u32 count)
|
||||
{
|
||||
|
|
|
@ -63,7 +63,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
|||
static std::thread g_save_thread;
|
||||
|
||||
// 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
|
||||
{
|
||||
|
|
|
@ -145,10 +145,10 @@ void SWBPWritten(int address, int newvalue)
|
|||
}
|
||||
break;
|
||||
|
||||
case BPMEM_TEV_REGISTER_L: // Reg 1
|
||||
case BPMEM_TEV_REGISTER_L+2: // Reg 2
|
||||
case BPMEM_TEV_REGISTER_L+4: // Reg 3
|
||||
case BPMEM_TEV_REGISTER_L+6: // Reg 4
|
||||
case BPMEM_TEV_COLOR_RA:
|
||||
case BPMEM_TEV_COLOR_RA + 2:
|
||||
case BPMEM_TEV_COLOR_RA + 4:
|
||||
case BPMEM_TEV_COLOR_RA + 6:
|
||||
{
|
||||
int regNum = (address >> 1 ) & 0x3;
|
||||
TevReg& reg = bpmem.tevregs[regNum];
|
||||
|
@ -160,10 +160,10 @@ void SWBPWritten(int address, int newvalue)
|
|||
break;
|
||||
}
|
||||
|
||||
case BPMEM_TEV_REGISTER_H: // Reg 1
|
||||
case BPMEM_TEV_REGISTER_H+2: // Reg 2
|
||||
case BPMEM_TEV_REGISTER_H+4: // Reg 3
|
||||
case BPMEM_TEV_REGISTER_H+6: // Reg 4
|
||||
case BPMEM_TEV_COLOR_BG:
|
||||
case BPMEM_TEV_COLOR_BG + 2:
|
||||
case BPMEM_TEV_COLOR_BG + 4:
|
||||
case BPMEM_TEV_COLOR_BG + 6:
|
||||
{
|
||||
int regNum = (address >> 1 ) & 0x3;
|
||||
TevReg& reg = bpmem.tevregs[regNum];
|
||||
|
|
|
@ -80,8 +80,8 @@
|
|||
#define BPMEM_TX_SETTLUT_4 0xB8 // 0xB8 + 4
|
||||
#define BPMEM_TEV_COLOR_ENV 0xC0 // 0xC0 + (2 * 16)
|
||||
#define BPMEM_TEV_ALPHA_ENV 0xC1 // 0xC1 + (2 * 16)
|
||||
#define BPMEM_TEV_REGISTER_L 0xE0 // 0xE0 + (2 * 4)
|
||||
#define BPMEM_TEV_REGISTER_H 0xE1 // 0xE1 + (2 * 4)
|
||||
#define BPMEM_TEV_COLOR_RA 0xE0 // 0xE0 + (2 * 4)
|
||||
#define BPMEM_TEV_COLOR_BG 0xE1 // 0xE1 + (2 * 4)
|
||||
#define BPMEM_FOGRANGE 0xE8 // 0xE8 + 6
|
||||
#define BPMEM_FOGPARAM0 0xEE
|
||||
#define BPMEM_FOGBMAGNITUDE 0xEF
|
||||
|
@ -853,6 +853,8 @@ union TevReg
|
|||
BitField< 0, 32,u64> low;
|
||||
BitField<32, 32,u64> high;
|
||||
|
||||
// TODO: Check if Konst uses all 11 bits or just 8
|
||||
|
||||
// Low register
|
||||
BitField< 0,11,s64> red;
|
||||
|
||||
|
|
|
@ -480,6 +480,55 @@ static void BPWritten(const BPCmd& bp)
|
|||
}
|
||||
}
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
@ -548,29 +597,6 @@ static void BPWritten(const BPCmd& bp)
|
|||
case BPMEM_TX_SETTLUT_4:
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
@ -1213,19 +1239,19 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
|
|||
break;
|
||||
}
|
||||
|
||||
case BPMEM_TEV_REGISTER_L: // 0xE0
|
||||
case BPMEM_TEV_REGISTER_L+2:
|
||||
case BPMEM_TEV_REGISTER_L+4:
|
||||
case BPMEM_TEV_REGISTER_L+6:
|
||||
SetRegName(BPMEM_TEV_REGISTER_L);
|
||||
case BPMEM_TEV_COLOR_RA: // 0xE0
|
||||
case BPMEM_TEV_COLOR_RA + 2: // 0xE2
|
||||
case BPMEM_TEV_COLOR_RA + 4: // 0xE4
|
||||
case BPMEM_TEV_COLOR_RA + 6: // 0xE6
|
||||
SetRegName(BPMEM_TEV_COLOR_RA);
|
||||
// TODO: Description
|
||||
break;
|
||||
|
||||
case BPMEM_TEV_REGISTER_H: // 0xE1
|
||||
case BPMEM_TEV_REGISTER_H+2:
|
||||
case BPMEM_TEV_REGISTER_H+4:
|
||||
case BPMEM_TEV_REGISTER_H+6:
|
||||
SetRegName(BPMEM_TEV_REGISTER_H);
|
||||
case BPMEM_TEV_COLOR_BG: // 0xE1
|
||||
case BPMEM_TEV_COLOR_BG + 2: // 0xE3
|
||||
case BPMEM_TEV_COLOR_BG + 4: // 0xE5
|
||||
case BPMEM_TEV_COLOR_BG + 6: // 0xE7
|
||||
SetRegName(BPMEM_TEV_COLOR_BG);
|
||||
// TODO: Description
|
||||
break;
|
||||
|
||||
|
|
|
@ -12,8 +12,11 @@
|
|||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
static bool s_bFogRangeAdjustChanged;
|
||||
static bool s_bViewPortChanged;
|
||||
bool PixelShaderManager::s_bFogRangeAdjustChanged;
|
||||
bool PixelShaderManager::s_bViewPortChanged;
|
||||
|
||||
std::array<int4,4> PixelShaderManager::s_tev_color;
|
||||
std::array<int4,4> PixelShaderManager::s_tev_konst_color;
|
||||
|
||||
PixelShaderConstants PixelShaderManager::constants;
|
||||
bool PixelShaderManager::dirty;
|
||||
|
@ -21,6 +24,9 @@ bool PixelShaderManager::dirty;
|
|||
void PixelShaderManager::Init()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -29,14 +35,15 @@ void PixelShaderManager::Dirty()
|
|||
s_bFogRangeAdjustChanged = true;
|
||||
s_bViewPortChanged = true;
|
||||
|
||||
SetColorChanged(0, 0);
|
||||
SetColorChanged(0, 1);
|
||||
SetColorChanged(0, 2);
|
||||
SetColorChanged(0, 3);
|
||||
SetColorChanged(1, 0);
|
||||
SetColorChanged(1, 1);
|
||||
SetColorChanged(1, 2);
|
||||
SetColorChanged(1, 3);
|
||||
for (unsigned index = 0; index < s_tev_color.size(); ++index)
|
||||
{
|
||||
for (int comp = 0; comp < 4; ++comp)
|
||||
{
|
||||
SetTevColor(index, comp, s_tev_color[index][comp]);
|
||||
SetTevKonstColor(index, comp, s_tev_konst_color[index][comp]);
|
||||
}
|
||||
}
|
||||
|
||||
SetAlpha();
|
||||
SetDestAlpha();
|
||||
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;
|
||||
c[num][0] = static_cast<s32>(bpmem.tevregs[num].red);
|
||||
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);
|
||||
auto& c = constants.colors[index];
|
||||
c[component] = s_tev_color[index][component] = value;
|
||||
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()
|
||||
|
@ -265,11 +278,13 @@ void PixelShaderManager::SetFogRangeAdjustChanged()
|
|||
|
||||
void PixelShaderManager::DoState(PointerWrap &p)
|
||||
{
|
||||
p.Do(constants);
|
||||
p.Do(dirty);
|
||||
p.DoArray(s_tev_color);
|
||||
p.DoArray(s_tev_konst_color);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "VideoCommon/BPMemory.h"
|
||||
#include "VideoCommon/ConstantManager.h"
|
||||
#include "VideoCommon/PixelShaderGen.h"
|
||||
|
@ -24,8 +26,11 @@ public:
|
|||
|
||||
static void SetConstants(); // sets pixel shader constants
|
||||
|
||||
// constant management, should be called after memory is committed
|
||||
static void SetColorChanged(int type, int index);
|
||||
// constant management
|
||||
// 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 SetDestAlpha();
|
||||
static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt);
|
||||
|
@ -42,4 +47,12 @@ public:
|
|||
|
||||
static PixelShaderConstants constants;
|
||||
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