GSdx: Even more alpha test voodoo magic, it must be nailed now!

And there is even an explanation. 

The tfx functions calculate At * Af >> 7, which means modulating by 0x80 should return At as the result. 

With the evil floating point pixel shader however 0x80 translates to 128/255 (0.502), not exactly 0.5, modulation as At' * Af' * 2 (' means 0 - 1.0 range) is not the same as with integers.

At' = Af' = 0.502
At' * Af' * 2 = 0.504

If the alpha test happens to be "not equal to 0x80", then abs(0.504 - 128/255) < 0.5/255 will just miss.

Solution is to re-scale those values to the integer range, do the calculations, and then back to float again, but in the end it just simplifies down to At' * Af' * 255/128, doh...

At * Af >> 7 => ((At' * 255) * (Af' * 255) / 128) / 255 => At' * Af' * 255/128

At' = Af' = 0.502
0.502 * 0.502 * 255/128 = 0.502 (w00t!)


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1272 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-05-27 05:55:32 +00:00
parent b1eadad216
commit 3e12966919
4 changed files with 11 additions and 11 deletions

View File

@ -511,7 +511,7 @@ void GSDevice10::IASetVertexBuffer(const void* vertices, size_t stride, size_t c
{
ASSERT(m_vertices.count == 0);
if(count > m_vertices.limit)
if(count * stride > m_vertices.limit * m_vertices.stride)
{
m_vertices.vb_old = m_vertices.vb;
m_vertices.vb = NULL;

View File

@ -648,7 +648,7 @@ void GSDevice9::IASetVertexBuffer(const void* vertices, size_t stride, size_t co
{
ASSERT(m_vertices.count == 0);
if(count > m_vertices.limit)
if(count * stride > m_vertices.limit * m_vertices.stride)
{
m_vertices.vb_old = m_vertices.vb;
m_vertices.vb = NULL;

View File

@ -414,11 +414,11 @@ PS_OUTPUT ps_main(PS_INPUT input)
{
if(TCC == 0)
{
c.rgb = c.rgb * t.rgb * 2;
c.rgb = c.rgb * t.rgb * 255.0f / 128;
}
else
{
c = c * t * 2;
c = c * t * 255.0f / 128;
}
}
else if(TFX == 1)
@ -434,7 +434,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
}
else if(TFX == 2)
{
c.rgb = c.rgb * t.rgb * 2 + c.a;
c.rgb = c.rgb * t.rgb * 255.0f / 128 + c.a;
if(TCC == 1)
{
@ -443,7 +443,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
}
else if(TFX == 3)
{
c.rgb = c.rgb * t.rgb * 2 + c.a;
c.rgb = c.rgb * t.rgb * 255.0f / 128 + c.a;
if(TCC == 1)
{

View File

@ -241,11 +241,11 @@ float4 ps_main(PS_INPUT input) : COLOR
{
if(TCC == 0)
{
c.rgb = c.rgb * t.rgb * 2;
c.rgb = c.rgb * t.rgb * 255.0f / 128;
}
else
{
c = c * t * 2;
c = c * t * 255.0f / 128;
}
}
else if(TFX == 1)
@ -261,7 +261,7 @@ float4 ps_main(PS_INPUT input) : COLOR
}
else if(TFX == 2)
{
c.rgb = c.rgb * t.rgb * 2 + c.a;
c.rgb = c.rgb * t.rgb * 255.0f / 128 + c.a;
if(TCC == 1)
{
@ -270,7 +270,7 @@ float4 ps_main(PS_INPUT input) : COLOR
}
else if(TFX == 3)
{
c.rgb = c.rgb * t.rgb * 2 + c.a;
c.rgb = c.rgb * t.rgb * 255.0f / 128 + c.a;
if(TCC == 1)
{
@ -292,7 +292,7 @@ float4 ps_main(PS_INPUT input) : COLOR
}
else if(ATST == 4) // e
{
clip(0.6f / 256 - abs(c.a - AREF)); // FIXME: 0.5f is too small
clip(0.6f / 255 - abs(c.a - AREF)); // FIXME: 0.5f is too small
}
else if(ATST == 5 || ATST == 6) // ge, g
{