summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Software/Tev.cpp
diff options
context:
space:
mode:
authorLinktothepast <kostamarino@gmail.com>2015-09-28 16:50:35 +0300
committerLinktothepast <kostamarino@gmail.com>2015-09-28 16:50:35 +0300
commit748be565b8df535ef558e74b38cd0f4d615f8a21 (patch)
treeb151efee0a87e99125f2401325a9bddecf84fc73 /Source/Core/VideoBackends/Software/Tev.cpp
parentcf17fccdd3093a1b8476b10183b1c4bde36da74d (diff)
parentce493b897d6d3735c930a8465cc0c26bbe5feb86 (diff)
Merge remote-tracking branch 'dolphin-emu/master' into gameinis
Diffstat (limited to 'Source/Core/VideoBackends/Software/Tev.cpp')
-rw-r--r--Source/Core/VideoBackends/Software/Tev.cpp207
1 files changed, 98 insertions, 109 deletions
diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp
index 6ea6eab051..552b60a99a 100644
--- a/Source/Core/VideoBackends/Software/Tev.cpp
+++ b/Source/Core/VideoBackends/Software/Tev.cpp
@@ -650,125 +650,120 @@ void Tev::Draw()
if (!TevAlphaTest(output[ALP_C]))
return;
- // This part is only needed if we are not simply computing bbox
- // (i. e., only needed when using the SW renderer)
- if (!BoundingBox::active)
+ // z texture
+ if (bpmem.ztex2.op)
{
- // z texture
- if (bpmem.ztex2.op)
+ u32 ztex = bpmem.ztex1.bias;
+ switch (bpmem.ztex2.type)
{
- u32 ztex = bpmem.ztex1.bias;
- switch (bpmem.ztex2.type)
- {
- case 0: // 8 bit
- ztex += TexColor[ALP_C];
- break;
- case 1: // 16 bit
- ztex += TexColor[ALP_C] << 8 | TexColor[RED_C];
- break;
- case 2: // 24 bit
- ztex += TexColor[RED_C] << 16 | TexColor[GRN_C] << 8 | TexColor[BLU_C];
- break;
- }
-
- if (bpmem.ztex2.op == ZTEXTURE_ADD)
- ztex += Position[2];
-
- Position[2] = ztex & 0x00ffffff;
+ case 0: // 8 bit
+ ztex += TexColor[ALP_C];
+ break;
+ case 1: // 16 bit
+ ztex += TexColor[ALP_C] << 8 | TexColor[RED_C];
+ break;
+ case 2: // 24 bit
+ ztex += TexColor[RED_C] << 16 | TexColor[GRN_C] << 8 | TexColor[BLU_C];
+ break;
}
- // fog
- if (bpmem.fog.c_proj_fsel.fsel)
- {
- float ze;
+ if (bpmem.ztex2.op == ZTEXTURE_ADD)
+ ztex += Position[2];
- if (bpmem.fog.c_proj_fsel.proj == 0)
- {
- // perspective
- // ze = A/(B - (Zs >> B_SHF))
- s32 denom = bpmem.fog.b_magnitude - (Position[2] >> bpmem.fog.b_shift);
- //in addition downscale magnitude and zs to 0.24 bits
- ze = (bpmem.fog.a.GetA() * 16777215.0f) / (float)denom;
- }
- else
- {
- // orthographic
- // ze = a*Zs
- //in addition downscale zs to 0.24 bits
- ze = bpmem.fog.a.GetA() * ((float)Position[2] / 16777215.0f);
+ Position[2] = ztex & 0x00ffffff;
+ }
- }
+ // fog
+ if (bpmem.fog.c_proj_fsel.fsel)
+ {
+ float ze;
- if (bpmem.fogRange.Base.Enabled)
- {
- // TODO: This is untested and should definitely be checked against real hw.
- // - No idea if offset is really normalized against the viewport width or against the projection matrix or yet something else
- // - scaling of the "k" coefficient isn't clear either.
-
- // First, calculate the offset from the viewport center (normalized to 0..1)
- float offset = (Position[0] - (bpmem.fogRange.Base.Center - 342)) / (float)xfmem.viewport.wd;
-
- // Based on that, choose the index such that points which are far away from the z-axis use the 10th "k" value and such that central points use the first value.
- float floatindex = 9.f - std::abs(offset) * 9.f;
- floatindex = (floatindex < 0.f) ? 0.f : (floatindex > 9.f) ? 9.f : floatindex; // TODO: This shouldn't be necessary!
-
- // Get the two closest integer indices, look up the corresponding samples
- int indexlower = (int)floor(floatindex);
- int indexupper = indexlower + 1;
- // Look up coefficient... Seems like multiplying by 4 makes Fortune Street work properly (fog is too strong without the factor)
- float klower = bpmem.fogRange.K[indexlower/2].GetValue(indexlower%2) * 4.f;
- float kupper = bpmem.fogRange.K[indexupper/2].GetValue(indexupper%2) * 4.f;
-
- // linearly interpolate the samples and multiple ze by the resulting adjustment factor
- float factor = indexupper - floatindex;
- float k = klower * factor + kupper * (1.f - factor);
- float x_adjust = sqrt(offset*offset + k*k)/k;
- ze *= x_adjust; // NOTE: This is basically dividing by a cosine (hidden behind GXInitFogAdjTable): 1/cos = c/b = sqrt(a^2+b^2)/b
- }
+ if (bpmem.fog.c_proj_fsel.proj == 0)
+ {
+ // perspective
+ // ze = A/(B - (Zs >> B_SHF))
+ s32 denom = bpmem.fog.b_magnitude - (Position[2] >> bpmem.fog.b_shift);
+ //in addition downscale magnitude and zs to 0.24 bits
+ ze = (bpmem.fog.a.GetA() * 16777215.0f) / (float)denom;
+ }
+ else
+ {
+ // orthographic
+ // ze = a*Zs
+ //in addition downscale zs to 0.24 bits
+ ze = bpmem.fog.a.GetA() * ((float)Position[2] / 16777215.0f);
- ze -= bpmem.fog.c_proj_fsel.GetC();
+ }
- // clamp 0 to 1
- float fog = (ze<0.0f) ? 0.0f : ((ze>1.0f) ? 1.0f : ze);
+ if (bpmem.fogRange.Base.Enabled)
+ {
+ // TODO: This is untested and should definitely be checked against real hw.
+ // - No idea if offset is really normalized against the viewport width or against the projection matrix or yet something else
+ // - scaling of the "k" coefficient isn't clear either.
+
+ // First, calculate the offset from the viewport center (normalized to 0..1)
+ float offset = (Position[0] - (bpmem.fogRange.Base.Center - 342)) / (float)xfmem.viewport.wd;
+
+ // Based on that, choose the index such that points which are far away from the z-axis use the 10th "k" value and such that central points use the first value.
+ float floatindex = 9.f - std::abs(offset) * 9.f;
+ floatindex = (floatindex < 0.f) ? 0.f : (floatindex > 9.f) ? 9.f : floatindex; // TODO: This shouldn't be necessary!
+
+ // Get the two closest integer indices, look up the corresponding samples
+ int indexlower = (int)floor(floatindex);
+ int indexupper = indexlower + 1;
+ // Look up coefficient... Seems like multiplying by 4 makes Fortune Street work properly (fog is too strong without the factor)
+ float klower = bpmem.fogRange.K[indexlower/2].GetValue(indexlower%2) * 4.f;
+ float kupper = bpmem.fogRange.K[indexupper/2].GetValue(indexupper%2) * 4.f;
+
+ // linearly interpolate the samples and multiple ze by the resulting adjustment factor
+ float factor = indexupper - floatindex;
+ float k = klower * factor + kupper * (1.f - factor);
+ float x_adjust = sqrt(offset*offset + k*k)/k;
+ ze *= x_adjust; // NOTE: This is basically dividing by a cosine (hidden behind GXInitFogAdjTable): 1/cos = c/b = sqrt(a^2+b^2)/b
+ }
- switch (bpmem.fog.c_proj_fsel.fsel)
- {
- case 4: // exp
- fog = 1.0f - pow(2.0f, -8.0f * fog);
- break;
- case 5: // exp2
- fog = 1.0f - pow(2.0f, -8.0f * fog * fog);
- break;
- case 6: // backward exp
- fog = 1.0f - fog;
- fog = pow(2.0f, -8.0f * fog);
- break;
- case 7: // backward exp2
- fog = 1.0f - fog;
- fog = pow(2.0f, -8.0f * fog * fog);
- break;
- }
+ ze -= bpmem.fog.c_proj_fsel.GetC();
- // lerp from output to fog color
- u32 fogInt = (u32)(fog * 256);
- u32 invFog = 256 - fogInt;
+ // clamp 0 to 1
+ float fog = (ze<0.0f) ? 0.0f : ((ze>1.0f) ? 1.0f : ze);
- output[RED_C] = (output[RED_C] * invFog + fogInt * bpmem.fog.color.r) >> 8;
- output[GRN_C] = (output[GRN_C] * invFog + fogInt * bpmem.fog.color.g) >> 8;
- output[BLU_C] = (output[BLU_C] * invFog + fogInt * bpmem.fog.color.b) >> 8;
+ switch (bpmem.fog.c_proj_fsel.fsel)
+ {
+ case 4: // exp
+ fog = 1.0f - pow(2.0f, -8.0f * fog);
+ break;
+ case 5: // exp2
+ fog = 1.0f - pow(2.0f, -8.0f * fog * fog);
+ break;
+ case 6: // backward exp
+ fog = 1.0f - fog;
+ fog = pow(2.0f, -8.0f * fog);
+ break;
+ case 7: // backward exp2
+ fog = 1.0f - fog;
+ fog = pow(2.0f, -8.0f * fog * fog);
+ break;
}
- bool late_ztest = !bpmem.zcontrol.early_ztest || !g_SWVideoConfig.bZComploc;
- if (late_ztest && bpmem.zmode.testenable)
- {
- // TODO: Check against hw if these values get incremented even if depth testing is disabled
- EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_INPUT);
+ // lerp from output to fog color
+ u32 fogInt = (u32)(fog * 256);
+ u32 invFog = 256 - fogInt;
- if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2]))
- return;
+ output[RED_C] = (output[RED_C] * invFog + fogInt * bpmem.fog.color.r) >> 8;
+ output[GRN_C] = (output[GRN_C] * invFog + fogInt * bpmem.fog.color.g) >> 8;
+ output[BLU_C] = (output[BLU_C] * invFog + fogInt * bpmem.fog.color.b) >> 8;
+ }
- EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_OUTPUT);
- }
+ bool late_ztest = !bpmem.zcontrol.early_ztest || !g_SWVideoConfig.bZComploc;
+ if (late_ztest && bpmem.zmode.testenable)
+ {
+ // TODO: Check against hw if these values get incremented even if depth testing is disabled
+ EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_INPUT);
+
+ if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2]))
+ return;
+
+ EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_OUTPUT);
}
// branchless bounding box update
@@ -777,12 +772,6 @@ void Tev::Draw()
BoundingBox::coords[BoundingBox::TOP] = std::min((u16)Position[1], BoundingBox::coords[BoundingBox::TOP]);
BoundingBox::coords[BoundingBox::BOTTOM] = std::max((u16)Position[1], BoundingBox::coords[BoundingBox::BOTTOM]);
- // if we are only calculating the bounding box,
- // there's no need to actually draw anything
- if (BoundingBox::active)
- return;
-
-
#if ALLOW_TEV_DUMPS
if (g_SWVideoConfig.bDumpTevStages)
{