some work on zscale and zoffset, don't know if this is correct but at least it seem to fix one or two games.
thanks a lot to chaoscode he make possible to test this on nvidia. please test this a lot and give me feedback :) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4468 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
1adc944115
commit
0511d6e185
|
@ -31,7 +31,7 @@ static bool s_bZTextureTypeChanged;
|
|||
static bool s_bDepthRangeChanged;
|
||||
static bool s_bFogColorChanged;
|
||||
static bool s_bFogParamChanged;
|
||||
static float lastDepthRange[2]; // 0 = far z, 1 = far - near
|
||||
static float lastDepthRange[4]; // 0 = far z, 1 = far - near, 2 = scale , 3 = offset
|
||||
static float lastRGBAfull[2][4][4];
|
||||
static float lastCustomTexScale[8][2];
|
||||
static u8 s_nTexDimsChanged;
|
||||
|
@ -54,6 +54,10 @@ void PixelShaderManager::Init()
|
|||
lastZBias = 0;
|
||||
s_texturemask = 0;
|
||||
memset(lastRGBAfull, 0, sizeof(lastRGBAfull));
|
||||
lastDepthRange[0]=16777216.0f;
|
||||
lastDepthRange[1]=16777216.0f;
|
||||
lastDepthRange[2]=16777216.0f;
|
||||
lastDepthRange[3]=0.0f;
|
||||
Dirty();
|
||||
}
|
||||
|
||||
|
@ -132,7 +136,7 @@ void PixelShaderManager::SetConstants()
|
|||
if (s_bZBiasChanged || s_bDepthRangeChanged)
|
||||
{
|
||||
//ERROR_LOG("pixel=%x,%x, bias=%x\n", bpmem.zcontrol.pixel_format, bpmem.ztex2.type, lastZBias);
|
||||
SetPSConstant4f(C_ZBIAS+1, lastDepthRange[0] / 16777215.0f, lastDepthRange[1] / 16777215.0f, 0, (float)( (((int)lastZBias<<8)>>8))/16777215.0f);
|
||||
SetPSConstant4f(C_ZBIAS+1, (lastDepthRange[0] + lastDepthRange[3]) / lastDepthRange[2], (lastDepthRange[1] + lastDepthRange[3]) / lastDepthRange[2], 0, (float)( (((int)lastZBias<<8)>>8))/16777215.0f);
|
||||
s_bZBiasChanged = s_bDepthRangeChanged = false;
|
||||
}
|
||||
|
||||
|
@ -326,6 +330,24 @@ void PixelShaderManager::SetViewport(float* viewport)
|
|||
}
|
||||
}
|
||||
|
||||
void PixelShaderManager::SetZScale(float data)
|
||||
{
|
||||
if (lastDepthRange[2] != data)
|
||||
{
|
||||
lastDepthRange[2] = data;
|
||||
s_bDepthRangeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PixelShaderManager::SetZOffset(float data)
|
||||
{
|
||||
if (lastDepthRange[3] != data)
|
||||
{
|
||||
lastDepthRange[3] = data;
|
||||
s_bDepthRangeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PixelShaderManager::SetIndTexScaleChanged(u8 stagemask)
|
||||
{
|
||||
s_nIndTexScaleChanged |= stagemask;
|
||||
|
|
|
@ -54,6 +54,8 @@ public:
|
|||
static void SetFogParamChanged();
|
||||
static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd);
|
||||
static u32 GetTextureMask();
|
||||
static void SetZScale(float data);
|
||||
static void SetZOffset(float data);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ const char *GenerateVertexShader(u32 components, bool D3D)
|
|||
//"half3 norm2 = normalize(_norm2);\n");
|
||||
}
|
||||
else {
|
||||
WRITE(p, "float4 pos = float4(dot("I_POSNORMALMATRIX".T0, rawpos), dot("I_POSNORMALMATRIX".T1, rawpos), dot("I_POSNORMALMATRIX".T2, rawpos), 1);\n");
|
||||
WRITE(p, "float4 pos = float4(dot("I_POSNORMALMATRIX".T0, rawpos), dot("I_POSNORMALMATRIX".T1, rawpos), dot("I_POSNORMALMATRIX".T2, rawpos), 1.0f);\n");
|
||||
if (components & VB_HAS_NRM0)
|
||||
WRITE(p, "half3 _norm0 = half3(dot("I_POSNORMALMATRIX".N0.xyz, rawnorm0), dot("I_POSNORMALMATRIX".N1.xyz, rawnorm0), dot("I_POSNORMALMATRIX".N2.xyz, rawnorm0));\n"
|
||||
"half3 norm0 = normalize(_norm0);\n");
|
||||
|
@ -243,7 +243,7 @@ const char *GenerateVertexShader(u32 components, bool D3D)
|
|||
if (components & (VB_HAS_COL0<<j) )
|
||||
WRITE(p, "lacc = color%d;\n", j);
|
||||
else
|
||||
WRITE(p, "lacc = half4(0.0f,0.0f,0.0f,0.0f);\n");
|
||||
WRITE(p, "lacc = half4(0,0,0,0);\n");
|
||||
}
|
||||
else // from color
|
||||
WRITE(p, "lacc = "I_MATERIALS".C%d;\n", j);
|
||||
|
@ -338,7 +338,7 @@ const char *GenerateVertexShader(u32 components, bool D3D)
|
|||
case XF_SRCNORMAL_INROW:
|
||||
if (components & VB_HAS_NRM0) {
|
||||
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
|
||||
WRITE(p, "float4 coord = float4(rawnorm0.xyz, 1.0);\n");
|
||||
WRITE(p, "float4 coord = float4(rawnorm0.xyz, 1.0f);\n");
|
||||
}
|
||||
else WRITE(p, "float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); // avoid errors
|
||||
break;
|
||||
|
@ -348,14 +348,14 @@ const char *GenerateVertexShader(u32 components, bool D3D)
|
|||
case XF_SRCBINORMAL_T_INROW:
|
||||
if (components & VB_HAS_NRM1) {
|
||||
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
|
||||
WRITE(p, "float4 coord = float4(rawnorm1.xyz, 1.0);\n");
|
||||
WRITE(p, "float4 coord = float4(rawnorm1.xyz, 1.0f);\n");
|
||||
}
|
||||
else WRITE(p, "float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); // avoid errors
|
||||
break;
|
||||
case XF_SRCBINORMAL_B_INROW:
|
||||
if (components & VB_HAS_NRM2) {
|
||||
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
|
||||
WRITE(p, "float4 coord = float4(rawnorm2.xyz, 1.0);\n");
|
||||
WRITE(p, "float4 coord = float4(rawnorm2.xyz, 1.0f);\n");
|
||||
}
|
||||
else WRITE(p, "float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n"); // avoid errors
|
||||
break;
|
||||
|
@ -479,7 +479,7 @@ char* GenerateLightShader(char* p, int index, const LitChannel& chan, const char
|
|||
WRITE(p, "attn = max(0.0f, dot("I_LIGHTS".lights[%d].cosatt.xyz, half3(1, attn, attn*attn))) / dot("I_LIGHTS".lights[%d].distatt.xyz, half3(1,dist,dist2));\n", index, index);
|
||||
}
|
||||
else if (chan.attnfunc == 1) { // specular
|
||||
WRITE(p, "attn = dot(norm0, "I_LIGHTS".lights[%d].pos.xyz) > 0 ? max(0.0f, dot(norm0, "I_LIGHTS".lights[%d].dir.xyz)) : 0;\n", index, index);
|
||||
WRITE(p, "attn = dot(norm0, "I_LIGHTS".lights[%d].pos.xyz) > 0.0f ? max(0.0f, dot(norm0, "I_LIGHTS".lights[%d].dir.xyz)) : 0.0f;\n", index, index);
|
||||
WRITE(p, "ldir = half3(1,attn,attn*attn);\n");
|
||||
WRITE(p, "attn = max(0.0f, dot("I_LIGHTS".lights[%d].cosatt.xyz, ldir)) / dot("I_LIGHTS".lights[%d].distatt.xyz, ldir);\n", index, index);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,8 @@ void VertexShaderManager::Init()
|
|||
|
||||
memset(&xfregs, 0, sizeof(xfregs));
|
||||
memset(xfmem, 0, sizeof(xfmem));
|
||||
|
||||
xfregs.ZScale = 16777216.0f;
|
||||
xfregs.Zoffset = 0.0f;
|
||||
ResetView();
|
||||
}
|
||||
|
||||
|
@ -451,6 +452,18 @@ void VertexShaderManager::SetViewport(float* _Viewport)
|
|||
bViewportChanged = true;
|
||||
}
|
||||
|
||||
void VertexShaderManager::SetZScale(float data)
|
||||
{
|
||||
xfregs.ZScale = data;
|
||||
bViewportChanged = true;
|
||||
}
|
||||
|
||||
void VertexShaderManager::SetZOffset(float data)
|
||||
{
|
||||
xfregs.Zoffset = data;
|
||||
bViewportChanged = true;
|
||||
}
|
||||
|
||||
void VertexShaderManager::SetViewportChanged()
|
||||
{
|
||||
bViewportChanged = true;
|
||||
|
|
|
@ -38,6 +38,8 @@ public:
|
|||
static void SetTexMatrixChangedA(u32 Value);
|
||||
static void SetTexMatrixChangedB(u32 Value);
|
||||
static void SetMaterialColor(int index, u32 data);
|
||||
static void SetZScale(float data);
|
||||
static void SetZOffset(float data);
|
||||
|
||||
static void TranslateView(float x, float y);
|
||||
static void RotateView(float x, float y);
|
||||
|
|
|
@ -228,6 +228,8 @@ struct XFRegisters
|
|||
bool bEnableDualTexTransform;
|
||||
float rawViewport[6];
|
||||
float rawProjection[7];
|
||||
float ZScale;
|
||||
float Zoffset;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -174,12 +174,18 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
|
|||
// paper mario writes 16777216.0f, 1677721.75
|
||||
// Killer 7 writes 16777216.0f here
|
||||
case XFMEM_SETZSCALE:
|
||||
VertexManager::Flush();
|
||||
VertexShaderManager::SetZScale((float)data);
|
||||
PixelShaderManager::SetZScale((float)data);
|
||||
INFO_LOG(VIDEO, "Set ZScale : %x=%x\n", address, data);
|
||||
break;
|
||||
|
||||
// paper mario writes 16777216.0f, 5033165.0f
|
||||
// Killer 7 alterns this between 16777216.0f and 16710107.0f
|
||||
case XFMEM_SETZOFFSET:
|
||||
VertexManager::Flush();
|
||||
VertexShaderManager::SetZOffset((float)data);
|
||||
PixelShaderManager::SetZOffset((float)data);
|
||||
INFO_LOG(VIDEO, "Set ZOffset : %x=%x\n", address, data);
|
||||
break;
|
||||
|
||||
|
|
|
@ -610,9 +610,9 @@ void UpdateViewport()
|
|||
|
||||
vp.Width = (int)ceil(abs((int)(2 * xfregs.rawViewport[0])) * MValueX);
|
||||
vp.Height = (int)ceil(abs((int)(2 * xfregs.rawViewport[1])) * MValueY);
|
||||
|
||||
vp.MinZ = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777215.0f;
|
||||
vp.MaxZ = xfregs.rawViewport[5] / 16777215.0f;
|
||||
//new depth equation , don't know if is correct but...
|
||||
vp.MinZ = (xfregs.rawViewport[5] - xfregs.rawViewport[2]+xfregs.Zoffset) / xfregs.ZScale;
|
||||
vp.MaxZ = (xfregs.rawViewport[5] + xfregs.Zoffset) / xfregs.ZScale;
|
||||
|
||||
// This seems to happen a lot - the above calc is probably wrong.
|
||||
if (vp.MinZ < 0.0f) vp.MinZ = 0.0f;
|
||||
|
|
|
@ -333,7 +333,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
|||
|
||||
glGenTextures(1, &xfbTexture);
|
||||
|
||||
#if 0 // XXX: Some video drivers don't handle glCopyTexImage2D correctly, so use EXT_framebuffer_blit whenever possible.
|
||||
#if 1 // XXX: Some video drivers don't handle glCopyTexImage2D correctly, so use EXT_framebuffer_blit whenever possible.
|
||||
if (m_msaaSamples > 1)
|
||||
#else
|
||||
if (s_bHaveFramebufferBlit)
|
||||
|
@ -373,7 +373,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
|||
|
||||
// Copy EFB to XFB texture
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
if (m_msaaSamples <= 1)
|
||||
#else
|
||||
if (!s_bHaveFramebufferBlit)
|
||||
|
|
|
@ -1344,8 +1344,9 @@ void UpdateViewport()
|
|||
int GLy = (int)ceil(Renderer::GetTargetHeight() - ((int)(xfregs.rawViewport[4] - xfregs.rawViewport[1] - scissorYOff)) * MValueY);
|
||||
int GLWidth = (int)ceil(abs((int)(2 * xfregs.rawViewport[0])) * MValueX);
|
||||
int GLHeight = (int)ceil(abs((int)(2 * xfregs.rawViewport[1])) * MValueY);
|
||||
double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777215.0f;
|
||||
double GLFar = xfregs.rawViewport[5] / 16777215.0f;
|
||||
//new dept equation , don't know if is correct but...
|
||||
double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2] + xfregs.Zoffset) / xfregs.ZScale;
|
||||
double GLFar = (xfregs.rawViewport[5] + xfregs.Zoffset) / xfregs.ZScale;
|
||||
|
||||
// Update the view port
|
||||
glViewport(GLx, GLy, GLWidth, GLHeight);
|
||||
|
|
|
@ -280,7 +280,7 @@ void VertexShaderCache::DisableShader()
|
|||
|
||||
void VertexShaderCache::SetCurrentShader(GLuint Shader)
|
||||
{
|
||||
if(ShaderEnabled /*&& CurrentShader != Shader*/)
|
||||
if(ShaderEnabled && CurrentShader != Shader)
|
||||
{
|
||||
CurrentShader = Shader;
|
||||
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, CurrentShader);
|
||||
|
|
Loading…
Reference in New Issue