Rework XF register loading a bit and change how registers are arranged in memory. This removes the assumption that all data for a viewport or projection matrix will be available when index 0 is loaded. Fixes issue 3688 and probably breaks old save states (sorry).

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7083 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
donkopunchstania
2011-02-05 18:25:34 +00:00
parent 98e24f5873
commit c36ed08cfc
10 changed files with 414 additions and 379 deletions

View File

@ -32,31 +32,31 @@ VERTEXSHADERUID last_vertex_shader_uid;
void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components)
{
uid->values[0] = components |
(xfregs.numTexGens << 23) |
(xfregs.nNumChans << 27) |
((u32)xfregs.bEnableDualTexTransform << 29);
(xfregs.numTexGen.numTexGens << 23) |
(xfregs.numChan.numColorChans << 27) |
(xfregs.dualTexTrans.enabled << 29);
for (int i = 0; i < 2; ++i) {
uid->values[1+i] = xfregs.colChans[i].color.enablelighting ?
(u32)xfregs.colChans[i].color.hex :
(u32)xfregs.colChans[i].color.matsource;
uid->values[1+i] |= (xfregs.colChans[i].alpha.enablelighting ?
(u32)xfregs.colChans[i].alpha.hex :
(u32)xfregs.colChans[i].alpha.matsource) << 15;
uid->values[1+i] = xfregs.color[i].enablelighting ?
(u32)xfregs.color[i].hex :
(u32)xfregs.color[i].matsource;
uid->values[1+i] |= (xfregs.alpha[i].enablelighting ?
(u32)xfregs.alpha[i].hex :
(u32)xfregs.alpha[i].matsource) << 15;
}
uid->values[2] |= (g_ActiveConfig.bEnablePixelLigting && g_ActiveConfig.backend_info.bSupportsPixelLighting) << 31;
u32 *pcurvalue = &uid->values[3];
for (int i = 0; i < xfregs.numTexGens; ++i) {
TexMtxInfo tinfo = xfregs.texcoords[i].texmtxinfo;
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.bEnableDualTexTransform && tinfo.texgentype == XF_TEXGEN_REGULAR) {
if (xfregs.dualTexTrans.enabled && tinfo.texgentype == XF_TEXGEN_REGULAR) {
// rewrite normalization and post index
val |= ((u32)xfregs.texcoords[i].postmtxinfo.index << 17) | ((u32)xfregs.texcoords[i].postmtxinfo.normalize << 23);
val |= ((u32)xfregs.postMtxInfo[i].index << 17) | ((u32)xfregs.postMtxInfo[i].normalize << 23);
}
switch (i & 3) {
@ -81,15 +81,15 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
setlocale(LC_NUMERIC, "C"); // Reset locale for compilation
text[sizeof(text) - 1] = 0x7C; // canary
_assert_(bpmem.genMode.numtexgens == xfregs.numTexGens);
_assert_(bpmem.genMode.numcolchans == xfregs.nNumChans);
_assert_(bpmem.genMode.numtexgens == xfregs.numTexGen.numTexGens);
_assert_(bpmem.genMode.numcolchans == xfregs.numChan.numColorChans);
bool is_d3d = (api_type == API_D3D9 || api_type == API_D3D11);
u32 lightMask = 0;
if (xfregs.nNumChans > 0)
lightMask |= xfregs.colChans[0].color.GetFullLightMask() | xfregs.colChans[0].alpha.GetFullLightMask();
if (xfregs.nNumChans > 1)
lightMask |= xfregs.colChans[1].color.GetFullLightMask() | xfregs.colChans[1].alpha.GetFullLightMask();
if (xfregs.numChan.numColorChans > 0)
lightMask |= xfregs.color[0].GetFullLightMask() | xfregs.alpha[0].GetFullLightMask();
if (xfregs.numChan.numColorChans > 1)
lightMask |= xfregs.color[1].GetFullLightMask() | xfregs.alpha[1].GetFullLightMask();
char *p = text;
WRITE(p, "//Vertex Shader: comp:%x, \n", components);
@ -110,12 +110,12 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
WRITE(p, " float4 colors_0 : COLOR0;\n");
WRITE(p, " float4 colors_1 : COLOR1;\n");
if (xfregs.numTexGens < 7) {
for (int i = 0; i < xfregs.numTexGens; ++i)
if (xfregs.numTexGen.numTexGens < 7) {
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
WRITE(p, " float3 tex%d : TEXCOORD%d;\n", i, i);
WRITE(p, " float4 clipPos : TEXCOORD%d;\n", xfregs.numTexGens);
WRITE(p, " float4 clipPos : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens);
if(g_ActiveConfig.bEnablePixelLigting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
WRITE(p, " float4 Normal : TEXCOORD%d;\n", xfregs.numTexGens + 1);
WRITE(p, " float4 Normal : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens + 1);
} else {
// clip position is in w of first 4 texcoords
if(g_ActiveConfig.bEnablePixelLigting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
@ -125,7 +125,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
}
else
{
for (int i = 0; i < xfregs.numTexGens; ++i)
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
WRITE(p, " float%d tex%d : TEXCOORD%d;\n", i < 4 ? 4 : 3 , i, i);
}
}
@ -231,7 +231,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
"float3 ldir, h;\n"
"float dist, dist2, attn;\n");
if(xfregs.nNumChans == 0)
if(xfregs.numChan.numColorChans == 0)
{
if (components & VB_HAS_COL0)
WRITE(p, "o.colors_0 = color0;\n");
@ -239,10 +239,10 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
WRITE(p, "o.colors_0 = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
}
// lights/colors
for (int j = 0; j < xfregs.nNumChans; j++)
for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++)
{
const LitChannel& color = xfregs.colChans[j].color;
const LitChannel& alpha = xfregs.colChans[j].alpha;
const LitChannel& color = xfregs.color[j];
const LitChannel& alpha = xfregs.alpha[j];
WRITE(p, "{\n");
@ -345,7 +345,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
WRITE(p, "o.colors_%d = mat * saturate(lacc);\n", j);
WRITE(p, "}\n");
}
if(xfregs.nNumChans < 2)
if(xfregs.numChan.numColorChans < 2)
{
if (components & VB_HAS_COL1)
WRITE(p, "o.colors_1 = color1;\n");
@ -363,8 +363,8 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
// transform texcoords
WRITE(p, "float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n");
for (int i = 0; i < xfregs.numTexGens; ++i) {
TexMtxInfo& texinfo = xfregs.texcoords[i].texmtxinfo;
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");
@ -443,8 +443,10 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
break;
}
if (xfregs.bEnableDualTexTransform && texinfo.texgentype == XF_TEXGEN_REGULAR) { // only works for regular tex gen types?
int postidx = xfregs.texcoords[i].postmtxinfo.index;
if (xfregs.dualTexTrans.enabled && texinfo.texgentype == XF_TEXGEN_REGULAR) { // only works for regular tex gen types?
const PostMtxInfo& postInfo = xfregs.postMtxInfo[i];
int postidx = postInfo.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",
@ -460,7 +462,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
}
else
{
if (xfregs.texcoords[i].postmtxinfo.normalize)
if (postInfo.normalize)
WRITE(p, "o.tex%d.xyz = normalize(o.tex%d.xyz);\n", i, i);
// multiply by postmatrix
@ -472,7 +474,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
}
// clipPos/w needs to be done in pixel shader, not here
if (xfregs.numTexGens < 7) {
if (xfregs.numTexGen.numTexGens < 7) {
WRITE(p, "o.clipPos = float4(pos.x,pos.y,o.pos.z,o.pos.w);\n");
} else {
WRITE(p, "o.tex0.w = pos.x;\n");
@ -483,13 +485,13 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
if(g_ActiveConfig.bEnablePixelLigting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
if (xfregs.numTexGens < 7) {
if (xfregs.numTexGen.numTexGens < 7) {
WRITE(p, "o.Normal = float4(_norm0.x,_norm0.y,_norm0.z,pos.z);\n");
} 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");
if (xfregs.numTexGens < 8)
if (xfregs.numTexGen.numTexGens < 8)
WRITE(p, "o.tex7 = pos.xyzz;\n");
else
WRITE(p, "o.tex7.w = pos.z;\n");