diff options
-rw-r--r-- | guilib/TextureDX.cpp | 2 | ||||
-rw-r--r-- | xbmc/RenderSystemDX.cpp | 118 | ||||
-rw-r--r-- | xbmc/RenderSystemDX.h | 8 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/WinRenderer.cpp | 9 |
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; |