diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index f54d428a2b..fcba116bf2 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -22,6 +22,7 @@ #include "NativeVertexFormat.h" #include "BPMemory.h" +#include "CPMemory.h" #include "VertexShaderGen.h" VERTEXSHADERUID last_vertex_shader_uid; @@ -323,6 +324,12 @@ const char *GenerateVertexShader(u32 components, bool D3D) for (int i = xfregs.nNumChans; i < 2; ++i) WRITE(p, "o.colors[%d] = float4(0.0f,0.0f,0.0f,0.0f);\n", i); + // special case if only pos and tex coord 0 and tex coord input is AB11 + bool texGenSpecialCase = + ((g_VtxDesc.Hex & 0x60600L) == g_VtxDesc.Hex) && // only pos and tex coord 0 + (g_VtxDesc.Tex0Coord != NOT_PRESENT) && + (xfregs.texcoords[0].texmtxinfo.inputform == XF_TEXINPUT_AB11); + // transform texcoords for (int i = 0; i < xfregs.numTexGens; ++i) { TexMtxInfo& texinfo = xfregs.texcoords[i].texmtxinfo; @@ -404,16 +411,27 @@ const char *GenerateVertexShader(u32 components, bool D3D) } if(xfregs.bEnableDualTexTransform && texinfo.texgentype == XF_TEXGEN_REGULAR) { // only works for regular tex gen types? - if (xfregs.texcoords[i].postmtxinfo.normalize) - WRITE(p, "o.tex%d.xyz = normalize(o.tex%d.xyz);\n", i, i); + int postidx = xfregs.texcoords[i].postmtxinfo.index; + WRITE(p, "float4 P0 = "I_POSTTRANSFORMMATRICES".T[%d].t;\n" + "float4 P1 = "I_POSTTRANSFORMMATRICES".T[%d].t;\n" + "float4 P2 = "I_POSTTRANSFORMMATRICES".T[%d].t;\n", + postidx&0x3f, (postidx+1)&0x3f, (postidx+2)&0x3f); - //multiply by postmatrix - int postidx = xfregs.texcoords[i].postmtxinfo.index; - WRITE(p, "float4 P0 = "I_POSTTRANSFORMMATRICES".T[%d].t;\n" - "float4 P1 = "I_POSTTRANSFORMMATRICES".T[%d].t;\n" - "float4 P2 = "I_POSTTRANSFORMMATRICES".T[%d].t;\n", - postidx&0x3f, (postidx+1)&0x3f, (postidx+2)&0x3f); - WRITE(p, "o.tex%d.xyz = float3(dot(P0.xyz, o.tex%d.xyz) + P0.w, dot(P1.xyz, o.tex%d.xyz) + P1.w, dot(P2.xyz, o.tex%d.xyz) + P2.w);\n", i, i, i, i); + if (texGenSpecialCase) { + // no normalization + // q of input is 1 + // q of output is unknown + + //multiply by postmatrix + WRITE(p, "o.tex%d.xyz = float3(dot(P0.xy, o.tex%d.xy) + P0.z + P0.w, dot(P1.xy, o.tex%d.xy) + P1.z + P1.w, 0.0f);\n", i, i, i); + } + else { + if (xfregs.texcoords[i].postmtxinfo.normalize) + WRITE(p, "o.tex%d.xyz = normalize(o.tex%d.xyz);\n", i, i); + + //multiply by postmatrix + WRITE(p, "o.tex%d.xyz = float3(dot(P0.xyz, o.tex%d.xyz) + P0.w, dot(P1.xyz, o.tex%d.xyz) + P1.w, dot(P2.xyz, o.tex%d.xyz) + P2.w);\n", i, i, i, i); + } } WRITE(p, "}\n"); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/TransformUnit.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/TransformUnit.cpp index 38c1cc853f..b955d233e9 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/TransformUnit.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/TransformUnit.cpp @@ -109,7 +109,7 @@ void TransformNormal(const InputVertexData *src, bool nbt, OutputVertexData *dst } } -inline void TransformTexCoordRegular(const TexMtxInfo &texinfo, int coordNum, const InputVertexData *srcVertex, OutputVertexData *dstVertex) +inline void TransformTexCoordRegular(const TexMtxInfo &texinfo, int coordNum, bool specialCase, const InputVertexData *srcVertex, OutputVertexData *dstVertex) { const float *src; switch (texinfo.sourcerow) @@ -150,23 +150,39 @@ inline void TransformTexCoordRegular(const TexMtxInfo &texinfo, int coordNum, co // normalize const PostMtxInfo &postInfo = xfregs.postMtxInfo[coordNum]; - if (postInfo.normalize) - { - float length = sqrtf(dst[0] * dst[0] + dst[1] * dst[1] + dst[2] * dst[2]); - float invL = 1.0f / length; - tempCoord[0] = invL * dst[0]; - tempCoord[1] = invL * dst[1]; - tempCoord[2] = invL * dst[2]; - } - else - { - tempCoord[0] = dst[0]; - tempCoord[1] = dst[1]; - tempCoord[2] = dst[2]; - } + const float *postMat = (const float*)&xfregs.postMatrices[postInfo.index * 4]; - const float *postMat = (const float*)&xfregs.postMatrices[postInfo.index * 4]; - MultiplyVec3Mat34(tempCoord, postMat, dst); + if (specialCase) + { + // no normalization + // q of input is 1 + // q of output is unknown + tempCoord[0] = dst[0]; + tempCoord[1] = dst[1]; + + dst[0] = postMat[0] * tempCoord[0] + postMat[1] * tempCoord[1] + postMat[2] + postMat[3]; + dst[1] = postMat[4] * tempCoord[0] + postMat[5] * tempCoord[1] + postMat[6] + postMat[7]; + dst[2] = 0.0f; + } + else + { + if (postInfo.normalize) + { + float length = sqrtf(dst[0] * dst[0] + dst[1] * dst[1] + dst[2] * dst[2]); + float invL = 1.0f / length; + tempCoord[0] = invL * dst[0]; + tempCoord[1] = invL * dst[1]; + tempCoord[2] = invL * dst[2]; + } + else + { + tempCoord[0] = dst[0]; + tempCoord[1] = dst[1]; + tempCoord[2] = dst[2]; + } + + MultiplyVec3Mat34(tempCoord, postMat, dst); + } } } @@ -443,7 +459,7 @@ void TransformColor(const InputVertexData *src, OutputVertexData *dst) } } -void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst) +void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool specialCase) { for (u32 coordNum = 0; coordNum < xfregs.numTexGens; coordNum++) { @@ -452,7 +468,7 @@ void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst) switch (texinfo.texgentype) { case XF_TEXGEN_REGULAR: - TransformTexCoordRegular(texinfo, coordNum, src, dst); + TransformTexCoordRegular(texinfo, coordNum, specialCase, src, dst); break; case XF_TEXGEN_EMBOSS_MAP: { diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/TransformUnit.h b/Source/Plugins/Plugin_VideoSoftware/Src/TransformUnit.h index b2f7a155e4..d45be8e3d8 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/TransformUnit.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/TransformUnit.h @@ -31,7 +31,7 @@ namespace TransformUnit void TransformPosition(const InputVertexData *src, OutputVertexData *dst); void TransformNormal(const InputVertexData *src, bool nbt, OutputVertexData *dst); void TransformColor(const InputVertexData *src, OutputVertexData *dst); - void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst); + void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool specialCase); } #endif diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VertexLoader.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/VertexLoader.cpp index 7a14969b78..ad8a850cb8 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VertexLoader.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VertexLoader.cpp @@ -320,6 +320,13 @@ void VertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType) } } + // special case if only pos and tex coord 0 and tex coord input is AB11 + 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); + + m_SetupUnit->Init(primitiveType); } @@ -341,7 +348,7 @@ void VertexLoader::LoadVertex() TransformUnit::TransformColor(&m_Vertex, outVertex); - TransformUnit::TransformTexCoord(&m_Vertex, outVertex); + TransformUnit::TransformTexCoord(&m_Vertex, outVertex, m_TexGenSpecialCase); m_SetupUnit->SetupVertex(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VertexLoader.h b/Source/Plugins/Plugin_VideoSoftware/Src/VertexLoader.h index 9a3935a610..d1f2622e19 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VertexLoader.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VertexLoader.h @@ -61,6 +61,8 @@ class VertexLoader SetupUnit *m_SetupUnit; + bool m_TexGenSpecialCase; + public: VertexLoader(); ~VertexLoader();