D3D: Fix render states on reset (resize). Add detection of INTZ texture format (undocumented, but both nVidia and AMD aupport it). Not sure if we'll actually use it.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4286 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-09-16 20:12:14 +00:00
parent a8270d50ee
commit 2eece4c2f4
2 changed files with 67 additions and 10 deletions

View File

@ -49,11 +49,12 @@ static int cur_adapter;
// Value caches for state filtering // Value caches for state filtering
const int MaxTextureStages = 9; const int MaxTextureStages = 9;
const int MaxRenderStates = 210; const int MaxRenderStates = 210 + 46;
const DWORD MaxTextureTypes = 33; const int MaxTextureTypes = 33;
const DWORD MaxSamplerSize = 13; const int MaxSamplerSize = 13;
const DWORD MaxSamplerTypes = 15; const int MaxSamplerTypes = 15;
static DWORD m_RenderStates[MaxRenderStates+46]; static bool m_RenderStatesSet[MaxRenderStates];
static DWORD m_RenderStates[MaxRenderStates];
static DWORD m_TextureStageStates[MaxTextureStages][MaxTextureTypes]; static DWORD m_TextureStageStates[MaxTextureStages][MaxTextureTypes];
static DWORD m_SamplerStates[MaxSamplerSize][MaxSamplerTypes]; static DWORD m_SamplerStates[MaxSamplerSize][MaxSamplerTypes];
LPDIRECT3DBASETEXTURE9 m_Textures[16]; LPDIRECT3DBASETEXTURE9 m_Textures[16];
@ -185,6 +186,24 @@ void Enumerate()
} }
} }
} }
// Determine if INTZ is supported. Code from ATI's doc.
// http://developer.amd.com/gpu_assets/Advanced%20DX9%20Capabilities%20for%20ATI%20Radeon%20Cards.pdf
a.supports_intz = D3D_OK == D3D->CheckDeviceFormat(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_INTZ);
// Also check for RAWZ (nvidia only, but the only option to get Z24 textures on sub GF8800
a.supports_rawz = D3D_OK == D3D->CheckDeviceFormat(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_RAWZ);
// Might as well check for RESZ and NULL too.
a.supports_resz = D3D_OK == D3D->CheckDeviceFormat(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_RESZ);
a.supports_resz = D3D_OK == D3D->CheckDeviceFormat(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_NULL);
if (a.aa_levels.size() == 1) if (a.aa_levels.size() == 1)
{ {
strcpy(a.aa_levels[0].name, "(Not supported on this device)"); strcpy(a.aa_levels[0].name, "(Not supported on this device)");
@ -260,6 +279,7 @@ HRESULT Create(int adapter, HWND wnd, bool _fullscreen, int _resolution, int aa_
return E_FAIL; return E_FAIL;
} }
} }
dev->GetDeviceCaps(&caps); dev->GetDeviceCaps(&caps);
dev->GetRenderTarget(0, &back_buffer); dev->GetRenderTarget(0, &back_buffer);
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND) if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
@ -322,7 +342,7 @@ void Reset()
{ {
if (dev) if (dev)
{ {
ForgetCachedState(); // ForgetCachedState();
// Can't keep a pointer around to the backbuffer surface when resetting. // Can't keep a pointer around to the backbuffer surface when resetting.
if (back_buffer_z) if (back_buffer_z)
@ -339,6 +359,7 @@ void Reset()
dev->GetRenderTarget(0, &back_buffer); dev->GetRenderTarget(0, &back_buffer);
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND) if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
back_buffer_z = NULL; back_buffer_z = NULL;
ApplyCachedState();
} }
} }
@ -401,12 +422,26 @@ void EndFrame()
} }
} }
void ForgetCachedState() void ApplyCachedState()
{ {
for (int sampler = 0; sampler < 8; sampler++)
{
for (int type = 0; type < MaxSamplerTypes; type++)
{
D3D::dev->SetSamplerState(sampler, (D3DSAMPLERSTATETYPE)type, m_SamplerStates[sampler][type]);
}
}
for (int rs = 0; rs < MaxRenderStates; rs++)
{
if (m_RenderStatesSet[rs])
D3D::dev->SetRenderState((D3DRENDERSTATETYPE)rs, m_RenderStates[rs]);
}
// We don't bother restoring these so let's just wipe the state copy
// so no stale state is around.
memset(m_Textures, 0, sizeof(m_Textures)); memset(m_Textures, 0, sizeof(m_Textures));
memset(m_RenderStates, 0xFF, sizeof(m_RenderStates));
memset(m_TextureStageStates, 0xFF, sizeof(m_TextureStageStates)); memset(m_TextureStageStates, 0xFF, sizeof(m_TextureStageStates));
memset(m_SamplerStates, 0xFF, sizeof(m_SamplerStates));
} }
void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture) void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
@ -423,6 +458,7 @@ void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value)
if (m_RenderStates[State] != Value) if (m_RenderStates[State] != Value)
{ {
m_RenderStates[State] = Value; m_RenderStates[State] = Value;
m_RenderStatesSet[State] = true;
D3D::dev->SetRenderState(State, Value); D3D::dev->SetRenderState(State, Value);
} }
} }

View File

@ -28,6 +28,20 @@
namespace D3D namespace D3D
{ {
// From http://developer.amd.com/gpu_assets/Advanced%20DX9%20Capabilities%20for%20ATI%20Radeon%20Cards.pdf
// Magic FourCC's to unlock undocumented D3D9 features:
// Z texture formats
#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')))
#define FOURCC_RAWZ ((D3DFORMAT)(MAKEFOURCC('R','A','W','Z')))
// Depth buffer resolve:
#define FOURCC_RESZ ((D3DFORMAT)(MAKEFOURCC('R','E','S','Z')))
#define RESZ_CODE 0x7fa05000
// Null render target to do Z-only shadow maps: (probably not useful for Dolphin)
#define FOURCC_NULL ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')))
HRESULT Init(); HRESULT Init();
HRESULT Create(int adapter, HWND wnd, bool fullscreen, int resolution, int aa_mode, bool auto_depth); HRESULT Create(int adapter, HWND wnd, bool fullscreen, int resolution, int aa_mode, bool auto_depth);
void Close(); void Close();
@ -41,6 +55,7 @@ bool BeginFrame();
void EndFrame(); void EndFrame();
void SwitchFullscreen(bool fullscreen); void SwitchFullscreen(bool fullscreen);
bool IsFullscreen(); bool IsFullscreen();
bool CanUseINTZ();
int GetBackBufferWidth(); int GetBackBufferWidth();
int GetBackBufferHeight(); int GetBackBufferHeight();
@ -57,7 +72,7 @@ void SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture);
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value); void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value); void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value); void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
void ForgetCachedState(); void ApplyCachedState();
// Utility functions for vendor specific hacks. So far, just the one. // Utility functions for vendor specific hacks. So far, just the one.
void EnableAlphaToCoverage(); void EnableAlphaToCoverage();
@ -85,6 +100,12 @@ struct Adapter
std::vector<Resolution> resolutions; std::vector<Resolution> resolutions;
std::vector<AALevel> aa_levels; std::vector<AALevel> aa_levels;
bool supports_alpha_to_coverage; bool supports_alpha_to_coverage;
// Magic render targets, see the top of this file.
bool supports_intz;
bool supports_rawz;
bool supports_resz;
bool supports_null;
}; };
const Adapter &GetAdapter(int i); const Adapter &GetAdapter(int i);