summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorhrydgard <hrydgard@gmail.com>2009-09-16 20:12:14 +0000
committerhrydgard <hrydgard@gmail.com>2009-09-16 20:12:14 +0000
commit2eece4c2f47454b9b545d93fc7f5f718bfd2706a (patch)
treeccb0f16362556f74159aaf3087a15e349a1165af /Source
parenta8270d50eebe9ac119314e5644d94c908efba4f4 (diff)
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
Diffstat (limited to 'Source')
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp54
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h23
2 files changed, 67 insertions, 10 deletions
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp
index 7b09a588f8..d09ba76d2c 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp
@@ -49,11 +49,12 @@ static int cur_adapter;
// Value caches for state filtering
const int MaxTextureStages = 9;
-const int MaxRenderStates = 210;
-const DWORD MaxTextureTypes = 33;
-const DWORD MaxSamplerSize = 13;
-const DWORD MaxSamplerTypes = 15;
-static DWORD m_RenderStates[MaxRenderStates+46];
+const int MaxRenderStates = 210 + 46;
+const int MaxTextureTypes = 33;
+const int MaxSamplerSize = 13;
+const int MaxSamplerTypes = 15;
+static bool m_RenderStatesSet[MaxRenderStates];
+static DWORD m_RenderStates[MaxRenderStates];
static DWORD m_TextureStageStates[MaxTextureStages][MaxTextureTypes];
static DWORD m_SamplerStates[MaxSamplerSize][MaxSamplerTypes];
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)
{
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;
}
}
+
dev->GetDeviceCaps(&caps);
dev->GetRenderTarget(0, &back_buffer);
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
@@ -322,7 +342,7 @@ void Reset()
{
if (dev)
{
- ForgetCachedState();
+ // ForgetCachedState();
// Can't keep a pointer around to the backbuffer surface when resetting.
if (back_buffer_z)
@@ -339,6 +359,7 @@ void Reset()
dev->GetRenderTarget(0, &back_buffer);
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
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_RenderStates, 0xFF, sizeof(m_RenderStates));
memset(m_TextureStageStates, 0xFF, sizeof(m_TextureStageStates));
- memset(m_SamplerStates, 0xFF, sizeof(m_SamplerStates));
}
void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
@@ -423,6 +458,7 @@ void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value)
if (m_RenderStates[State] != Value)
{
m_RenderStates[State] = Value;
+ m_RenderStatesSet[State] = true;
D3D::dev->SetRenderState(State, Value);
}
}
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h
index c92168a9cf..f7c4b80bba 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h
@@ -28,6 +28,20 @@
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 Create(int adapter, HWND wnd, bool fullscreen, int resolution, int aa_mode, bool auto_depth);
void Close();
@@ -41,6 +55,7 @@ bool BeginFrame();
void EndFrame();
void SwitchFullscreen(bool fullscreen);
bool IsFullscreen();
+bool CanUseINTZ();
int GetBackBufferWidth();
int GetBackBufferHeight();
@@ -57,7 +72,7 @@ void SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture);
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE 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.
void EnableAlphaToCoverage();
@@ -85,6 +100,12 @@ struct Adapter
std::vector<Resolution> resolutions;
std::vector<AALevel> aa_levels;
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);