30 changes: 21 additions & 9 deletions Source/Core/VideoCommon/Src/CommandProcessor.cpp
Expand Up @@ -115,13 +115,13 @@ void Init()
fifo.CPCmdIdle = 1;
fifo.CPReadIdle = 1;
fifo.bFF_Breakpoint = 0;
fifo.bFF_HiWatermark = 0;
fifo.bFF_HiWatermark = 0;
fifo.bFF_HiWatermarkInt = 0;
fifo.bFF_LoWatermark = 0;
fifo.bFF_LoWatermark = 0;
fifo.bFF_LoWatermarkInt = 0;

interruptSet = false;
interruptWaiting = false;
interruptWaiting = false;
interruptFinishWaiting = false;
interruptTokenWaiting = false;

Expand All @@ -131,15 +131,15 @@ void Init()
isHiWatermarkActive = false;
isLoWatermarkActive = false;

et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper);
et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper);
}

void Read16(u16& _rReturnValue, const u32 _Address)
{
INFO_LOG(COMMANDPROCESSOR, "(r): 0x%08x", _Address);
switch (_Address & 0xFFF)
{
case STATUS_REGISTER:
case STATUS_REGISTER:
SetCpStatusRegister();
_rReturnValue = m_CPStatusReg.Hex;
return;
Expand All @@ -166,22 +166,30 @@ void Read16(u16& _rReturnValue, const u32 _Address)

case FIFO_RW_DISTANCE_LO:
if (IsOnThread())
{
if(fifo.CPWritePointer >= fifo.SafeCPReadPointer)
_rReturnValue = ReadLow (fifo.CPWritePointer - fifo.SafeCPReadPointer);
else
_rReturnValue = ReadLow (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32);
}
else
{
_rReturnValue = ReadLow (fifo.CPReadWriteDistance);
}
DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue);
return;
case FIFO_RW_DISTANCE_HI:
if (IsOnThread())
{
if(fifo.CPWritePointer >= fifo.SafeCPReadPointer)
_rReturnValue = ReadHigh (fifo.CPWritePointer - fifo.SafeCPReadPointer);
else
_rReturnValue = ReadHigh (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32);
}
else
{
_rReturnValue = ReadHigh(fifo.CPReadWriteDistance);
}
DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_RW_DISTANCE_HI : %04x", _rReturnValue);
return;
case FIFO_WRITE_POINTER_LO:
Expand Down Expand Up @@ -437,7 +445,9 @@ void STACKALIGN GatherPipeBursted()
if (!m_CPCtrlReg.GPLinkEnable)
{
if (!IsOnThread())
{
RunGpu();
}
else
{
// In multibuffer mode is not allowed write in the same FIFO attached to the GPU.
Expand Down Expand Up @@ -467,7 +477,7 @@ void STACKALIGN GatherPipeBursted()
if (!IsOnThread())
RunGpu();

_assert_msg_(COMMANDPROCESSOR, fifo.CPReadWriteDistance <= fifo.CPEnd - fifo.CPBase,
_assert_msg_(COMMANDPROCESSOR, fifo.CPReadWriteDistance <= fifo.CPEnd - fifo.CPBase,
"FIFO is overflowed by GatherPipe !\nCPU thread is too fast!");

// check if we are in sync
Expand All @@ -482,13 +492,13 @@ void UpdateInterrupts(u64 userdata)
{
interruptSet = true;
INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
}
else
{
interruptSet = false;
INFO_LOG(COMMANDPROCESSOR,"Interrupt cleared");
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false);
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false);
}
interruptWaiting = false;
}
Expand All @@ -510,7 +520,7 @@ void SetCpStatus(bool isCPUThread)
fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark);

// breakpoint
// breakpoint
if (!isCPUThread)
{
if (fifo.bFF_BPEnable)
Expand Down Expand Up @@ -571,7 +581,9 @@ void SetCpStatus(bool isCPUThread)
}
}
else
{
CommandProcessor::UpdateInterrupts(userdata);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/Src/CommandProcessor.h
Expand Up @@ -75,7 +75,7 @@ enum
enum
{
GATHER_PIPE_SIZE = 32,
INT_CAUSE_CP = 0x800
INT_CAUSE_CP = 0x800
};

// Fifo Status Register
Expand Down
7 changes: 5 additions & 2 deletions Source/Core/VideoCommon/Src/EmuWindow.cpp
Expand Up @@ -68,6 +68,7 @@ void FreeLookInput( UINT iMsg, WPARAM wParam )
static bool mouseMoveEnabled = false;
static float lastMouse[2];
POINT point;

switch(iMsg)
{
case WM_USER_KEYDOWN:
Expand Down Expand Up @@ -99,14 +100,16 @@ void FreeLookInput( UINT iMsg, WPARAM wParam )
break;

case WM_MOUSEMOVE:
if (mouseLookEnabled) {
if (mouseLookEnabled)
{
GetCursorPos(&point);
VertexShaderManager::RotateView((point.x - lastMouse[0]) / 200.0f, (point.y - lastMouse[1]) / 200.0f);
lastMouse[0] = (float)point.x;
lastMouse[1] = (float)point.y;
}

if (mouseMoveEnabled) {
if (mouseMoveEnabled)
{
GetCursorPos(&point);
VertexShaderManager::TranslateView((point.x - lastMouse[0]) / 50.0f, (point.y - lastMouse[1]) / 50.0f);
lastMouse[0] = (float)point.x;
Expand Down
15 changes: 10 additions & 5 deletions Source/Core/VideoCommon/Src/Fifo.cpp
Expand Up @@ -151,7 +151,8 @@ void RunGpuLoop()
// check if we are able to run this buffer
while (GpuRunningState && !CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint())
{
if (!GpuRunningState) break;
if (!GpuRunningState)
break;

fifo.isGpuReadingData = true;
CommandProcessor::isPossibleWaitingSetDrawDone = fifo.bFF_GPLinkEnable ? true : false;
Expand All @@ -161,8 +162,10 @@ void RunGpuLoop()
u32 readPtr = fifo.CPReadPointer;
u8 *uData = Memory::GetPointer(readPtr);

if (readPtr == fifo.CPEnd) readPtr = fifo.CPBase;
else readPtr += 32;
if (readPtr == fifo.CPEnd)
readPtr = fifo.CPBase;
else
readPtr += 32;

_assert_msg_(COMMANDPROCESSOR, (s32)fifo.CPReadWriteDistance - 32 >= 0 ,
"Negative fifo.CPReadWriteDistance = %i in FIFO Loop !\nThat can produce instability in the game. Please report it.", fifo.CPReadWriteDistance - 32);
Expand Down Expand Up @@ -236,8 +239,10 @@ void RunGpu()

//DEBUG_LOG(COMMANDPROCESSOR, "Fifo wraps to base");

if (fifo.CPReadPointer == fifo.CPEnd) fifo.CPReadPointer = fifo.CPBase;
else fifo.CPReadPointer += 32;
if (fifo.CPReadPointer == fifo.CPEnd)
fifo.CPReadPointer = fifo.CPBase;
else
fifo.CPReadPointer += 32;

fifo.CPReadWriteDistance -= 32;
}
Expand Down
7 changes: 6 additions & 1 deletion Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp
Expand Up @@ -36,7 +36,8 @@ FramebufferManagerBase::~FramebufferManagerBase()

const XFBSourceBase* const* FramebufferManagerBase::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
{
if (!g_ActiveConfig.bUseXFB) return NULL;
if (!g_ActiveConfig.bUseXFB)
return NULL;

if (g_ActiveConfig.bUseRealXFB)
return GetRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
Expand Down Expand Up @@ -237,7 +238,9 @@ int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x, unsigned int backbuffe
return x * (int)backbuffer_width / (int)FramebufferManagerBase::LastXfbWidth();
}
else
{
return x * (int)Renderer::GetTargetRectangle().GetWidth() / (int)FramebufferManagerBase::LastXfbWidth();
}
}

int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height)
Expand All @@ -251,5 +254,7 @@ int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y, unsigned int backbuff
return y * (int)backbuffer_height / (int)FramebufferManagerBase::LastXfbHeight();
}
else
{
return y * (int)Renderer::GetTargetRectangle().GetHeight() / (int)FramebufferManagerBase::LastXfbHeight();
}
}
26 changes: 19 additions & 7 deletions Source/Core/VideoCommon/Src/IndexGenerator.cpp
Expand Up @@ -92,15 +92,18 @@ template <bool pr> void IndexGenerator::AddList(u32 const numVerts)

template <bool pr> void IndexGenerator::AddStrip(u32 const numVerts)
{
if(pr) {
if(pr)
{
for (u32 i = 0; i < numVerts; ++i)
{
*Tptr++ = index + i;
}
*Tptr++ = s_primitive_restart;
numT += numVerts - 2;

} else {
}
else
{
bool wind = false;
for (u32 i = 2; i < numVerts; ++i)
{
Expand Down Expand Up @@ -137,8 +140,10 @@ template <bool pr> void IndexGenerator::AddFan(u32 numVerts)
{
u32 i = 2;

if(pr) {
for(; i<=numVerts-3; i+=3) {
if(pr)
{
for(; i<=numVerts-3; i+=3)
{
*Tptr++ = index + i - 1;
*Tptr++ = index + i + 0;
*Tptr++ = index;
Expand All @@ -148,7 +153,8 @@ template <bool pr> void IndexGenerator::AddFan(u32 numVerts)
numT += 3;
}

for(; i<=numVerts-2; i+=2) {
for(; i<=numVerts-2; i+=2)
{
*Tptr++ = index + i - 1;
*Tptr++ = index + i + 0;
*Tptr++ = index;
Expand Down Expand Up @@ -186,26 +192,32 @@ template <bool pr> void IndexGenerator::AddQuads(u32 numVerts)
auto const numQuads = numVerts / 4;
for (u32 i = 0; i != numQuads; ++i)
{
if(pr) {
if(pr)
{
*Tptr++ = index + i * 4 + 1;
*Tptr++ = index + i * 4 + 2;
*Tptr++ = index + i * 4 + 0;
*Tptr++ = index + i * 4 + 3;
*Tptr++ = s_primitive_restart;
numT += 2;
} else {
}
else
{
WriteTriangle<pr>(index + i * 4, index + i * 4 + 1, index + i * 4 + 2);
WriteTriangle<pr>(index + i * 4, index + i * 4 + 2, index + i * 4 + 3);
}
}

// three vertices remaining, so render a triangle
u32 remainingVerts = numVerts - numQuads*4;
if(remainingVerts == 3)
{
WriteTriangle<pr>(index+numVerts-3, index+numVerts-2, index+numVerts-1);
}
else if(remainingVerts)
{
ERROR_LOG(VIDEO, "AddQuads: unknown count of vertices found");
}
}

// Lines
Expand Down
51 changes: 35 additions & 16 deletions Source/Core/VideoCommon/Src/LightingShaderGen.cpp
Expand Up @@ -27,12 +27,17 @@ int GetLightingShaderId(u32* out)
char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char* lightsName, int coloralpha)
{
const char* swizzle = "xyzw";
if (coloralpha == 1 ) swizzle = "xyz";
else if (coloralpha == 2 ) swizzle = "w";

if (!(chan.attnfunc & 1)) {
// atten disabled
switch (chan.diffusefunc) {
if (coloralpha == 1 )
swizzle = "xyz";
else if (coloralpha == 2 )
swizzle = "w";

if (!(chan.attnfunc & 1))
{
// attenuation disabled
switch (chan.diffusefunc)
{
case LIGHTDIF_NONE:
WRITE(p, "lacc.%s += %s[%d].%s;\n", swizzle, lightsName, index * 5, swizzle);
break;
Expand All @@ -45,8 +50,8 @@ char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char
default: _assert_(0);
}
}
else { // spec and spot
else // spec and spot
{
if (chan.attnfunc == 3)
{ // spot
WRITE(p, "ldir = %s[%d + 3].xyz - pos.xyz;\n", lightsName, index * 5);
Expand Down Expand Up @@ -74,13 +79,13 @@ char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char
swizzle,
chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(",
lightsName,
index * 5,
index * 5,
swizzle);
break;
default: _assert_(0);
}
}
WRITE(p, "\n");
WRITE(p, "\n");
return p;
}

Expand All @@ -98,7 +103,8 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName,

WRITE(p, "{\n");

if (color.matsource) {// from vertex
if (color.matsource) // from vertex
{
if (components & (VB_HAS_COL0 << j))
WRITE(p, "mat = %s%d;\n", inColorName, j);
else if (components & VB_HAS_COL0)
Expand All @@ -107,10 +113,14 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName,
WRITE(p, "mat = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
}
else // from color
{
WRITE(p, "mat = %s[%d];\n", materialsName, j+2);
}

if (color.enablelighting) {
if (color.ambsource) { // from vertex
if (color.enablelighting)
{
if (color.ambsource) // from vertex
{
if (components & (VB_HAS_COL0<<j) )
WRITE(p, "lacc = %s%d;\n", inColorName, j);
else if (components & VB_HAS_COL0 )
Expand All @@ -119,29 +129,36 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName,
WRITE(p, "lacc = float4(0.0f, 0.0f, 0.0f, 0.0f);\n");
}
else // from color
{
WRITE(p, "lacc = %s[%d];\n", materialsName, j);
}
}
else
{
WRITE(p, "lacc = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
}

// check if alpha is different
if (alpha.matsource != color.matsource) {
if (alpha.matsource) {// from vertex
if (alpha.matsource != color.matsource)
{
if (alpha.matsource) // from vertex
{
if (components & (VB_HAS_COL0<<j))
WRITE(p, "mat.w = %s%d.w;\n", inColorName, j);
else if (components & VB_HAS_COL0)
WRITE(p, "mat.w = %s0.w;\n", inColorName);
else WRITE(p, "mat.w = 1.0f;\n");
}
else // from color
{
WRITE(p, "mat.w = %s[%d].w;\n", materialsName, j+2);
}
}

if (alpha.enablelighting)
{
if (alpha.ambsource) {// from vertex
if (alpha.ambsource) // from vertex
{
if (components & (VB_HAS_COL0<<j) )
WRITE(p, "lacc.w = %s%d.w;\n", inColorName, j);
else if (components & VB_HAS_COL0 )
Expand All @@ -150,12 +167,14 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName,
WRITE(p, "lacc.w = 0.0f;\n");
}
else // from color
{
WRITE(p, "lacc.w = %s[%d].w;\n", materialsName, j);
}
}
else
{
WRITE(p, "lacc.w = 1.0f;\n");
}
}

if(color.enablelighting && alpha.enablelighting)
{
Expand Down
7 changes: 6 additions & 1 deletion Source/Core/VideoCommon/Src/MainBase.cpp
Expand Up @@ -230,9 +230,13 @@ void VideoBackendHardware::DoState(PointerWrap& p)
{
bool software = false;
p.Do(software);

if (p.GetMode() == PointerWrap::MODE_READ && software == true)
{
// change mode to abort load of incompatible save state.
p.SetMode(PointerWrap::MODE_VERIFY);
}

VideoCommon_DoState(p);
p.DoMarker("VideoCommon");

Expand All @@ -255,7 +259,8 @@ void VideoBackendHardware::DoState(PointerWrap& p)
}
}

void VideoBackendHardware::CheckInvalidState() {
void VideoBackendHardware::CheckInvalidState()
{
if (m_invalid)
{
m_invalid = false;
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/VideoCommon/Src/NativeVertexFormat.h
Expand Up @@ -21,7 +21,8 @@
#include "Common.h"

// m_components
enum {
enum
{
VB_HAS_POSMTXIDX =(1<<1),
VB_HAS_TEXMTXIDX0=(1<<2),
VB_HAS_TEXMTXIDX1=(1<<3),
Expand Down
18 changes: 14 additions & 4 deletions Source/Core/VideoCommon/Src/OnScreenDisplay.cpp
Expand Up @@ -19,7 +19,8 @@ namespace OSD
struct MESSAGE
{
MESSAGE() {}
MESSAGE(const char* p, u32 dw) {
MESSAGE(const char* p, u32 dw)
{
strncpy(str, p, 255);
str[255] = '\0';
dwTimeStamp = dw;
Expand All @@ -45,8 +46,10 @@ class OSDCALLBACK
{
m_functionptr(m_data);
}

CallbackType Type() { return m_type; }
};

std::vector<OSDCALLBACK> m_callbacks;
static std::list<MESSAGE> s_listMsgs;

Expand All @@ -57,7 +60,8 @@ void AddMessage(const char* pstr, u32 ms)

void DrawMessages()
{
if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bOnScreenDisplayMessages) return;
if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bOnScreenDisplayMessages)
return;

if (s_listMsgs.size() > 0)
{
Expand All @@ -71,7 +75,8 @@ void DrawMessages()
if (time_left < 1024)
{
alpha = time_left >> 2;
if (time_left < 0) alpha = 0;
if (time_left < 0)
alpha = 0;
}

alpha <<= 24;
Expand All @@ -91,8 +96,11 @@ void DrawMessages()
void ClearMessages()
{
std::list<MESSAGE>::iterator it = s_listMsgs.begin();
while (it != s_listMsgs.end())

while (it != s_listMsgs.end())
{
it = s_listMsgs.erase(it);
}
}

// On-Screen Display Callbacks
Expand All @@ -104,8 +112,10 @@ void AddCallback(CallbackType OnType, CallbackPtr FuncPtr, u32 UserData)
void DoCallbacks(CallbackType OnType)
{
for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
{
if (it->Type() == OnType)
it->Call();
}
}

} // namespace
60 changes: 38 additions & 22 deletions Source/Core/VideoCommon/Src/PixelShaderGen.cpp
Expand Up @@ -61,7 +61,8 @@ static void StageHash(u32 stage, u32* out)
out[3] |= bpmem.tevorders[stage/2].getEnable(stage&1);
if (bpmem.tevorders[stage/2].getEnable(stage&1))
{
if (bHasIndStage) needstexcoord = true;
if (bHasIndStage)
needstexcoord = true;

out[0] |= bpmem.combiners[stage].alphaC.tswap;
out[3] |= bpmem.tevksel[bpmem.combiners[stage].alphaC.tswap*2].swap1 << 1; // 2
Expand Down Expand Up @@ -98,20 +99,27 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
bool enablePL = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
uid->values[0] |= enablePL << 10; // 1

if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4
if (!enablePL)
{
uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4
}

AlphaTest::TEST_RESULT alphaPreTest = bpmem.alpha_test.TestResult();
uid->values[0] |= alphaPreTest << 15; // 2

// numtexgens should be <= 8
for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i)
{
uid->values[0] |= xfregs.texMtxInfo[i].projection << (17+i); // 1
}

uid->values[1] = bpmem.genMode.numindstages; // 3
u32 indirectStagesUsed = 0;
for (unsigned int i = 0; i < bpmem.genMode.numindstages; ++i)
{
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
indirectStagesUsed |= (1 << bpmem.tevind[i].bt);
}

assert(indirectStagesUsed == (indirectStagesUsed & 0xF));

Expand Down Expand Up @@ -255,7 +263,7 @@ void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::
//
// color for this stage (alpha, color) is given by bpmem.tevorders[0].colorchan0
// konstant for this stage (alpha, color) is given by bpmem.tevksel
// inputs are given by bpmem.combiners[0].colorC.a/b/c/d << could be current chan color
// inputs are given by bpmem.combiners[0].colorC.a/b/c/d << could be current channel color
// according to GXTevColorArg table above
// output is given by .outreg
// tevtemp is set according to swapmodetables and
Expand All @@ -268,7 +276,7 @@ static void WriteFog(char *&p);

static const char *tevKSelTableC[] = // KCSEL
{
"1.0f,1.0f,1.0f", // 1 = 0x00
"1.0f,1.0f,1.0f", // 1 = 0x00
"0.875f,0.875f,0.875f", // 7_8 = 0x01
"0.75f,0.75f,0.75f", // 3_4 = 0x02
"0.625f,0.625f,0.625f", // 5_8 = 0x03
Expand Down Expand Up @@ -407,7 +415,7 @@ static const char *tevAInputTable[] = // CA
"rastemp", // RASA,
"konsttemp", // KONST, (hw1 had quarter)
"float4(0.0f, 0.0f, 0.0f, 0.0f)", // ZERO
///aded extra values to map clamped values
///added extra values to map clamped values
"cprev", // APREV,
"cc0", // A0,
"cc1", // A1,
Expand Down Expand Up @@ -827,7 +835,9 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
}

if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
{
WRITE(p, "\tocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n");
}
else
{
WriteFog(p);
Expand Down Expand Up @@ -959,10 +969,14 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
WRITE(p, "float2 indtevtrans%d = " I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n);
}
else
{
WRITE(p, "float2 indtevtrans%d = float2(0.0f, 0.0f);\n", n);
}
}
else
{
WRITE(p, "float2 indtevtrans%d = float2(0.0f, 0.0f);\n", n);
}

// ---------
// Wrapping
Expand Down Expand Up @@ -1022,7 +1036,9 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
SampleTexture(p, "textemp", "tevcoord", texswap, texmap, ApiType);
}
else
{
WRITE(p, "textemp = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
}


if (cc.a == TEVCOLORARG_KONST || cc.b == TEVCOLORARG_KONST || cc.c == TEVCOLORARG_KONST || cc.d == TEVCOLORARG_KONST
Expand Down Expand Up @@ -1226,14 +1242,14 @@ void SampleTexture(char *&p, const char *destination, const char *texcoords, con

static const char *tevAlphaFuncsTable[] =
{
"(false)", //ALPHACMP_NEVER 0
"(prev.a <= %s - (0.25f/255.0f))", //ALPHACMP_LESS 1
"(abs( prev.a - %s ) < (0.5f/255.0f))", //ALPHACMP_EQUAL 2
"(prev.a < %s + (0.25f/255.0f))", //ALPHACMP_LEQUAL 3
"(false)", //ALPHACMP_NEVER 0
"(prev.a <= %s - (0.25f/255.0f))", //ALPHACMP_LESS 1
"(abs( prev.a - %s ) < (0.5f/255.0f))", //ALPHACMP_EQUAL 2
"(prev.a < %s + (0.25f/255.0f))", //ALPHACMP_LEQUAL 3
"(prev.a >= %s + (0.25f/255.0f))", //ALPHACMP_GREATER 4
"(abs( prev.a - %s ) >= (0.5f/255.0f))", //ALPHACMP_NEQUAL 5
"(prev.a > %s - (0.25f/255.0f))", //ALPHACMP_GEQUAL 6
"(true)" //ALPHACMP_ALWAYS 7
"(abs( prev.a - %s ) >= (0.5f/255.0f))", //ALPHACMP_NEQUAL 5
"(prev.a > %s - (0.25f/255.0f))", //ALPHACMP_GEQUAL 6
"(true)" //ALPHACMP_ALWAYS 7
};

static const char *tevAlphaFunclogicTable[] =
Expand All @@ -1250,7 +1266,7 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode
{
I_ALPHA"[0].r",
I_ALPHA"[0].g"
};
};


// using discard then return works the same in cg and dx9 but not in dx11
Expand All @@ -1275,7 +1291,7 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode
// or after texturing and alpha test. PC GPUs have no way to support this
// feature properly as of 2012: depth buffer and depth test are not
// programmable and the depth test is always done after texturing.
// Most importantly, PC GPUs do not allow writing to the z buffer without
// Most importantly, PC GPUs do not allow writing to the z-buffer without
// writing a color value (unless color writing is disabled altogether).
// We implement "depth test before texturing" by discarding the fragment
// when the alpha test fail. This is not a correct implementation because
Expand All @@ -1293,14 +1309,14 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode

static const char *tevFogFuncsTable[] =
{
"", //No Fog
"", //?
"", //Linear
"", //?
"\tfog = 1.0f - pow(2.0f, -8.0f * fog);\n", //exp
"\tfog = 1.0f - pow(2.0f, -8.0f * fog * fog);\n", //exp2
"\tfog = pow(2.0f, -8.0f * (1.0f - fog));\n", //backward exp
"\tfog = 1.0f - fog;\n fog = pow(2.0f, -8.0f * fog * fog);\n" //backward exp2
"", // No Fog
"", // ?
"", // Linear
"", // ?
"\tfog = 1.0f - pow(2.0f, -8.0f * fog);\n", // exp
"\tfog = 1.0f - pow(2.0f, -8.0f * fog * fog);\n", // exp2
"\tfog = pow(2.0f, -8.0f * (1.0f - fog));\n", // backward exp
"\tfog = 1.0f - fog;\n fog = pow(2.0f, -8.0f * fog * fog);\n" // backward exp2
};

static void WriteFog(char *&p)
Expand Down
20 changes: 16 additions & 4 deletions Source/Core/VideoCommon/Src/PixelShaderGen.h
Expand Up @@ -62,46 +62,58 @@ class _PIXELSHADERUID
_PIXELSHADERUID(const _PIXELSHADERUID& r)
{
num_values = r.num_values;
if (safe) memcpy(values, r.values, PIXELSHADERUID_MAX_VALUES_SAFE);
else memcpy(values, r.values, r.GetNumValues() * sizeof(values[0]));

if (safe)
memcpy(values, r.values, PIXELSHADERUID_MAX_VALUES_SAFE);
else
memcpy(values, r.values, r.GetNumValues() * sizeof(values[0]));
}

int GetNumValues() const
{
if (safe) return (sizeof(values) / sizeof(u32));
else return num_values;
if (safe)
return (sizeof(values) / sizeof(u32));
else
return num_values;
}

bool operator <(const _PIXELSHADERUID& _Right) const
{
int N = GetNumValues();

if (N < _Right.GetNumValues())
return true;
else if (N > _Right.GetNumValues())
return false;

for (int i = 0; i < N; ++i)
{
if (values[i] < _Right.values[i])
return true;
else if (values[i] > _Right.values[i])
return false;
}

return false;
}

bool operator ==(const _PIXELSHADERUID& _Right) const
{
int N = GetNumValues();

if (N != _Right.GetNumValues())
return false;

for (int i = 0; i < N; ++i)
{
if (values[i] != _Right.values[i])
return false;
}

return true;
}
};

typedef _PIXELSHADERUID<false> PIXELSHADERUID;
typedef _PIXELSHADERUID<true> PIXELSHADERUIDSAFE;

Expand Down
20 changes: 16 additions & 4 deletions Source/Core/VideoCommon/Src/PixelShaderManager.cpp
Expand Up @@ -74,6 +74,7 @@ void PixelShaderManager::SetConstants()
{
if (g_ActiveConfig.backend_info.APIType == API_OPENGL && !g_ActiveConfig.backend_info.bSupportsGLSLUBO)
Dirty();

for (int i = 0; i < 2; ++i)
{
if (s_nColorsChanged[i])
Expand Down Expand Up @@ -158,8 +159,10 @@ void PixelShaderManager::SetConstants()
SetPSConstant4fv(C_INDTEXSCALE, f);
}

if (s_nIndTexScaleChanged & 0x0c) {
for (u32 i = 2; i < 4; ++i) {
if (s_nIndTexScaleChanged & 0x0c)
{
for (u32 i = 2; i < 4; ++i)
{
f[2 * i] = bpmem.texscale[1].getScaleS(i & 1);
f[2 * i + 1] = bpmem.texscale[1].getScaleT(i & 1);
PRIM_LOG("tex indscale%d: %f %f\n", i, f[2 * i], f[2 * i + 1]);
Expand Down Expand Up @@ -243,7 +246,9 @@ void PixelShaderManager::SetConstants()
SetPSConstant4f(C_FOG + 2, ScreenSpaceCenter, (float)Renderer::EFBToScaledX((int)(2.0f * xfregs.viewport.wd)), bpmem.fogRange.K[4].HI / 256.0f,0.0f);
}
else
{
SetPSConstant4f(C_FOG + 2, 0.0f, 1.0f, 1.0f, 0.0f); // Need to update these values for older hardware that fails to divide by zero in shaders.
}

s_bFogRangeAdjustChanged = false;
}
Expand Down Expand Up @@ -279,7 +284,9 @@ void PixelShaderManager::SetConstants()
SetPSConstant4f(C_PLIGHTS+5*i+j+1, 0.00001f, xfmemptr[1], xfmemptr[2], 0);
}
else
{
SetPSConstant4fv(C_PLIGHTS+5*i+j+1, xfmemptr);
}
}
}

Expand Down Expand Up @@ -347,17 +354,22 @@ void PixelShaderManager::SetPSTextureDims(int texid)
void PixelShaderManager::SetColorChanged(int type, int num, bool high)
{
float *pf = &lastRGBAfull[type][num][0];
if (!high) {

if (!high)
{
int r = bpmem.tevregs[num].low.a;
int a = bpmem.tevregs[num].low.b;
pf[0] = (float)r * (1.0f / 255.0f);
pf[3] = (float)a * (1.0f / 255.0f);
} else {
}
else
{
int b = bpmem.tevregs[num].high.a;
int g = bpmem.tevregs[num].high.b;
pf[1] = (float)g * (1.0f / 255.0f);
pf[2] = (float)b * (1.0f / 255.0f);
}

s_nColorsChanged[type] |= 1 << num;
PRIM_LOG("pixel %scolor%d: %f %f %f %f\n", type?"k":"", num, pf[0], pf[1], pf[2], pf[3]);
}
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/VideoCommon/Src/Statistics.cpp
Expand Up @@ -72,7 +72,8 @@ char *Statistics::ToString(char *ptr)
}

// Is this really needed?
char *Statistics::ToStringProj(char *ptr) {
char *Statistics::ToStringProj(char *ptr)
{
char *p = ptr;
p+=sprintf(p,"Projection #: X for Raw 6=0 (X for Raw 6!=0)\n\n");
p+=sprintf(p,"Projection 0: %f (%f) Raw 0: %f\n", stats.gproj_0, stats.g2proj_0, stats.proj_0);
Expand Down
18 changes: 15 additions & 3 deletions Source/Core/VideoCommon/Src/TextureCacheBase.cpp
Expand Up @@ -42,9 +42,12 @@ TextureCache::TextureCache()
temp_size = 2048 * 2048 * 4;
if (!temp)
temp = (u8*)AllocateAlignedMemory(temp_size, 16);

TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter);

if(g_ActiveConfig.bHiresTextures && !g_ActiveConfig.bDumpTextures)
HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());

SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures);
}

Expand Down Expand Up @@ -125,7 +128,9 @@ void TextureCache::Cleanup()
textures.erase(iter++);
}
else
{
++iter;
}
}
}

Expand All @@ -143,7 +148,9 @@ void TextureCache::InvalidateRange(u32 start_address, u32 size)
textures.erase(iter++);
}
else
{
++iter;
}
}
}

Expand Down Expand Up @@ -201,7 +208,9 @@ void TextureCache::ClearRenderTargets()
textures.erase(iter++);
}
else
{
++iter;
}
}
}

Expand Down Expand Up @@ -547,17 +556,20 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
{
// Emulation methods:
//
// - EFB to RAM:
// Encodes the requested EFB data at its native resolution to the emulated RAM using shaders.
// Load() decodes the data from there again (using TextureDecoder) if the EFB copy is being used as a texture again.
// Advantage: CPU can read data from the EFB copy and we don't lose any important updates to the texture
// Disadvantage: Encoding+decoding steps often are redundant because only some games read or modify EFB copies before using them as textures.
//
// - EFB to texture:
// Copies the requested EFB data to a texture object in VRAM, performing any color conversion using shaders.
// Advantage: Works for many games, since in most cases EFB copies aren't read or modified at all before being used as a texture again.
// Since we don't do any further encoding or decoding here, this method is much faster.
// It also allows enhancing the visual quality by doing scaled EFB copies.
// - hybrid EFB copies:
//
// - Hybrid EFB copies:
// 1a) Whenever this function gets called, encode the requested EFB data to RAM (like EFB to RAM)
// 1b) Set type to TCET_EC_DYNAMIC for all texture cache entries in the destination address range.
// If EFB copy caching is enabled, further checks will (try to) prevent redundant EFB copies.
Expand Down Expand Up @@ -672,8 +684,8 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
}
else
{
cbufid = 9;
}
cbufid = 9;
}
}
else// alpha
{
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/VideoCommon/Src/TextureCacheBase.h
Expand Up @@ -124,7 +124,8 @@ class TextureCache
static TexCache textures;

// Backup configuration values
static struct BackupConfig {
static struct BackupConfig
{
int s_colorsamples;
bool s_copy_efb_to_texture;
bool s_copy_efb_scaled;
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/VideoCommon/Src/TextureConversionShader.cpp
Expand Up @@ -26,7 +26,8 @@ namespace TextureConversionShader

u16 GetEncodedSampleCount(u32 format)
{
switch (format) {
switch (format)
{
case GX_TF_I4: return 8;
case GX_TF_I8: return 4;
case GX_TF_IA4: return 4;
Expand Down
86 changes: 59 additions & 27 deletions Source/Core/VideoCommon/Src/VertexLoader.cpp
Expand Up @@ -214,7 +214,7 @@ void VertexLoader::CompileVertexTranslator()

#ifdef USE_JIT
if (m_compiledCode)
PanicAlert("Trying to recompile a vtx translator");
PanicAlert("Trying to recompile a vertex translator");

m_compiledCode = GetCodePtr();
ABI_EmitPrologue(4);
Expand All @@ -224,14 +224,17 @@ void VertexLoader::CompileVertexTranslator()

// Reset component counters if present in vertex format only.
if (m_VtxDesc.Tex0Coord || m_VtxDesc.Tex1Coord || m_VtxDesc.Tex2Coord || m_VtxDesc.Tex3Coord ||
m_VtxDesc.Tex4Coord || m_VtxDesc.Tex5Coord || m_VtxDesc.Tex6Coord || m_VtxDesc.Tex7Coord) {
m_VtxDesc.Tex4Coord || m_VtxDesc.Tex5Coord || m_VtxDesc.Tex6Coord || m_VtxDesc.Tex7Coord)
{
WriteSetVariable(32, &tcIndex, Imm32(0));
}
if (m_VtxDesc.Color0 || m_VtxDesc.Color1) {
if (m_VtxDesc.Color0 || m_VtxDesc.Color1)
{
WriteSetVariable(32, &colIndex, Imm32(0));
}
if (m_VtxDesc.Tex0MatIdx || m_VtxDesc.Tex1MatIdx || m_VtxDesc.Tex2MatIdx || m_VtxDesc.Tex3MatIdx ||
m_VtxDesc.Tex4MatIdx || m_VtxDesc.Tex5MatIdx || m_VtxDesc.Tex6MatIdx || m_VtxDesc.Tex7MatIdx) {
m_VtxDesc.Tex4MatIdx || m_VtxDesc.Tex5MatIdx || m_VtxDesc.Tex6MatIdx || m_VtxDesc.Tex7MatIdx)
{
WriteSetVariable(32, &s_texmtxwrite, Imm32(0));
WriteSetVariable(32, &s_texmtxread, Imm32(0));
}
Expand All @@ -258,14 +261,16 @@ void VertexLoader::CompileVertexTranslator()
int nat_offset = 0;
PortableVertexDeclaration vtx_decl;
memset(&vtx_decl, 0, sizeof(vtx_decl));
for (int i = 0; i < 8; i++) {
for (int i = 0; i < 8; i++)
{
vtx_decl.texcoord_offset[i] = -1;
}

// m_VBVertexStride for texmtx and posmtx is computed later when writing.

// Position Matrix Index
if (m_VtxDesc.PosMatIdx) {
if (m_VtxDesc.PosMatIdx)
{
WriteCall(PosMtx_ReadDirect_UByte);
m_NativeFmt->m_components |= VB_HAS_POSMTXIDX;
m_VertexSize += 1;
Expand All @@ -281,11 +286,14 @@ void VertexLoader::CompileVertexTranslator()
if (m_VtxDesc.Tex7MatIdx) {m_VertexSize += 1; m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX7; WriteCall(TexMtx_ReadDirect_UByte); }

// Write vertex position loader
if(g_ActiveConfig.bUseBBox) {
if(g_ActiveConfig.bUseBBox)
{
WriteCall(UpdateBoundingBoxPrepare);
WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements));
WriteCall(UpdateBoundingBox);
} else {
}
else
{
WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements));
}
m_VertexSize += VertexLoader_Position::GetSize(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements);
Expand Down Expand Up @@ -317,7 +325,9 @@ void VertexLoader::CompileVertexTranslator()
vtx_decl.normal_gl_size = 3;
vtx_decl.normal_offset[0] = nat_offset;
nat_offset += 12;
if (vtx_attr.NormalElements) {

if (vtx_attr.NormalElements)
{
vtx_decl.normal_offset[1] = nat_offset;
nat_offset += 12;
vtx_decl.normal_offset[2] = nat_offset;
Expand All @@ -334,7 +344,8 @@ void VertexLoader::CompileVertexTranslator()
vtx_decl.color_gl_type = VAR_UNSIGNED_BYTE;
vtx_decl.color_offset[0] = -1;
vtx_decl.color_offset[1] = -1;
for (int i = 0; i < 2; i++) {
for (int i = 0; i < 2; i++)
{
m_NativeFmt->m_components |= VB_HAS_COL0 << i;
switch (col[i])
{
Expand Down Expand Up @@ -382,21 +393,26 @@ void VertexLoader::CompileVertexTranslator()
break;
}
// Common for the three bottom cases
if (col[i] != NOT_PRESENT) {
if (col[i] != NOT_PRESENT)
{
vtx_decl.color_offset[i] = nat_offset;
nat_offset += 4;
}
}

// Texture matrix indices (remove if corresponding texture coordinate isn't enabled)
for (int i = 0; i < 8; i++) {
for (int i = 0; i < 8; i++)
{
vtx_decl.texcoord_offset[i] = -1;
const int format = m_VtxAttr.texCoord[i].Format;
const int elements = m_VtxAttr.texCoord[i].Elements;

if (tc[i] == NOT_PRESENT) {
if (tc[i] == NOT_PRESENT)
{
m_NativeFmt->m_components &= ~(VB_HAS_UV0 << i);
} else {
}
else
{
_assert_msg_(VIDEO, DIRECT <= tc[i] && tc[i] <= INDEX16, "Invalid texture coordinates!\n(tc[i] = %d)", tc[i]);
_assert_msg_(VIDEO, FORMAT_UBYTE <= format && format <= FORMAT_FLOAT, "Invalid texture coordinates format!\n(format = %d)", format);
_assert_msg_(VIDEO, 0 <= elements && elements <= 1, "Invalid number of texture coordinates elements!\n(elements = %d)", elements);
Expand All @@ -406,16 +422,19 @@ void VertexLoader::CompileVertexTranslator()
m_VertexSize += VertexLoader_TextCoord::GetSize(tc[i], format, elements);
}

if (m_NativeFmt->m_components & (VB_HAS_TEXMTXIDX0 << i)) {
if (tc[i] != NOT_PRESENT) {
if (m_NativeFmt->m_components & (VB_HAS_TEXMTXIDX0 << i))
{
if (tc[i] != NOT_PRESENT)
{
// if texmtx is included, texcoord will always be 3 floats, z will be the texmtx index
vtx_decl.texcoord_offset[i] = nat_offset;
vtx_decl.texcoord_gl_type[i] = VAR_FLOAT;
vtx_decl.texcoord_size[i] = 3;
nat_offset += 12;
WriteCall(m_VtxAttr.texCoord[i].Elements ? TexMtx_Write_Float : TexMtx_Write_Float2);
}
else {
else
{
m_NativeFmt->m_components |= VB_HAS_UV0 << i; // have to include since using now
vtx_decl.texcoord_offset[i] = nat_offset;
vtx_decl.texcoord_gl_type[i] = VAR_FLOAT;
Expand All @@ -424,37 +443,46 @@ void VertexLoader::CompileVertexTranslator()
WriteCall(TexMtx_Write_Float4);
}
}
else {
if (tc[i] != NOT_PRESENT) {
else
{
if (tc[i] != NOT_PRESENT)
{
vtx_decl.texcoord_offset[i] = nat_offset;
vtx_decl.texcoord_gl_type[i] = VAR_FLOAT;
vtx_decl.texcoord_size[i] = vtx_attr.texCoord[i].Elements ? 2 : 1;
nat_offset += 4 * (vtx_attr.texCoord[i].Elements ? 2 : 1);
}
}

if (tc[i] == NOT_PRESENT) {
if (tc[i] == NOT_PRESENT)
{
// if there's more tex coords later, have to write a dummy call
int j = i + 1;
for (; j < 8; ++j) {
if (tc[j] != NOT_PRESENT) {
for (; j < 8; ++j)
{
if (tc[j] != NOT_PRESENT)
{
WriteCall(VertexLoader_TextCoord::GetDummyFunction()); // important to get indices right!
break;
}
}
// tricky!
if (j == 8 && !((m_NativeFmt->m_components & VB_HAS_TEXMTXIDXALL) & (VB_HAS_TEXMTXIDXALL << (i + 1)))) {
if (j == 8 && !((m_NativeFmt->m_components & VB_HAS_TEXMTXIDXALL) & (VB_HAS_TEXMTXIDXALL << (i + 1))))
{
// no more tex coords and tex matrices, so exit loop
break;
}
}
}

if (m_VtxDesc.PosMatIdx) {
if (m_VtxDesc.PosMatIdx)
{
WriteCall(PosMtx_Write);
vtx_decl.posmtx_offset = nat_offset;
nat_offset += 4;
} else {
}
else
{
vtx_decl.posmtx_offset = -1;
}

Expand Down Expand Up @@ -574,7 +602,8 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int const coun
void VertexLoader::ConvertVertices ( int count )
{
#ifdef USE_JIT
if (count > 0) {
if (count > 0)
{
loop_counter = count;
((void (*)())(void*)m_compiledCode)();
}
Expand Down Expand Up @@ -678,10 +707,13 @@ void VertexLoader::AppendToString(std::string *dest) const
dest->append(StringFromFormat("%ib skin: %i P: %i %s-%s ",
m_VertexSize, m_VtxDesc.PosMatIdx,
m_VtxAttr.PosElements ? 3 : 2, posMode[m_VtxDesc.Position], posFormats[m_VtxAttr.PosFormat]));
if (m_VtxDesc.Normal) {

if (m_VtxDesc.Normal)
{
dest->append(StringFromFormat("Nrm: %i %s-%s ",
m_VtxAttr.NormalElements, posMode[m_VtxDesc.Normal], posFormats[m_VtxAttr.NormalFormat]));
}

u32 color_mode[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1};
for (int i = 0; i < 2; i++)
{
Expand Down
35 changes: 27 additions & 8 deletions Source/Core/VideoCommon/Src/VertexLoader.h
Expand Up @@ -24,41 +24,60 @@ class VertexLoaderUID
u32 vid[5];
size_t hash;
public:
VertexLoaderUID() {}
void InitFromCurrentState(int vtx_attr_group) {
VertexLoaderUID()
{
}

void InitFromCurrentState(int vtx_attr_group)
{
vid[0] = g_VtxDesc.Hex & 0xFFFFFFFF;
vid[1] = g_VtxDesc.Hex >> 32;
vid[2] = g_VtxAttr[vtx_attr_group].g0.Hex & ~VAT_0_FRACBITS;
vid[3] = g_VtxAttr[vtx_attr_group].g1.Hex & ~VAT_1_FRACBITS;
vid[4] = g_VtxAttr[vtx_attr_group].g2.Hex & ~VAT_2_FRACBITS;
hash = CalculateHash();
}
bool operator < (const VertexLoaderUID &other) const {

bool operator < (const VertexLoaderUID &other) const
{
// This is complex because of speed.
if (vid[0] < other.vid[0])
return true;
else if (vid[0] > other.vid[0])
return false;
for (int i = 1; i < 5; ++i) {

for (int i = 1; i < 5; ++i)
{
if (vid[i] < other.vid[i])
return true;
else if (vid[i] > other.vid[i])
return false;
}

return false;
}
bool operator == (const VertexLoaderUID& rh) const {

bool operator == (const VertexLoaderUID& rh) const
{
return hash == rh.hash && std::equal(vid, vid + sizeof(vid) / sizeof(vid[0]), rh.vid);
}
size_t GetHash() const {

size_t GetHash() const
{
return hash;
}

private:
size_t CalculateHash() {

size_t CalculateHash()
{
size_t h = -1;
for (unsigned int i = 0; i < sizeof(vid) / sizeof(vid[0]); ++i) {

for (unsigned int i = 0; i < sizeof(vid) / sizeof(vid[0]); ++i)
{
h = h * 137 + vid[i];
}

return h;
}
};
Expand Down
12 changes: 8 additions & 4 deletions Source/Core/VideoCommon/Src/VertexLoaderManager.cpp
Expand Up @@ -57,11 +57,14 @@ void Shutdown()
g_VertexLoaderMap.clear();
}

namespace {
struct entry {
namespace
{
struct entry
{
std::string text;
u64 num_verts;
bool operator < (const entry &other) const {
bool operator < (const entry &other) const
{
return num_verts > other.num_verts;
}
};
Expand All @@ -82,7 +85,8 @@ void AppendListToString(std::string *dest)
}
sort(entries.begin(), entries.end());
dest->reserve(dest->size() + total_size);
for (std::vector<entry>::const_iterator iter = entries.begin(); iter != entries.end(); ++iter) {
for (std::vector<entry>::const_iterator iter = entries.begin(); iter != entries.end(); ++iter)
{
dest->append(iter->text);
}
}
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/VideoCommon/Src/VertexLoader_Color.cpp
Expand Up @@ -78,7 +78,8 @@ void LOADERDECL Color_ReadDirect_24b_888()
DataSkip(3);
}

void LOADERDECL Color_ReadDirect_32b_888x(){
void LOADERDECL Color_ReadDirect_32b_888x()
{
_SetCol(_Read24(DataGetPosition()));
DataSkip(4);
}
Expand Down
6 changes: 4 additions & 2 deletions Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp
Expand Up @@ -40,7 +40,9 @@ __forceinline float FracAdjust(T val)

template <>
__forceinline float FracAdjust(float val)
{ return val; }
{
return val;
}

template <typename T, int N>
__forceinline void ReadIndirect(const T* data)
Expand Down Expand Up @@ -187,5 +189,5 @@ TPipelineFunction VertexLoader_Normal::GetFunction(unsigned int _type,
unsigned int _format, unsigned int _elements, unsigned int _index3)
{
TPipelineFunction pFunc = m_Table[_type][_index3][_elements][_format].function;
return pFunc;
return pFunc;
}
16 changes: 11 additions & 5 deletions Source/Core/VideoCommon/Src/VertexLoader_Position.cpp
Expand Up @@ -68,7 +68,9 @@ float PosScale(T val)

template <>
float PosScale(float val)
{ return val; }
{
return val;
}

template <typename T, int N>
void LOADERDECL Pos_ReadDirect()
Expand Down Expand Up @@ -166,11 +168,13 @@ static int tableReadPositionVertexSize[4][8][2] = {
};


void VertexLoader_Position::Init(void) {
void VertexLoader_Position::Init(void)
{

#if _M_SSE >= 0x301

if (cpu_info.bSSSE3) {
if (cpu_info.bSSSE3)
{
tableReadPosition[2][4][0] = Pos_ReadIndex_Float_SSSE3<u8, false>;
tableReadPosition[2][4][1] = Pos_ReadIndex_Float_SSSE3<u8, true>;
tableReadPosition[3][4][0] = Pos_ReadIndex_Float_SSSE3<u16, false>;
Expand All @@ -181,10 +185,12 @@ void VertexLoader_Position::Init(void) {

}

unsigned int VertexLoader_Position::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements) {
unsigned int VertexLoader_Position::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements)
{
return tableReadPositionVertexSize[_type][_format][_elements];
}

TPipelineFunction VertexLoader_Position::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements) {
TPipelineFunction VertexLoader_Position::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements)
{
return tableReadPosition[_type][_format][_elements];
}
16 changes: 11 additions & 5 deletions Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp
Expand Up @@ -48,7 +48,9 @@ float TCScale(T val)

template <>
float TCScale(float val)
{ return val; }
{
return val;
}

template <typename T, int N>
void LOADERDECL TexCoord_ReadDirect()
Expand Down Expand Up @@ -166,7 +168,8 @@ static int tableReadTexCoordVertexSize[4][8][2] = {
},
};

void VertexLoader_TextCoord::Init(void) {
void VertexLoader_TextCoord::Init(void)
{

#if _M_SSE >= 0x301

Expand All @@ -190,14 +193,17 @@ void VertexLoader_TextCoord::Init(void) {

}

unsigned int VertexLoader_TextCoord::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements) {
unsigned int VertexLoader_TextCoord::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements)
{
return tableReadTexCoordVertexSize[_type][_format][_elements];
}

TPipelineFunction VertexLoader_TextCoord::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements) {
TPipelineFunction VertexLoader_TextCoord::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements)
{
return tableReadTexCoord[_type][_format][_elements];
}

TPipelineFunction VertexLoader_TextCoord::GetDummyFunction() {
TPipelineFunction VertexLoader_TextCoord::GetDummyFunction()
{
return TexCoord_Read_Dummy;
}
12 changes: 9 additions & 3 deletions Source/Core/VideoCommon/Src/VertexManagerBase.cpp
Expand Up @@ -35,7 +35,8 @@ VertexManager::VertexManager()
}

VertexManager::~VertexManager()
{}
{
}

void VertexManager::ResetBuffer()
{
Expand Down Expand Up @@ -75,7 +76,8 @@ bool VertexManager::IsFlushed() const
u32 VertexManager::GetRemainingIndices(int primitive)
{

if(g_Config.backend_info.bSupportsPrimitiveRestart) {
if(g_Config.backend_info.bSupportsPrimitiveRestart)
{
switch (primitive)
{
case GX_DRAW_QUADS:
Expand All @@ -98,7 +100,9 @@ u32 VertexManager::GetRemainingIndices(int primitive)
default:
return 0;
}
} else {
}
else
{
switch (primitive)
{
case GX_DRAW_QUADS:
Expand Down Expand Up @@ -216,7 +220,9 @@ void VertexManager::Flush()
PixelShaderManager::SetTexDims(i, tentry->nativeW, tentry->nativeH, 0, 0);
}
else
{
ERROR_LOG(VIDEO, "Error loading texture");
}
}
}

Expand Down
108 changes: 78 additions & 30 deletions Source/Core/VideoCommon/Src/VertexShaderGen.cpp
Expand Up @@ -28,20 +28,23 @@ void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components)

uid->values[2] |= (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) << 31;
u32 *pcurvalue = &uid->values[3];
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) {
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
{
TexMtxInfo tinfo = xfregs.texMtxInfo[i];
if (tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP)
tinfo.hex &= 0x7ff;
if (tinfo.texgentype != XF_TEXGEN_REGULAR)
tinfo.projection = 0;

u32 val = ((tinfo.hex >> 1) & 0x1ffff);
if (xfregs.dualTexTrans.enabled && tinfo.texgentype == XF_TEXGEN_REGULAR) {
if (xfregs.dualTexTrans.enabled && tinfo.texgentype == XF_TEXGEN_REGULAR)
{
// rewrite normalization and post index
val |= ((u32)xfregs.postMtxInfo[i].index << 17) | ((u32)xfregs.postMtxInfo[i].normalize << 23);
}

switch (i & 3) {
switch (i & 3)
{
case 0: pcurvalue[0] |= val; break;
case 1: pcurvalue[0] |= val << 24; pcurvalue[1] = val >> 8; ++pcurvalue; break;
case 2: pcurvalue[0] |= val << 16; pcurvalue[1] = val >> 16; ++pcurvalue; break;
Expand All @@ -60,12 +63,16 @@ void GetSafeVertexShaderId(VERTEXSHADERUIDSAFE *uid, u32 components)
*ptr++ = xfregs.numChan.hex;
*ptr++ = xfregs.dualTexTrans.hex;

for (int i = 0; i < 2; ++i) {
for (int i = 0; i < 2; ++i)
{
*ptr++ = xfregs.color[i].hex;
*ptr++ = xfregs.alpha[i].hex;
}

*ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
for (unsigned int i = 0; i < 8; ++i) {

for (unsigned int i = 0; i < 8; ++i)
{
*ptr++ = xfregs.texMtxInfo[i].hex;
*ptr++ = xfregs.postMtxInfo[i].hex;
}
Expand Down Expand Up @@ -131,13 +138,18 @@ char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE ApiType)
WRITE(p, " %s float4 colors_0 %s COLOR0;\n", optCentroid, ApiType == API_OPENGL ? ";//" : ":");
WRITE(p, " %s float4 colors_1 %s COLOR1;\n", optCentroid, ApiType == API_OPENGL ? ";//" : ":");

if (xfregs.numTexGen.numTexGens < 7) {
if (xfregs.numTexGen.numTexGens < 7)
{
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
WRITE(p, " %s float3 tex%d %s TEXCOORD%d;\n", optCentroid, i, ApiType == API_OPENGL ? ";//" : ":", i);

WRITE(p, " %s float4 clipPos %s TEXCOORD%d;\n", optCentroid, ApiType == API_OPENGL ? ";//" : ":", xfregs.numTexGen.numTexGens);

if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
WRITE(p, " %s float4 Normal %s TEXCOORD%d;\n", optCentroid, ApiType == API_OPENGL ? ";//" : ":", xfregs.numTexGen.numTexGens + 1);
} else {
}
else
{
// clip position is in w of first 4 texcoords
if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
Expand Down Expand Up @@ -212,7 +224,8 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
if (components & VB_HAS_COL1)
WRITE(p, "ATTRIN float4 color1; // ATTR%d,\n", SHADER_COLOR1_ATTRIB);

for (int i = 0; i < 8; ++i) {
for (int i = 0; i < 8; ++i)
{
u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i));
if ((components & (VB_HAS_UV0<<i)) || hastexmtx)
WRITE(p, "ATTRIN float%d tex%d; // ATTR%d,\n", hastexmtx ? 3 : 2, i, SHADER_TEXTURE0_ATTRIB + i);
Expand Down Expand Up @@ -253,28 +266,36 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
// inputs
if (components & VB_HAS_NRM0)
WRITE(p, " float3 rawnorm0 : NORMAL0,\n");
if (components & VB_HAS_NRM1) {
if (components & VB_HAS_NRM1)
{
if (is_d3d)
WRITE(p, " float3 rawnorm1 : NORMAL1,\n");
else
WRITE(p, " float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB);
}
if (components & VB_HAS_NRM2) {
if (components & VB_HAS_NRM2)
{
if (is_d3d)
WRITE(p, " float3 rawnorm2 : NORMAL2,\n");
else
WRITE(p, " float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB);
}
if (components & VB_HAS_COL0)
{
WRITE(p, " float4 color0 : COLOR0,\n");
}
if (components & VB_HAS_COL1)
{
WRITE(p, " float4 color1 : COLOR1,\n");
for (int i = 0; i < 8; ++i) {
}
for (int i = 0; i < 8; ++i)
{
u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i));
if ((components & (VB_HAS_UV0<<i)) || hastexmtx)
WRITE(p, " float%d tex%d : TEXCOORD%d,\n", hastexmtx ? 3 : 2, i, i);
}
if (components & VB_HAS_POSMTXIDX) {
if (components & VB_HAS_POSMTXIDX)
{
if (is_d3d)
WRITE(p, " float4 blend_indices : BLENDINDICES,\n");
else
Expand Down Expand Up @@ -364,18 +385,22 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)

// transform texcoords
WRITE(p, "float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n");
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) {
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
{
TexMtxInfo& texinfo = xfregs.texMtxInfo[i];

WRITE(p, "{\n");
WRITE(p, "coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n");
switch (texinfo.sourcerow) {

switch (texinfo.sourcerow)
{
case XF_SRCGEOM_INROW:
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
WRITE(p, "coord = rawpos;\n"); // pos.w is 1
break;
case XF_SRCNORMAL_INROW:
if (components & VB_HAS_NRM0) {
if (components & VB_HAS_NRM0)
{
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
WRITE(p, "coord = float4(rawnorm0.xyz, 1.0f);\n");
}
Expand All @@ -384,13 +409,15 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
_assert_( texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC0 || texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC1 );
break;
case XF_SRCBINORMAL_T_INROW:
if (components & VB_HAS_NRM1) {
if (components & VB_HAS_NRM1)
{
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
WRITE(p, "coord = float4(rawnorm1.xyz, 1.0f);\n");
}
break;
case XF_SRCBINORMAL_B_INROW:
if (components & VB_HAS_NRM2) {
if (components & VB_HAS_NRM2)
{
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
WRITE(p, "coord = float4(rawnorm2.xyz, 1.0f);\n");
}
Expand All @@ -403,10 +430,12 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
}

// first transformation
switch (texinfo.texgentype) {
switch (texinfo.texgentype)
{
case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map

if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) {
if (components & (VB_HAS_NRM1|VB_HAS_NRM2))
{
// transform the light dir into tangent space
WRITE(p, "ldir = normalize(" I_LIGHTS"[5*%d + 3].xyz - pos.xyz);\n", texinfo.embosslightshift);
WRITE(p, "o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift);
Expand All @@ -433,11 +462,11 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
WRITE(p, "int tmp = int(tex%d.z);\n", i);
if (texinfo.projection == XF_TEXPROJ_STQ)
WRITE(p, "o.tex%d.xyz = float3(dot(coord, " I_TRANSFORMMATRICES"[tmp]), dot(coord, " I_TRANSFORMMATRICES"[tmp+1]), dot(coord, " I_TRANSFORMMATRICES"[tmp+2]));\n", i);
else {
else
WRITE(p, "o.tex%d.xyz = float3(dot(coord, " I_TRANSFORMMATRICES"[tmp]), dot(coord, " I_TRANSFORMMATRICES"[tmp+1]), 1);\n", i);
}
}
else {
else
{
if (texinfo.projection == XF_TEXPROJ_STQ)
WRITE(p, "o.tex%d.xyz = float3(dot(coord, " I_TEXMATRICES"[%d]), dot(coord, " I_TEXMATRICES"[%d]), dot(coord, " I_TEXMATRICES"[%d]));\n", i, 3*i, 3*i+1, 3*i+2);
else
Expand All @@ -446,7 +475,9 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
break;
}

if (xfregs.dualTexTrans.enabled && texinfo.texgentype == XF_TEXGEN_REGULAR) { // only works for regular tex gen types?
// CHECKME: does this only work for regular tex gen types?
if (xfregs.dualTexTrans.enabled && texinfo.texgentype == XF_TEXGEN_REGULAR)
{
const PostMtxInfo& postInfo = xfregs.postMtxInfo[i];

int postidx = postInfo.index;
Expand All @@ -455,7 +486,8 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
"float4 P2 = " I_POSTTRANSFORMMATRICES"[%d];\n",
postidx&0x3f, (postidx+1)&0x3f, (postidx+2)&0x3f);

if (texGenSpecialCase) {
if (texGenSpecialCase)
{
// no normalization
// q of input is 1
// q of output is unknown
Expand All @@ -477,9 +509,12 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
}

// clipPos/w needs to be done in pixel shader, not here
if (xfregs.numTexGen.numTexGens < 7) {
if (xfregs.numTexGen.numTexGens < 7)
{
WRITE(p, "o.clipPos = float4(pos.x,pos.y,o.pos.z,o.pos.w);\n");
} else {
}
else
{
WRITE(p, "o.tex0.w = pos.x;\n");
WRITE(p, "o.tex1.w = pos.y;\n");
WRITE(p, "o.tex2.w = o.pos.z;\n");
Expand All @@ -488,9 +523,12 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)

if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
if (xfregs.numTexGen.numTexGens < 7) {
if (xfregs.numTexGen.numTexGens < 7)
{
WRITE(p, "o.Normal = float4(_norm0.x,_norm0.y,_norm0.z,pos.z);\n");
} else {
}
else
{
WRITE(p, "o.tex4.w = _norm0.x;\n");
WRITE(p, "o.tex5.w = _norm0.y;\n");
WRITE(p, "o.tex6.w = _norm0.z;\n");
Expand All @@ -499,6 +537,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
else
WRITE(p, "o.tex7.w = pos.z;\n");
}

if (components & VB_HAS_COL0)
WRITE(p, "o.colors_0 = color0;\n");

Expand Down Expand Up @@ -550,16 +589,23 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
// Will look better when we bind uniforms in GLSL 1.3
// clipPos/w needs to be done in pixel shader, not here

if (xfregs.numTexGen.numTexGens < 7) {
if (xfregs.numTexGen.numTexGens < 7)
{
for (unsigned int i = 0; i < 8; ++i)
{
if(i < xfregs.numTexGen.numTexGens)
WRITE(p, " uv%d_2.xyz = o.tex%d;\n", i, i);
else
WRITE(p, " uv%d_2.xyz = float3(0.0f, 0.0f, 0.0f);\n", i);
}

WRITE(p, " clipPos_2 = o.clipPos;\n");

if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
WRITE(p, " Normal_2 = o.Normal;\n");
} else {
}
else
{
// clip position is in w of first 4 texcoords
if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
Expand All @@ -578,7 +624,9 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
WRITE(p, "}\n");
}
else
{
WRITE(p, "return o;\n}\n");
}

if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("VertexShader generator - buffer too small, canary has been eaten!");
Expand Down
6 changes: 5 additions & 1 deletion Source/Core/VideoCommon/Src/VertexShaderGen.h
Expand Up @@ -58,7 +58,7 @@ const s_svar VSVar_Loc[] = { {I_POSNORMALMATRIX, C_POSNORMALMATRIX, 6 },
{I_NORMALMATRICES , C_NORMALMATRICES, 32 },
{I_POSTTRANSFORMMATRICES, C_POSTTRANSFORMMATRICES, 64 },
{I_DEPTHPARAMS, C_DEPTHPARAMS, 1 },
};
};
template<bool safe>
class _VERTEXSHADERUID
{
Expand Down Expand Up @@ -88,6 +88,7 @@ class _VERTEXSHADERUID
return true;
else if (values[0] > _Right.values[0])
return false;

int N = GetNumValues();
for (int i = 1; i < N; ++i)
{
Expand All @@ -96,19 +97,22 @@ class _VERTEXSHADERUID
else if (values[i] > _Right.values[i])
return false;
}

return false;
}

bool operator ==(const _VERTEXSHADERUID& _Right) const
{
if (values[0] != _Right.values[0])
return false;

int N = GetNumValues();
for (int i = 1; i < N; ++i)
{
if (values[i] != _Right.values[i])
return false;
}

return true;
}
};
Expand Down
18 changes: 14 additions & 4 deletions Source/Core/VideoCommon/Src/VertexShaderManager.cpp
Expand Up @@ -86,15 +86,18 @@ float PHackValue(std::string sValue)
c[i] = '\0';
break;
}

c[i] = (cStr[i] == ',') ? '.' : *(cStr+i);
if (c[i] == '.')
fp = true;
}

cStr = c;
sTof.str(cStr);
sTof >> f;

if (!fp) f /= 0xF4240;
if (!fp)
f /= 0xF4240;

delete [] c;
return f;
Expand Down Expand Up @@ -183,6 +186,7 @@ void VertexShaderManager::SetConstants()
{
if (g_ActiveConfig.backend_info.APIType == API_OPENGL && !g_ActiveConfig.backend_info.bSupportsGLSLUBO)
Dirty();

if (nTransformMatricesChanged[0] >= 0)
{
int startn = nTransformMatricesChanged[0] / 4;
Expand All @@ -191,6 +195,7 @@ void VertexShaderManager::SetConstants()
SetMultiVSConstant4fv(C_TRANSFORMMATRICES + startn, endn - startn, pstart);
nTransformMatricesChanged[0] = nTransformMatricesChanged[1] = -1;
}

if (nNormalMatricesChanged[0] >= 0)
{
int startn = nNormalMatricesChanged[0] / 3;
Expand Down Expand Up @@ -238,7 +243,9 @@ void VertexShaderManager::SetConstants()
SetVSConstant4f(C_LIGHTS+5*i+j+1, 0.00001f, xfmemptr[1], xfmemptr[2], 0);
}
else
{
SetVSConstant4fv(C_LIGHTS+5*i+j+1, xfmemptr);
}
}
}

Expand Down Expand Up @@ -479,21 +486,24 @@ void VertexShaderManager::InvalidateXFRange(int start, int end)
if (((u32)start >= (u32)MatrixIndexA.PosNormalMtxIdx * 4 &&
(u32)start < (u32)MatrixIndexA.PosNormalMtxIdx * 4 + 12) ||
((u32)start >= XFMEM_NORMALMATRICES + ((u32)MatrixIndexA.PosNormalMtxIdx & 31) * 3 &&
(u32)start < XFMEM_NORMALMATRICES + ((u32)MatrixIndexA.PosNormalMtxIdx & 31) * 3 + 9)) {
(u32)start < XFMEM_NORMALMATRICES + ((u32)MatrixIndexA.PosNormalMtxIdx & 31) * 3 + 9))
{
bPosNormalMatrixChanged = true;
}

if (((u32)start >= (u32)MatrixIndexA.Tex0MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex0MtxIdx*4+12) ||
((u32)start >= (u32)MatrixIndexA.Tex1MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex1MtxIdx*4+12) ||
((u32)start >= (u32)MatrixIndexA.Tex2MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex2MtxIdx*4+12) ||
((u32)start >= (u32)MatrixIndexA.Tex3MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex3MtxIdx*4+12)) {
((u32)start >= (u32)MatrixIndexA.Tex3MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex3MtxIdx*4+12))
{
bTexMatricesChanged[0] = true;
}

if (((u32)start >= (u32)MatrixIndexB.Tex4MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex4MtxIdx*4+12) ||
((u32)start >= (u32)MatrixIndexB.Tex5MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex5MtxIdx*4+12) ||
((u32)start >= (u32)MatrixIndexB.Tex6MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex6MtxIdx*4+12) ||
((u32)start >= (u32)MatrixIndexB.Tex7MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex7MtxIdx*4+12)) {
((u32)start >= (u32)MatrixIndexB.Tex7MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex7MtxIdx*4+12))
{
bTexMatricesChanged[1] = true;
}

Expand Down
5 changes: 3 additions & 2 deletions Source/Core/VideoCommon/Src/VideoConfig.cpp
Expand Up @@ -129,9 +129,10 @@ void VideoConfig::GameIniLoad(const char *ini_file)
if (tmp != -9000)
{
if (tmp != SCALE_FORCE_INTEGRAL)
{
iEFBScale = tmp;
// Round down to multiple of native IR
else
}
else // Round down to multiple of native IR
{
switch (iEFBScale)
{
Expand Down
14 changes: 9 additions & 5 deletions Source/Core/VideoCommon/Src/XFMemory.h
Expand Up @@ -195,20 +195,24 @@ union DualTexInfo
struct Light
{
u32 useless[3];
u32 color; //rgba
float a0; //attenuation
u32 color; // rgba
float a0; // attenuation
float a1;
float a2;
float k0; //k stuff
float k0; // k stuff
float k1;
float k2;

union
{
struct {
struct
{
float dpos[3];
float ddir[3]; // specular lights only
};
struct {

struct
{
float sdir[3];
float shalfangle[3]; // specular lights only
};
Expand Down
30 changes: 22 additions & 8 deletions Source/Core/VideoCommon/Src/x64DLCache.cpp
Expand Up @@ -169,7 +169,7 @@ struct CachedDisplayList
while(Current)
{
if(!Current->IntersectsMemoryRange(RegionStart, Regionsize))
return Current;
return Current;
Current = Current->NextRegion;
}
return Current;
Expand Down Expand Up @@ -598,14 +598,17 @@ void Shutdown()
void Clear()
{
VDLMap::iterator iter = dl_map.begin();
while (iter != dl_map.end()) {
while (iter != dl_map.end())
{
VDlist &ParentEntry = iter->second;
DLMap::iterator childiter = ParentEntry.dl_map.begin();
while (childiter != ParentEntry.dl_map.end()) {
while (childiter != ParentEntry.dl_map.end())
{
CachedDisplayList &entry = childiter->second;
entry.ClearRegions();
childiter++;
}

ParentEntry.dl_map.clear();
iter++;
}
Expand All @@ -617,26 +620,33 @@ void Clear()
void ProgressiveCleanup()
{
VDLMap::iterator iter = dl_map.begin();
while (iter != dl_map.end()) {
while (iter != dl_map.end())
{
VDlist &ParentEntry = iter->second;
DLMap::iterator childiter = ParentEntry.dl_map.begin();
while (childiter != ParentEntry.dl_map.end())
{
CachedDisplayList &entry = childiter->second;
int limit = 3600;
if (entry.frame_count < frameCount - limit) {
if (entry.frame_count < frameCount - limit)
{
entry.ClearRegions();
ParentEntry.dl_map.erase(childiter++); // (this is gcc standard!)
}
else
{
++childiter;
}
}

if(ParentEntry.dl_map.empty())
{
dl_map.erase(iter++);
}
else
{
iter++;
}
}
}

Expand All @@ -653,10 +663,12 @@ bool HandleDisplayList(u32 address, u32 size)
//Fixed DlistCaching now is fully functional still some things to workout
if(!g_ActiveConfig.bDlistCachingEnable)
return false;
if(size == 0) return false;
if(size == 0)
return false;

// Is this thread safe?
if (DLCache::GetSpaceLeft() < DL_CODE_CLEAR_THRESHOLD) {
// TODO: Is this thread safe?
if (DLCache::GetSpaceLeft() < DL_CODE_CLEAR_THRESHOLD)
{
DLCache::Clear();
}

Expand All @@ -665,12 +677,14 @@ bool HandleDisplayList(u32 address, u32 size)
DLCache::VDLMap::iterator Parentiter = DLCache::dl_map.find(dl_id);
DLCache::DLMap::iterator iter;
bool childexist = false;

if (Parentiter != DLCache::dl_map.end())
{
vhash = DLCache::CreateVMapId(Parentiter->second.VATUsed);
iter = Parentiter->second.dl_map.find(vhash);
childexist = iter != Parentiter->second.dl_map.end();
}

if (Parentiter != DLCache::dl_map.end() && childexist)
{
DLCache::CachedDisplayList &dl = iter->second;
Expand Down