Avoid repeatedly asserting in SWG plugin when matrix indices don't match. Small change to the transform unit to avoid some unnecessary work. Check if Q is zero before dividing UV coordinates by it. Fixes issue 3454.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6504 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
donkopunchstania 2010-12-01 04:26:21 +00:00
parent 0718e1bd77
commit 1f660de7e5
4 changed files with 56 additions and 23 deletions

View File

@ -26,7 +26,7 @@
// shader cache for every revision, graphics-related or not, which is simply annoying.
enum
{
LINEAR_DISKCACHE_VER = 6473
LINEAR_DISKCACHE_VER = 6504
};
// On disk format:

View File

@ -730,7 +730,12 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
{
// optional perspective divides
if (xfregs.texcoords[i].texmtxinfo.projection == XF_TEXPROJ_STQ)
WRITE(p, "uv%d.xy = uv%d.xy/uv%d.z;\n", i, i, i);
{
WRITE(p, "if (uv%d.z)", i);
WRITE(p, " uv%d.xy = uv%d.xy / uv%d.z;\n", i, i, i);
WRITE(p, "else");
WRITE(p, " uv%d.xy = float2(0.0f, 0.0f);\n", i);
}
WRITE(p, "uv%d.xy = uv%d.xy * "I_TEXDIMS"[%d].zw;\n", i, i, i);
}

View File

@ -35,6 +35,7 @@ void MultiplyVec2Mat24(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] + mat[7];
result.z = 1.0f;
}
void MultiplyVec2Mat34(const Vec3 &vec, const float *mat, Vec3 &result)
@ -51,6 +52,13 @@ void MultiplyVec3Mat33(const Vec3 &vec, const float *mat, Vec3 &result)
result.z = mat[6] * vec.x + mat[7] * vec.y + mat[8] * vec.z;
}
void MultiplyVec3Mat24(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z + mat[3];
result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] * vec.z + mat[7];
result.z = 1.0f;
}
void MultiplyVec3Mat34(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z + mat[3];
@ -134,14 +142,22 @@ inline void TransformTexCoordRegular(const TexMtxInfo &texinfo, int coordNum, bo
const float *mat = (const float*)&xfregs.posMatrices[srcVertex->texMtx[coordNum] * 4];
Vec3 *dst = &dstVertex->texCoords[coordNum];
if (texinfo.inputform == XF_TEXINPUT_AB11)
{
MultiplyVec2Mat34(*src, mat, *dst);
}
else
{
MultiplyVec3Mat34(*src, mat, *dst);
}
if (texinfo.projection == XF_TEXPROJ_ST)
{
if (texinfo.inputform == XF_TEXINPUT_AB11 || specialCase)
MultiplyVec2Mat24(*src, mat, *dst);
else
MultiplyVec3Mat24(*src, mat, *dst);
}
else // texinfo.projection == XF_TEXPROJ_STQ
{
_assert_(!specialCase);
if (texinfo.inputform == XF_TEXINPUT_AB11)
MultiplyVec2Mat34(*src, mat, *dst);
else
MultiplyVec3Mat34(*src, mat, *dst);
}
if (xfregs.dualTexTrans)
{

View File

@ -107,16 +107,26 @@ void VertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
m_NumAttributeLoaders = 0;
// Reset vertex
// matrix index from xfregs or cp memory?
_assert_msg_(VIDEO, xfregs.MatrixIndexA.PosNormalMtxIdx == MatrixIndexA.PosNormalMtxIdx, "Matrix indices don't match");
//_assert_msg_(VIDEO, xfregs.MatrixIndexA.Tex0MtxIdx == MatrixIndexA.Tex0MtxIdx, "Matrix indices don't match");
//_assert_msg_(VIDEO, xfregs.MatrixIndexA.Tex1MtxIdx == MatrixIndexA.Tex1MtxIdx, "Matrix indices don't match");
_assert_msg_(VIDEO, xfregs.MatrixIndexA.Tex2MtxIdx == MatrixIndexA.Tex2MtxIdx, "Matrix indices don't match");
_assert_msg_(VIDEO, xfregs.MatrixIndexA.Tex3MtxIdx == MatrixIndexA.Tex3MtxIdx, "Matrix indices don't match");
_assert_msg_(VIDEO, xfregs.MatrixIndexB.Tex4MtxIdx == MatrixIndexB.Tex4MtxIdx, "Matrix indices don't match");
_assert_msg_(VIDEO, xfregs.MatrixIndexB.Tex5MtxIdx == MatrixIndexB.Tex5MtxIdx, "Matrix indices don't match");
_assert_msg_(VIDEO, xfregs.MatrixIndexB.Tex6MtxIdx == MatrixIndexB.Tex6MtxIdx, "Matrix indices don't match");
_assert_msg_(VIDEO, xfregs.MatrixIndexB.Tex7MtxIdx == MatrixIndexB.Tex7MtxIdx, "Matrix indices don't match");
// matrix index from xf regs or cp memory?
if (xfregs.MatrixIndexA.PosNormalMtxIdx != MatrixIndexA.PosNormalMtxIdx ||
xfregs.MatrixIndexA.Tex0MtxIdx != MatrixIndexA.Tex0MtxIdx ||
xfregs.MatrixIndexA.Tex1MtxIdx != MatrixIndexA.Tex1MtxIdx ||
xfregs.MatrixIndexA.Tex2MtxIdx != MatrixIndexA.Tex2MtxIdx ||
xfregs.MatrixIndexA.Tex3MtxIdx != MatrixIndexA.Tex3MtxIdx ||
xfregs.MatrixIndexB.Tex4MtxIdx != MatrixIndexB.Tex4MtxIdx ||
xfregs.MatrixIndexB.Tex5MtxIdx != MatrixIndexB.Tex5MtxIdx ||
xfregs.MatrixIndexB.Tex6MtxIdx != MatrixIndexB.Tex6MtxIdx ||
xfregs.MatrixIndexB.Tex7MtxIdx != MatrixIndexB.Tex7MtxIdx)
{
WARN_LOG(VIDEO, "Matrix indices don't match");
// Just show the assert once
static bool showedAlert = false;
_assert_msg_(VIDEO, showedAlert, "Matrix indices don't match");
showedAlert = true;
}
#if(1)
m_Vertex.posMtx = xfregs.MatrixIndexA.PosNormalMtxIdx;
m_Vertex.texMtx[0] = xfregs.MatrixIndexA.Tex0MtxIdx;
m_Vertex.texMtx[1] = xfregs.MatrixIndexA.Tex1MtxIdx;
@ -126,7 +136,8 @@ void VertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
m_Vertex.texMtx[5] = xfregs.MatrixIndexB.Tex5MtxIdx;
m_Vertex.texMtx[6] = xfregs.MatrixIndexB.Tex6MtxIdx;
m_Vertex.texMtx[7] = xfregs.MatrixIndexB.Tex7MtxIdx;
/*m_Vertex.posMtx = MatrixIndexA.PosNormalMtxIdx;
#else
m_Vertex.posMtx = MatrixIndexA.PosNormalMtxIdx;
m_Vertex.texMtx[0] = MatrixIndexA.Tex0MtxIdx;
m_Vertex.texMtx[1] = MatrixIndexA.Tex1MtxIdx;
m_Vertex.texMtx[2] = MatrixIndexA.Tex2MtxIdx;
@ -134,7 +145,8 @@ void VertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
m_Vertex.texMtx[4] = MatrixIndexB.Tex4MtxIdx;
m_Vertex.texMtx[5] = MatrixIndexB.Tex5MtxIdx;
m_Vertex.texMtx[6] = MatrixIndexB.Tex6MtxIdx;
m_Vertex.texMtx[7] = MatrixIndexB.Tex7MtxIdx;*/
m_Vertex.texMtx[7] = MatrixIndexB.Tex7MtxIdx;
#endif
if (g_VtxDesc.PosMatIdx != NOT_PRESENT) {
AddAttributeLoader(LoadPosMtx);
@ -258,7 +270,7 @@ void VertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
m_TexGenSpecialCase =
((g_VtxDesc.Hex & 0x60600L) == g_VtxDesc.Hex) && // only pos and tex coord 0
(g_VtxDesc.Tex0Coord != NOT_PRESENT) &&
(xfregs.texMtxInfo[0].inputform == XF_TEXINPUT_AB11);
(xfregs.texMtxInfo[0].projection == XF_TEXPROJ_ST);
m_SetupUnit->Init(primitiveType);