summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorTony Wasserka <neobrainx@gmail.com>2014-09-21 10:51:27 +0200
committerTony Wasserka <neobrainx@gmail.com>2014-09-21 10:51:27 +0200
commit124df2e1348938b3e44e9cedc6abc2a0054600d1 (patch)
tree910100a61cf6d7b5d0dbdd712bdacd622858903e /Source/Core/VideoCommon
parent536582b2ebf62e103b89b34c5d8e9099b6d7082e (diff)
parent1d23c2ca8bfe41549970dc77da7d4b21950e11e6 (diff)
Merge pull request #1102 from neobrain/tevreg_loading
GPU: Only load the relevant color components upon writes to the tev color registers
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/BPMemory.h6
-rw-r--r--Source/Core/VideoCommon/BPStructs.cpp92
-rw-r--r--Source/Core/VideoCommon/PixelShaderManager.cpp53
-rw-r--r--Source/Core/VideoCommon/PixelShaderManager.h17
4 files changed, 112 insertions, 56 deletions
diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h
index 3e5867c418..0d50f3ac51 100644
--- a/Source/Core/VideoCommon/BPMemory.h
+++ b/Source/Core/VideoCommon/BPMemory.h
@@ -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;
diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp
index 5910488f3c..308badae6e 100644
--- a/Source/Core/VideoCommon/BPStructs.cpp
+++ b/Source/Core/VideoCommon/BPStructs.cpp
@@ -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;
diff --git a/Source/Core/VideoCommon/PixelShaderManager.cpp b/Source/Core/VideoCommon/PixelShaderManager.cpp
index d9c601e42c..cbd68ce92e 100644
--- a/Source/Core/VideoCommon/PixelShaderManager.cpp
+++ b/Source/Core/VideoCommon/PixelShaderManager.cpp
@@ -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)
+{
+ auto& c = constants.colors[index];
+ c[component] = s_tev_color[index][component] = value;
+ dirty = true;
+
+ 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)
{
- 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.kcolors[index];
+ c[component] = s_tev_konst_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 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();
}
}
diff --git a/Source/Core/VideoCommon/PixelShaderManager.h b/Source/Core/VideoCommon/PixelShaderManager.h
index 5c07b0522a..ebf299d9fc 100644
--- a/Source/Core/VideoCommon/PixelShaderManager.h
+++ b/Source/Core/VideoCommon/PixelShaderManager.h
@@ -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;
};