Merge branch 'master' into wii-network

This commit is contained in:
Matthew Parlane 2013-04-25 01:41:45 +12:00
commit c3dbbe011d
37 changed files with 565 additions and 261 deletions

View File

@ -213,7 +213,7 @@ void Write32(const u32 _Value, const u32 _Address)
break;
}
WII_IPC_HLE_Interface::Update();
//WII_IPC_HLE_Interface::Update();
CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0);
}

View File

@ -88,7 +88,6 @@ void EnqueReplyCallback(u64 userdata, int)
void Init()
{
enque_reply = CoreTiming::RegisterEvent("IPCReply", EnqueReplyCallback);
_dbg_assert_msg_(WII_IPC_HLE, g_DeviceMap.empty(), "DeviceMap isn't empty on init");
CWII_IPC_HLE_Device_es::m_ContentFile = "";
@ -130,11 +129,15 @@ void Init()
#endif
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++;
g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); i++;
enque_reply = CoreTiming::RegisterEvent("IPCReply", EnqueReplyCallback);
}
void Reset(bool _bHard)
{
CoreTiming::RemoveAllEvents(enque_reply);
u32 i;
for (i=0; i<IPC_MAX_FDS; i++)
{

View File

@ -89,8 +89,10 @@ bool AVIDump::CreateFile()
return false;
}
if (!m_fileCount) {
if (!SetCompressionOptions()) {
if (!m_fileCount)
{
if (!SetCompressionOptions())
{
NOTICE_LOG(VIDEO, "SetCompressionOptions failed");
Stop();
return false;

View File

@ -646,7 +646,8 @@ union FogParam0
u32 sign : 1;
};
float GetA() {
float GetA()
{
union { u32 i; float f; } dummy;
dummy.i = ((u32)sign << 31) | ((u32)exponent << 23) | ((u32)mantissa << 12); // scale mantissa from 11 to 23 bits
return dummy.f;
@ -667,7 +668,8 @@ union FogParam3
};
// amount to subtract from eyespacez after range adjustment
float GetC() {
float GetC()
{
union { u32 i; float f; } dummy;
dummy.i = ((u32)c_sign << 31) | ((u32)c_exp << 23) | ((u32)c_mant << 12); // scale mantissa from 11 to 23 bits
return dummy.f;
@ -906,7 +908,8 @@ union UPE_Copy
union BPU_PreloadTileInfo
{
u32 hex;
struct {
struct
{
u32 count : 15;
u32 type : 2;
};

View File

@ -102,7 +102,9 @@ void BPWritten(const BPCmd& bp)
if (!mapTexFound)
{
if (bp.address != BPMEM_TEV_COLOR_ENV && bp.address != BPMEM_TEV_ALPHA_ENV)
{
numWrites = 0;
}
else if (++numWrites >= 100) // seem that if 100 consecutive BP writes are called to either of these addresses in ZTP,
{ // then it is safe to assume the map texture address is currently loaded into the BP memory
mapTexAddress = bpmem.tex[0].texImage3[0].hex << 5;
@ -193,15 +195,19 @@ void BPWritten(const BPCmd& bp)
PRIM_LOG("blendmode: en=%d, open=%d, colupd=%d, alphaupd=%d, dst=%d, src=%d, sub=%d, mode=%d",
bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable, bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate,
bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode);
// Set LogicOp Blending Mode
if (bp.changes & 2)
SetLogicOpMode();
// Set Dithering Mode
if (bp.changes & 4)
SetDitherMode();
// Set Blending Mode
if (bp.changes & 0xFF1)
SetBlendMode();
// Set Color Mask
if (bp.changes & 0x18)
SetColorMask();
@ -420,7 +426,8 @@ void BPWritten(const BPCmd& bp)
if(g_bSkipCurrentFrame)
break;
if (bp.address == BPMEM_CLEARBBOX1) {
if (bp.address == BPMEM_CLEARBBOX1)
{
int right = bp.newvalue >> 10;
int left = bp.newvalue & 0x3ff;
@ -428,7 +435,9 @@ void BPWritten(const BPCmd& bp)
PixelEngine::bbox[0] = left;
PixelEngine::bbox[1] = right;
PixelEngine::bbox_active = true;
} else {
}
else
{
int bottom = bp.newvalue >> 10;
int top = bp.newvalue & 0x3ff;
@ -446,7 +455,8 @@ void BPWritten(const BPCmd& bp)
case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
OnPixelFormatChange();
if(bp.changes & 7) {
if(bp.changes & 7)
{
SetBlendMode(); // dual source could be activated by changing to PIXELFMT_RGBA6_Z24
g_renderer->SetColorMask(); // alpha writing needs to be disabled if the new pixel format doesn't have an alpha channel
}

View File

@ -88,7 +88,9 @@ union TVtxDesc
u32 Tex7Coord : 2;
u32 :31;
};
struct {
struct
{
u32 Hex0, Hex1;
};
};

View File

@ -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:
@ -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.
@ -571,9 +581,11 @@ void SetCpStatus(bool isCPUThread)
}
}
else
{
CommandProcessor::UpdateInterrupts(userdata);
}
}
}
void ProcessFifoToLoWatermark()
{

View File

@ -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:
@ -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;

View File

@ -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;
@ -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);
@ -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;
}

View File

@ -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);
@ -237,8 +238,10 @@ 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)
{
@ -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();
}
}

View File

@ -92,7 +92,8 @@ 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;
@ -100,7 +101,9 @@ template <bool pr> void IndexGenerator::AddStrip(u32 const numVerts)
*Tptr++ = s_primitive_restart;
numT += numVerts - 2;
} else {
}
else
{
bool wind = false;
for (u32 i = 2; i < numVerts; ++i)
{
@ -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;
@ -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;
@ -186,18 +192,22 @@ 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)
@ -205,8 +215,10 @@ template <bool pr> void IndexGenerator::AddQuads(u32 numVerts)
WriteTriangle<pr>(index+numVerts-3, index+numVerts-2, index+numVerts-1);
}
else if(remainingVerts)
{
ERROR_LOG(VIDEO, "AddQuads: unknown count of vertices found");
}
}
// Lines
void IndexGenerator::AddLineList(u32 numVerts)

View File

@ -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;
@ -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);
@ -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)
@ -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 )
@ -119,16 +129,20 @@ 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)
@ -136,12 +150,15 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName,
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 )
@ -150,8 +167,10 @@ 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");

View File

@ -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");
@ -255,7 +259,8 @@ void VideoBackendHardware::DoState(PointerWrap& p)
}
}
void VideoBackendHardware::CheckInvalidState() {
void VideoBackendHardware::CheckInvalidState()
{
if (m_invalid)
{
m_invalid = false;

View File

@ -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),

View File

@ -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;
@ -45,8 +46,10 @@ public:
{
m_functionptr(m_data);
}
CallbackType Type() { return m_type; }
};
std::vector<OSDCALLBACK> m_callbacks;
static std::list<MESSAGE> s_listMsgs;
@ -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)
{
@ -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;
@ -91,9 +96,12 @@ void DrawMessages()
void ClearMessages()
{
std::list<MESSAGE>::iterator it = s_listMsgs.begin();
while (it != s_listMsgs.end())
{
it = s_listMsgs.erase(it);
}
}
// On-Screen Display Callbacks
void AddCallback(CallbackType OnType, CallbackPtr FuncPtr, u32 UserData)
@ -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

View File

@ -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
@ -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));
@ -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
@ -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,
@ -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);
@ -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
@ -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
@ -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

View File

@ -62,23 +62,30 @@ public:
_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])
@ -86,22 +93,27 @@ public:
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;

View File

@ -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])
@ -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]);
@ -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;
}
@ -279,9 +284,11 @@ 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);
}
}
}
nLightsChanged[0] = nLightsChanged[1] = -1;
}
@ -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]);
}

View File

@ -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);

View File

@ -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);
}
@ -125,9 +128,11 @@ void TextureCache::Cleanup()
textures.erase(iter++);
}
else
{
++iter;
}
}
}
void TextureCache::InvalidateRange(u32 start_address, u32 size)
{
@ -143,9 +148,11 @@ void TextureCache::InvalidateRange(u32 start_address, u32 size)
textures.erase(iter++);
}
else
{
++iter;
}
}
}
void TextureCache::MakeRangeDynamic(u32 start_address, u32 size)
{
@ -201,9 +208,11 @@ void TextureCache::ClearRenderTargets()
textures.erase(iter++);
}
else
{
++iter;
}
}
}
bool TextureCache::CheckForCustomTextureLODs(u64 tex_hash, int texformat, unsigned int levels)
{
@ -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.

View File

@ -124,7 +124,8 @@ private:
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;

View File

@ -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;

View File

@ -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);
@ -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));
}
@ -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;
@ -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);
@ -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;
@ -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])
{
@ -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);
@ -406,8 +422,10 @@ 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;
@ -415,7 +433,8 @@ void VertexLoader::CompileVertexTranslator()
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;
@ -424,8 +443,10 @@ 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;
@ -433,28 +454,35 @@ void VertexLoader::CompileVertexTranslator()
}
}
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;
}
@ -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)();
}
@ -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++)
{

View File

@ -24,8 +24,12 @@ 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;
@ -33,32 +37,47 @@ public:
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;
}
};

View File

@ -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;
}
};
@ -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);
}
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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()
@ -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>;
@ -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];
}

View File

@ -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()
@ -166,7 +168,8 @@ static int tableReadTexCoordVertexSize[4][8][2] = {
},
};
void VertexLoader_TextCoord::Init(void) {
void VertexLoader_TextCoord::Init(void)
{
#if _M_SSE >= 0x301
@ -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;
}

View File

@ -35,7 +35,8 @@ VertexManager::VertexManager()
}
VertexManager::~VertexManager()
{}
{
}
void VertexManager::ResetBuffer()
{
@ -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:
@ -98,7 +100,9 @@ u32 VertexManager::GetRemainingIndices(int primitive)
default:
return 0;
}
} else {
}
else
{
switch (primitive)
{
case GX_DRAW_QUADS:
@ -216,9 +220,11 @@ void VertexManager::Flush()
PixelShaderManager::SetTexDims(i, tentry->nativeW, tentry->nativeH, 0, 0);
}
else
{
ERROR_LOG(VIDEO, "Error loading texture");
}
}
}
// set global constants
VertexShaderManager::SetConstants();

View File

@ -28,7 +28,8 @@ 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;
@ -36,12 +37,14 @@ void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components)
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;
@ -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;
}
@ -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)
{
@ -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);
@ -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
@ -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");
}
@ -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");
}
@ -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);
@ -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
@ -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;
@ -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
@ -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");
@ -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");
@ -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");
@ -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)
{
@ -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!");

View File

@ -88,6 +88,7 @@ public:
return true;
else if (values[0] > _Right.values[0])
return false;
int N = GetNumValues();
for (int i = 1; i < N; ++i)
{
@ -96,6 +97,7 @@ public:
else if (values[i] > _Right.values[i])
return false;
}
return false;
}
@ -103,12 +105,14 @@ public:
{
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;
}
};

View File

@ -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;
@ -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;
@ -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;
@ -238,9 +243,11 @@ 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);
}
}
}
nLightsChanged[0] = nLightsChanged[1] = -1;
}
@ -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;
}

View File

@ -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)
{

View File

@ -202,13 +202,17 @@ struct Light
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
};

View File

@ -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++;
}
@ -617,28 +620,35 @@ 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++;
}
}
}
static size_t GetSpaceLeft()
{
@ -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();
}
@ -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;