diff options
| author | Linktothepast <kostamarino@gmail.com> | 2015-09-28 16:50:35 +0300 |
|---|---|---|
| committer | Linktothepast <kostamarino@gmail.com> | 2015-09-28 16:50:35 +0300 |
| commit | 748be565b8df535ef558e74b38cd0f4d615f8a21 (patch) | |
| tree | b151efee0a87e99125f2401325a9bddecf84fc73 /Source/Core/VideoBackends/Software/Tev.cpp | |
| parent | cf17fccdd3093a1b8476b10183b1c4bde36da74d (diff) | |
| parent | ce493b897d6d3735c930a8465cc0c26bbe5feb86 (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.cpp | 207 |
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) { |
