Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[windows] Enable shader based HQ scalers for DXVA renderer #838

Merged
merged 1 commit into from
Aug 31, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 43 additions & 17 deletions xbmc/cores/VideoRenderers/WinRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,8 @@ bool CWinRenderer::CreateIntermediateRenderTarget()
D3DFORMAT format = D3DFMT_X8R8G8B8;
DWORD usage = D3DUSAGE_RENDERTARGET;

if (g_Windowing.IsTextureFormatOk(D3DFMT_A2R10G10B10, usage)) format = D3DFMT_A2R10G10B10;
if (m_renderMethod == RENDER_DXVA) format = D3DFMT_X8R8G8B8;
else if (g_Windowing.IsTextureFormatOk(D3DFMT_A2R10G10B10, usage)) format = D3DFMT_A2R10G10B10;
else if (g_Windowing.IsTextureFormatOk(D3DFMT_A2B10G10R10, usage)) format = D3DFMT_A2B10G10R10;
else if (g_Windowing.IsTextureFormatOk(D3DFMT_A8R8G8B8, usage)) format = D3DFMT_A8R8G8B8;
else if (g_Windowing.IsTextureFormatOk(D3DFMT_A8B8G8R8, usage)) format = D3DFMT_A8B8G8R8;
Expand Down Expand Up @@ -525,7 +526,12 @@ void CWinRenderer::SelectPSVideoFilter()
bool scaleUp = (int)m_sourceHeight < g_graphicsContext.GetHeight() && (int)m_sourceWidth < g_graphicsContext.GetWidth();
bool scaleFps = m_fps < (g_advancedSettings.m_videoAutoScaleMaxFps + 0.01f);

if (scaleSD && scaleUp && scaleFps && Supports(VS_SCALINGMETHOD_LANCZOS3_FAST))
if (m_renderMethod == RENDER_DXVA)
{
m_scalingMethod = VS_SCALINGMETHOD_DXVA_HARDWARE;
m_bUseHQScaler = false;
}
else if (scaleSD && scaleUp && scaleFps && Supports(VS_SCALINGMETHOD_LANCZOS3_FAST))
{
m_scalingMethod = VS_SCALINGMETHOD_LANCZOS3_FAST;
m_bUseHQScaler = true;
Expand Down Expand Up @@ -573,6 +579,10 @@ void CWinRenderer::UpdatePSVideoFilter()

SAFE_DELETE(m_colorShader);

// When using DXVA, we are already setup at this point, color shader is not needed
if (m_renderMethod == RENDER_DXVA)
return;

if (m_bUseHQScaler)
{
m_colorShader = new CYUV2RGBShader();
Expand Down Expand Up @@ -618,14 +628,11 @@ void CWinRenderer::UpdateVideoFilter()
break;

case RENDER_PS:
case RENDER_DXVA:
SelectPSVideoFilter();
UpdatePSVideoFilter();
break;

case RENDER_DXVA:
// Everything already setup, nothing to do.
break;

default:
return;
}
Expand All @@ -635,6 +642,9 @@ void CWinRenderer::Render(DWORD flags)
{
if (m_renderMethod == RENDER_DXVA)
{
UpdateVideoFilter();
if (m_bUseHQScaler)
g_Windowing.FlushGPU();
CWinRenderer::RenderProcessor(flags);
return;
}
Expand Down Expand Up @@ -918,19 +928,38 @@ void CWinRenderer::RenderProcessor(DWORD flags)
{
CSingleLock lock(g_graphicsContext);
HRESULT hr;
CRect destRect;

if (m_bUseHQScaler)
{
destRect.y1 = 0.0f;
destRect.y2 = m_sourceHeight;
destRect.x1 = 0.0f;
destRect.x2 = m_sourceWidth;
}
else
destRect = m_destRect;

DXVABuffer *image = (DXVABuffer*)m_VideoBuffers[m_iYV12RenderBuffer];

IDirect3DSurface9* target;
if(FAILED(hr = g_Windowing.Get3DDevice()->GetRenderTarget(0, &target)))
if (m_bUseHQScaler)
m_IntermediateTarget.GetSurfaceLevel(0, &target);
else
{
CLog::Log(LOGERROR, "CWinRenderer::RenderSurface - failed to get render target. %s", CRenderSystemDX::GetErrorDescription(hr).c_str());
return;
if(FAILED(hr = g_Windowing.Get3DDevice()->GetRenderTarget(0, &target)))
{
CLog::Log(LOGERROR, "CWinRenderer::RenderSurface - failed to get render target. %s", CRenderSystemDX::GetErrorDescription(hr).c_str());
return;
}
}

m_processor.Render(m_sourceRect, g_graphicsContext.StereoCorrection(m_destRect), target, image->id, flags);
m_processor.Render(m_sourceRect, g_graphicsContext.StereoCorrection(destRect), target, image->id, flags);

target->Release();

if (m_bUseHQScaler)
Stage2();
}

bool CWinRenderer::RenderCapture(CRenderCapture* capture)
Expand Down Expand Up @@ -1068,17 +1097,14 @@ bool CWinRenderer::Supports(ERENDERFEATURE feature)

bool CWinRenderer::Supports(ESCALINGMETHOD method)
{
if (m_renderMethod == RENDER_DXVA)
if (m_renderMethod == RENDER_PS || m_renderMethod == RENDER_DXVA)
{
if(method == VS_SCALINGMETHOD_DXVA_HARDWARE)
if(m_renderMethod == RENDER_DXVA && method == VS_SCALINGMETHOD_DXVA_HARDWARE)
return true;
return false;
}
else if(m_renderMethod == RENDER_PS)
{

if(m_deviceCaps.PixelShaderVersion >= D3DPS_VERSION(2, 0)
&& ( method == VS_SCALINGMETHOD_AUTO
|| method == VS_SCALINGMETHOD_LINEAR))
|| (method == VS_SCALINGMETHOD_LINEAR && m_renderMethod == RENDER_PS) ))
return true;

if(m_deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0))
Expand Down
12 changes: 12 additions & 0 deletions xbmc/rendering/dx/RenderSystemDX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1043,5 +1043,17 @@ bool CRenderSystemDX::SupportsStereo(RENDER_STEREO_MODE mode) const
}
}

void CRenderSystemDX::FlushGPU()
{
IDirect3DQuery9* pEvent = NULL;

m_pD3DDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pEvent);
if (pEvent != NULL)
{
pEvent->Issue(D3DISSUE_END);
while (S_FALSE == pEvent->GetData(NULL, 0, D3DGETDATA_FLUSH))
Sleep(1);
}
}

#endif
2 changes: 2 additions & 0 deletions xbmc/rendering/dx/RenderSystemDX.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class CRenderSystemDX : public CRenderSystemBase

virtual void Project(float &x, float &y, float &z);

void FlushGPU();

LPDIRECT3DDEVICE9 Get3DDevice() { return m_pD3DDevice; }
int GetBackbufferCount() const { return m_D3DPP.BackBufferCount; }

Expand Down