aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--guilib/TextureDX.cpp2
-rw-r--r--xbmc/RenderSystemDX.cpp118
-rw-r--r--xbmc/RenderSystemDX.h8
-rw-r--r--xbmc/cores/VideoRenderers/WinRenderer.cpp9
4 files changed, 116 insertions, 21 deletions
diff --git a/guilib/TextureDX.cpp b/guilib/TextureDX.cpp
index baa733c787..af8350887c 100644
--- a/guilib/TextureDX.cpp
+++ b/guilib/TextureDX.cpp
@@ -64,7 +64,7 @@ void CDXTexture::CreateTextureObject()
return;
}
- m_texture.Create(m_textureWidth, m_textureHeight, 1, 0, format, D3DPOOL_MANAGED);
+ m_texture.Create(m_textureWidth, m_textureHeight, 1, g_Windowing.DefaultD3DUsage(), format, g_Windowing.DefaultD3DPool());
}
void CDXTexture::DestroyTextureObject()
diff --git a/xbmc/RenderSystemDX.cpp b/xbmc/RenderSystemDX.cpp
index e64f770097..317855ebb2 100644
--- a/xbmc/RenderSystemDX.cpp
+++ b/xbmc/RenderSystemDX.cpp
@@ -31,9 +31,23 @@
#include "D3DResource.h"
#include "GUISettings.h"
#include "AdvancedSettings.h"
+#include "utils/SystemInfo.h"
using namespace std;
+// Dynamic loading of Direct3DCreate9Ex to keep compatibility with 2000/XP.
+typedef HRESULT (WINAPI *LPDIRECT3DCREATE9EX)( UINT SDKVersion, IDirect3D9Ex **ppD3D);
+static LPDIRECT3DCREATE9EX g_Direct3DCreate9Ex;
+static HMODULE g_D3D9ExHandle;
+
+static bool LoadD3D9Ex()
+{
+ g_Direct3DCreate9Ex = (LPDIRECT3DCREATE9EX)GetProcAddress( GetModuleHandle("d3d9.dll"), "Direct3DCreate9Ex" );
+ if(g_Direct3DCreate9Ex == NULL)
+ return false;
+ return true;
+}
+
CRenderSystemDX::CRenderSystemDX() : CRenderSystemBase()
{
m_enumRenderingSystem = RENDERING_SYSTEM_DIRECTX;
@@ -53,6 +67,9 @@ CRenderSystemDX::CRenderSystemDX() : CRenderSystemBase()
m_adapter = D3DADAPTER_DEFAULT;
m_screenHeight = 0;
m_systemFreq = CurrentHostFrequency();
+ m_useD3D9Ex = false;
+ m_defaultD3DUsage = 0;
+ m_defaultD3DPool = D3DPOOL_MANAGED;
ZeroMemory(&m_D3DPP, sizeof(D3DPRESENT_PARAMETERS));
}
@@ -68,12 +85,23 @@ bool CRenderSystemDX::InitRenderSystem()
m_renderCaps = 0;
D3DADAPTER_IDENTIFIER9 AIdentifier;
+ m_useD3D9Ex = (g_sysinfo.IsVistaOrHigher() && LoadD3D9Ex());
m_pD3D = NULL;
- m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
- if(m_pD3D == NULL)
- return false;
-
+ if (m_useD3D9Ex)
+ {
+ HRESULT hr;
+ if (FAILED(hr=g_Direct3DCreate9Ex(D3D_SDK_VERSION, (IDirect3D9Ex**) &m_pD3D)))
+ return false;
+ CLog::Log(LOGDEBUG, "%s - using D3D9Ex", __FUNCTION__);
+ }
+ else
+ {
+ m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
+ if(m_pD3D == NULL)
+ return false;
+ }
+
UpdateMonitor();
if(CreateDevice()==false)
@@ -110,6 +138,18 @@ bool CRenderSystemDX::InitRenderSystem()
}
m_maxTextureSize = min(caps.MaxTextureWidth, caps.MaxTextureHeight);
+ if (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES)
+ {
+ m_defaultD3DUsage = D3DUSAGE_DYNAMIC;
+ m_defaultD3DPool = D3DPOOL_DEFAULT;
+ CLog::Log(LOGDEBUG, "%s - using D3DCAPS2_DYNAMICTEXTURES", __FUNCTION__);
+ }
+ else
+ {
+ m_defaultD3DUsage = 0;
+ m_defaultD3DPool = D3DPOOL_MANAGED;
+ }
+
return true;
}
@@ -173,6 +213,7 @@ void CRenderSystemDX::BuildPresentParameters()
m_D3DPP.MultiSampleType = D3DMULTISAMPLE_NONE;
m_D3DPP.MultiSampleQuality = 0;
+
// Try to create a 32-bit depth, 8-bit stencil
if( FAILED( m_pD3D->CheckDeviceFormat( m_adapter,
D3DDEVTYPE_HAL, m_D3DPP.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
@@ -199,6 +240,17 @@ void CRenderSystemDX::BuildPresentParameters()
else
m_D3DPP.AutoDepthStencilFormat = D3DFMT_D24X8;
}
+
+ if (m_useD3D9Ex)
+ {
+ ZeroMemory( &m_D3DDMEX, sizeof(D3DDISPLAYMODEEX) );
+ m_D3DDMEX.Size = sizeof(D3DDISPLAYMODEEX);
+ m_D3DDMEX.Width = m_D3DPP.BackBufferWidth;
+ m_D3DDMEX.Height = m_D3DPP.BackBufferHeight;
+ m_D3DDMEX.RefreshRate = m_D3DPP.FullScreen_RefreshRateInHz;
+ m_D3DDMEX.Format = m_D3DPP.BackBufferFormat;
+ m_D3DDMEX.ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE;
+ }
}
bool CRenderSystemDX::DestroyRenderSystem()
@@ -245,12 +297,16 @@ void CRenderSystemDX::OnDeviceLost()
void CRenderSystemDX::OnDeviceReset()
{
CSingleLock lock(m_resourceSection);
+
if (m_needNewDevice)
CreateDevice();
else
{
// just need a reset
- m_nDeviceStatus = m_pD3DDevice->Reset(&m_D3DPP);
+ if (m_useD3D9Ex)
+ m_nDeviceStatus = ((IDirect3DDevice9Ex*)m_pD3DDevice)->ResetEx(&m_D3DPP, m_D3DPP.Windowed ? NULL : &m_D3DDMEX);
+ else
+ m_nDeviceStatus = m_pD3DDevice->Reset(&m_D3DPP);
}
if (m_nDeviceStatus == S_OK)
@@ -290,25 +346,55 @@ bool CRenderSystemDX::CreateDevice()
BuildPresentParameters();
- hr = m_pD3D->CreateDevice(m_adapter, devType, m_hFocusWnd,
- D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, &m_pD3DDevice );
- if (FAILED(hr))
+ if (m_useD3D9Ex)
+ {
+ hr = ((IDirect3D9Ex*)m_pD3D)->CreateDeviceEx(m_adapter, devType, m_hFocusWnd,
+ D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, m_D3DPP.Windowed ? NULL : &m_D3DDMEX, (IDirect3DDevice9Ex**)&m_pD3DDevice );
+
+ if (FAILED(hr))
+ {
+ // Try a second time, may fail the first time due to back buffer count,
+ // which will be corrected down to 1 by the runtime
+ hr = ((IDirect3D9Ex*)m_pD3D)->CreateDeviceEx( m_adapter, devType, m_hFocusWnd,
+ D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, m_D3DPP.Windowed ? NULL : &m_D3DDMEX, (IDirect3DDevice9Ex**)&m_pD3DDevice );
+ if( FAILED( hr ) )
+ {
+ hr = ((IDirect3D9Ex*)m_pD3D)->CreateDeviceEx( m_adapter, devType, m_hFocusWnd,
+ D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, m_D3DPP.Windowed ? NULL : &m_D3DDMEX, (IDirect3DDevice9Ex**)&m_pD3DDevice );
+ if( FAILED( hr ) )
+ {
+ hr = ((IDirect3D9Ex*)m_pD3D)->CreateDeviceEx( m_adapter, devType, m_hFocusWnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, m_D3DPP.Windowed ? NULL : &m_D3DDMEX, (IDirect3DDevice9Ex**)&m_pD3DDevice );
+ }
+ if(FAILED( hr ) )
+ return false;
+ }
+ }
+ }
+ else
{
- // Try a second time, may fail the first time due to back buffer count,
- // which will be corrected down to 1 by the runtime
- hr = m_pD3D->CreateDevice( m_adapter, devType, m_hFocusWnd,
+
+ hr = m_pD3D->CreateDevice(m_adapter, devType, m_hFocusWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, &m_pD3DDevice );
- if( FAILED( hr ) )
+
+ if (FAILED(hr))
{
+ // Try a second time, may fail the first time due to back buffer count,
+ // which will be corrected down to 1 by the runtime
hr = m_pD3D->CreateDevice( m_adapter, devType, m_hFocusWnd,
- D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, &m_pD3DDevice );
+ D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, &m_pD3DDevice );
if( FAILED( hr ) )
{
hr = m_pD3D->CreateDevice( m_adapter, devType, m_hFocusWnd,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, &m_pD3DDevice );
+ D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, &m_pD3DDevice );
+ if( FAILED( hr ) )
+ {
+ hr = m_pD3D->CreateDevice( m_adapter, devType, m_hFocusWnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_D3DPP, &m_pD3DDevice );
+ }
+ if(FAILED( hr ) )
+ return false;
}
- if(FAILED( hr ) )
- return false;
}
}
diff --git a/xbmc/RenderSystemDX.h b/xbmc/RenderSystemDX.h
index 3b301fda67..24bd2a5a3d 100644
--- a/xbmc/RenderSystemDX.h
+++ b/xbmc/RenderSystemDX.h
@@ -66,6 +66,10 @@ public:
LPDIRECT3DDEVICE9 Get3DDevice() { return m_pD3DDevice; }
int GetBackbufferCount() const { return m_D3DPP.BackBufferCount; }
+ bool UseD3D9Ex() { return m_useD3D9Ex; }
+ DWORD DefaultD3DUsage() { return m_defaultD3DUsage; }
+ D3DPOOL DefaultD3DPool() { return m_defaultD3DPool; }
+
/*!
\brief Register as a dependent of the DirectX Render System
Resources should call this on construction if they're dependent on the Render System
@@ -107,6 +111,7 @@ protected:
unsigned int m_screenHeight;
D3DPRESENT_PARAMETERS m_D3DPP;
+ D3DDISPLAYMODEEX m_D3DDMEX;
HWND m_hFocusWnd;
HWND m_hDeviceWnd;
unsigned int m_nBackBufferWidth;
@@ -116,6 +121,9 @@ protected:
HRESULT m_nDeviceStatus;
IDirect3DStateBlock9* m_stateBlock;
int64_t m_systemFreq;
+ bool m_useD3D9Ex;
+ DWORD m_defaultD3DUsage;
+ D3DPOOL m_defaultD3DPool;
CCriticalSection m_resourceSection;
std::vector<ID3DResource*> m_resources;
diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp
index 2d938b2519..a0403aaff8 100644
--- a/xbmc/cores/VideoRenderers/WinRenderer.cpp
+++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp
@@ -435,7 +435,7 @@ void CWinRenderer::UpdateVideoFilter()
return;
}
- if(!m_HQKernelTexture.Create(256, 1, 1, 0, D3DFMT_A16B16G16R16F, D3DPOOL_MANAGED))
+ if (!m_HQKernelTexture.Create(256, 1, 1, g_Windowing.DefaultD3DUsage(), D3DFMT_A16B16G16R16F, g_Windowing.DefaultD3DPool()))
{
CLog::Log(LOGERROR, __FUNCTION__": Failed to create kernel texture.");
g_application.m_guiDialogKaiToast.QueueNotification(CGUIDialogKaiToast::Error, "Video Renderering", "Failed to init video scaler, falling back to bilinear scaling.");
@@ -714,9 +714,10 @@ bool CWinRenderer::CreateYV12Texture(int index)
DeleteYV12Texture(index);
SVideoBuffer &buf = m_VideoBuffers[index];
- if (!buf.planes[0].texture.Create(m_sourceWidth , m_sourceHeight , 1, 0, D3DFMT_L8, D3DPOOL_MANAGED)
- || !buf.planes[1].texture.Create(m_sourceWidth / 2, m_sourceHeight / 2, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED)
- || !buf.planes[2].texture.Create(m_sourceWidth / 2, m_sourceHeight / 2, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED))
+
+ if ( !buf.planes[0].texture.Create(m_sourceWidth , m_sourceHeight , 1, g_Windowing.DefaultD3DUsage(), D3DFMT_L8, g_Windowing.DefaultD3DPool())
+ || !buf.planes[1].texture.Create(m_sourceWidth / 2, m_sourceHeight / 2, 1, g_Windowing.DefaultD3DUsage(), D3DFMT_L8, g_Windowing.DefaultD3DPool())
+ || !buf.planes[2].texture.Create(m_sourceWidth / 2, m_sourceHeight / 2, 1, g_Windowing.DefaultD3DUsage(), D3DFMT_L8, g_Windowing.DefaultD3DPool()))
{
CLog::Log(LOGERROR, "Unable to create YV12 video texture %i", index);
return false;