texture2D g_KernelTexture;
float2 g_StepXY;
float2 g_viewPort;
+float2 g_colorRange;
SamplerState RGBSampler : IMMUTABLE
{
getLine(ypos.z, xpos, linetaps) * columntaps.b +
getLine(ypos.w, xpos, linetaps) * columntaps.a;
- return float4(rgb, 1.0);
+ return float4(g_colorRange.x + g_colorRange.y * saturate(rgb), 1.0);
}
technique11 SCALER_T
texture2D g_KernelTexture;
float2 g_StepXY;
float2 g_viewPort;
+float2 g_colorRange;
SamplerState RGBSampler : IMMUTABLE
{
getLine(ypos2.y, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.b +
getLine(ypos2.z, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.b;
- return float4(rgb, 1.0f);
+ return float4(g_colorRange.x + g_colorRange.y * saturate(rgb), 1.0);
}
technique11 SCALER_T
texture2D g_KernelTexture;
float4 g_StepXY;
float2 g_viewPort;
+float2 g_colorRange;
SamplerState RGBSampler : IMMUTABLE
{
float xystart = (-1.0 - f.y) * g_StepXY.w + TextureUV.y;
float4 ypos = xystart + g_StepXY.w * float4(0.0, 1.0, 2.0, 3.0);
- return float4(getRow(TextureUV.x, ypos, columntaps), 1.0f);
+ return float4(g_colorRange.x + g_colorRange.y * saturate(getRow(TextureUV.x, ypos, columntaps)), 1.0);
}
technique11 SCALER_T
texture2D g_KernelTexture;
float4 g_StepXY;
float2 g_viewPort;
+float2 g_colorRange;
SamplerState RGBSampler : IMMUTABLE
{
float3 ypos1 = ystart + g_StepXY.w * float3(0.0, 1.0, 2.0);
float3 ypos2 = ystart + g_StepXY.w * float3(3.0, 4.0, 5.0);
- return float4(getRow(TextureUV.x, ypos1, ypos2, columntaps1, columntaps2), 1.0);
+ return float4(g_colorRange.x + g_colorRange.y * saturate(getRow(TextureUV.x, ypos1, ypos2, columntaps1, columntaps2)), 1.0);
}
technique11 SCALER_T
float4 PS(PS_INPUT input) : SV_TARGET
{
- return texVideo.Sample(DynamicSampler, input.tex);
+ return adjustColorRange(texVideo.Sample(DynamicSampler, input.tex));
}
current.a = input.color.a;
current.rgb += specular.rgb - 0.5;
- return current;
+ return adjustColorRange(current);
}
return false;
}
- D3D11_VIDEO_PROCESSOR_COLOR_SPACE cs;
- cs.Usage = 0; // 0 - Playback, 1 - Processing
- cs.RGB_Range = 0; // 0 - Full (0-255), 1 - Limited (16-235)
- cs.YCbCr_Matrix = m_flags & CONF_FLAGS_YUVCOEF_BT709 ? 1 : 0; // 0 - BT.601, 1 - BT.709
- cs.YCbCr_xvYCC = 1; // 0 - Conventional YCbCr, 1 - xvYCC
- cs.Nominal_Range = m_flags & CONF_FLAGS_YUV_FULLRANGE ? 2 : 1; // 2 - Full luminance range [0-255], 1 - Studio luminance range [16-235], 0 - driver defaults
+ D3D11_VIDEO_PROCESSOR_COLOR_SPACE cs
+ {
+ 0, // 0 - Playback, 1 - Processing
+ 0, // 0 - Full (0-255), 1 - Limited (16-235)
+ m_flags & CONF_FLAGS_YUVCOEF_BT709 ? 1 : 0, // 0 - BT.601, 1 - BT.709
+ m_flags & CONF_FLAGS_YUV_FULLRANGE ? 1 : 0, // 0 - Conventional YCbCr, 1 - xvYCC
+ 0, // 2 - Full luminance range [0-255], 1 - Studio luminance range [16-235], 0 - driver defaults
+ };
+ if (m_vcaps.DeviceCaps & D3D11_VIDEO_PROCESSOR_DEVICE_CAPS_NOMINAL_RANGE)
+ cs.Nominal_Range = m_flags & CONF_FLAGS_YUV_FULLRANGE ? 2 : 1;
m_pVideoContext->VideoProcessorSetStreamColorSpace(m_pVideoProcessor, DEFAULT_STREAM_INDEX, &cs);
// Output background color (black)
// Output rect
m_pVideoContext->VideoProcessorSetOutputTargetRect(m_pVideoProcessor, TRUE, &dstRECT);
// Output color space
+ // don't apply any color range conversion, this will be fixed at later stage.
D3D11_VIDEO_PROCESSOR_COLOR_SPACE colorSpace = {};
colorSpace.Usage = 0; // 0 - playback, 1 - video processing
colorSpace.RGB_Range = 0; // 0 - 0-255, 1 - 16-235
colorSpace.YCbCr_Matrix = 1; // 0 - BT.601, 1 = BT.709
colorSpace.YCbCr_xvYCC = 1; // 0 - Conventional YCbCr, 1 - xvYCC
- colorSpace.Nominal_Range = g_Windowing.UseLimitedColor() ? 1 : 2; // 2 - 0-255, 1 = 16-235, 0 - undefined
+ colorSpace.Nominal_Range = 2; // 2 - 0-255, 1 = 16-235, 0 - undefined
m_pVideoContext->VideoProcessorSetOutputColorSpace(m_pVideoProcessor, &colorSpace);
CYUV2RGBMatrix::CYUV2RGBMatrix()
{
- m_NeedRecalc = true;
- m_blacklevel = 0.0f;
- m_contrast = 0.0f;
- m_flags = 0;
- m_format = RENDER_FMT_NONE;
+ m_NeedRecalc = true;
+ m_blacklevel = 0.0f;
+ m_contrast = 0.0f;
+ m_flags = 0;
+ m_limitedRange = false;
+ m_format = RENDER_FMT_NONE;
}
void CYUV2RGBMatrix::SetParameters(float contrast, float blacklevel, unsigned int flags, ERenderFormat format)
m_NeedRecalc = true;
m_format = format;
}
+ if (m_limitedRange != g_Windowing.UseLimitedColor())
+ {
+ m_NeedRecalc = true;
+ m_limitedRange = g_Windowing.UseLimitedColor();
+ }
}
XMFLOAT4X4* CYUV2RGBMatrix::Matrix()
unsigned int sourceWidth, unsigned int sourceHeight,
unsigned int destWidth, unsigned int destHeight,
CRect sourceRect,
- CRect destRect)
+ CRect destRect,
+ bool useLimitedRange)
{
PrepareParameters(sourceWidth, sourceHeight, sourceRect, destRect);
float texSteps[] = { 1.0f/(float)sourceWidth, 1.0f/(float)sourceHeight};
- SetShaderParameters(sourceTexture, &texSteps[0], ARRAY_SIZE(texSteps));
+ SetShaderParameters(sourceTexture, &texSteps[0], ARRAY_SIZE(texSteps), useLimitedRange);
Execute(nullptr, 4);
}
}
}
-void CConvolutionShader1Pass::SetShaderParameters(CD3DTexture &sourceTexture, float* texSteps, int texStepsCount)
+void CConvolutionShader1Pass::SetShaderParameters(CD3DTexture &sourceTexture, float* texSteps, int texStepsCount, bool useLimitedRange)
{
m_effect.SetTechnique( "SCALER_T" );
m_effect.SetTexture( "g_Texture", sourceTexture ) ;
m_effect.SetTexture( "g_KernelTexture", m_HQKernelTexture );
m_effect.SetFloatArray("g_StepXY", texSteps, texStepsCount);
-
UINT numVP = 1;
D3D11_VIEWPORT viewPort = {};
g_Windowing.Get3D11Context()->RSGetViewports(&numVP, &viewPort);
m_effect.SetFloatArray("g_viewPort", &viewPort.Width, 2);
+ float colorRange[2] =
+ {
+ (useLimitedRange ? 16.f : 0.f) / 255.f,
+ (useLimitedRange ? (235.f - 16.f) : 255.f) / 255.f,
+ };
+ m_effect.SetFloatArray("g_colorRange", colorRange, _countof(colorRange));
}
//==================================================================================
unsigned int sourceWidth, unsigned int sourceHeight,
unsigned int destWidth, unsigned int destHeight,
CRect sourceRect,
- CRect destRect)
+ CRect destRect,
+ bool useLimitedRange)
{
if(m_destWidth != destWidth || m_sourceHeight != sourceHeight)
CreateIntermediateRenderTarget(destWidth, sourceHeight);
1.0f / static_cast<float>(destWidth),
1.0f / static_cast<float>(sourceHeight)
};
- SetShaderParameters(sourceTexture, texSteps, 4);
+ SetShaderParameters(sourceTexture, texSteps, 4, useLimitedRange);
Execute(nullptr, 4);
}
}
-void CConvolutionShaderSeparable::SetShaderParameters(CD3DTexture &sourceTexture, float* texSteps, int texStepsCount)
+void CConvolutionShaderSeparable::SetShaderParameters(CD3DTexture &sourceTexture, float* texSteps, int texStepsCount, bool useLimitedRange)
{
m_effect.SetTechnique( "SCALER_T" );
m_effect.SetTexture( "g_Texture", sourceTexture );
m_effect.SetTexture( "g_KernelTexture", m_HQKernelTexture );
m_effect.SetFloatArray("g_StepXY", texSteps, texStepsCount);
+ float colorRange[2] =
+ {
+ (useLimitedRange ? 16.f : 0.f) / 255.f,
+ (useLimitedRange ? (235.f - 16.f) : 255.f) / 255.f,
+ };
+ m_effect.SetFloatArray("g_colorRange", colorRange, _countof(colorRange));
}
void CConvolutionShaderSeparable::SetStepParams(UINT iPass)
float m_contrast;
float m_blacklevel;
unsigned int m_flags;
+ bool m_limitedRange;
ERenderFormat m_format;
XMFLOAT4X4 m_mat;
};
unsigned int sourceWidth, unsigned int sourceHeight,
unsigned int destWidth, unsigned int destHeight,
CRect sourceRect,
- CRect destRect) = 0;
+ CRect destRect,
+ bool useLimitedRange) = 0;
CConvolutionShader() : CWinShader() {}
virtual ~CConvolutionShader();
unsigned int sourceWidth, unsigned int sourceHeight,
unsigned int destWidth, unsigned int destHeight,
CRect sourceRect,
- CRect destRect);
+ CRect destRect,
+ bool useLimitedRange);
CConvolutionShader1Pass() : CConvolutionShader(), m_sourceWidth(0), m_sourceHeight(0) {}
protected:
virtual void PrepareParameters(unsigned int sourceWidth, unsigned int sourceHeight,
CRect sourceRect,
CRect destRect);
- virtual void SetShaderParameters(CD3DTexture &sourceTexture, float* texSteps, int texStepsCount);
+ virtual void SetShaderParameters(CD3DTexture &sourceTexture, float* texSteps, int texStepsCount, bool useLimitedRange);
private:
unsigned int sourceWidth, unsigned int sourceHeight,
unsigned int destWidth, unsigned int destHeight,
CRect sourceRect,
- CRect destRect);
+ CRect destRect,
+ bool useLimitedRange);
virtual ~CConvolutionShaderSeparable();
protected:
unsigned int destWidth, unsigned int destHeight,
CRect sourceRect,
CRect destRect);
- virtual void SetShaderParameters(CD3DTexture &sourceTexture, float* texSteps, int texStepsCount);
+ virtual void SetShaderParameters(CD3DTexture &sourceTexture, float* texSteps, int texStepsCount, bool useLimitedRange);
virtual void SetStepParams(UINT stepIndex);
private:
m_destWidth = 0;
m_destHeight = 0;
m_bConfigured = false;
- m_clearColour = 0;
m_format = RENDER_FMT_NONE;
m_processor = nullptr;
m_neededBuffers = 0;
void CWinRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
{
if (clear)
- g_graphicsContext.Clear(m_clearColour);
-
- if (alpha < 255)
- g_Windowing.SetAlphaBlendEnable(true);
- else
- g_Windowing.SetAlphaBlendEnable(false);
+ g_graphicsContext.Clear(g_Windowing.UseLimitedColor() ? 0x101010 : 0);
+ g_Windowing.SetAlphaBlendEnable(alpha < 255);
if (!m_bConfigured)
return;
ManageTextures();
CSingleLock lock(g_graphicsContext);
-
ManageDisplay();
-
Render(flags);
}
if ( m_resolution == RES_WINDOW )
m_resolution = RES_DESKTOP;
- // setup the background colour
- m_clearColour = (g_advancedSettings.m_videoBlackBarColour & 0xff) * 0x010101;
-
m_formats.clear();
m_formats.push_back(RENDER_FMT_YUV420P);
CRect destRect = m_bUseHQScaler ? m_sourceRect : g_graphicsContext.StereoCorrection(m_destRect);
// select target view
ID3D11RenderTargetView* pRTView = m_bUseHQScaler ? m_IntermediateTarget.GetRenderTarget() : oldRTView;
- // set destination render target
- pContext->OMSetRenderTargets(1, &pRTView, nullptr);
+ // change destination for HQ scallers
+ if (m_bUseHQScaler)
+ pContext->OMSetRenderTargets(1, &pRTView, nullptr);
// get rendertarget's dimension
if (pRTView)
{
{
D3D11_TEXTURE2D_DESC desc;
pTexture->GetDesc(&desc);
- viewPort = CD3D11_VIEWPORT(0.0f, 0.0f, desc.Width, desc.Height);
+ viewPort = CD3D11_VIEWPORT(0.0f, 0.0f, static_cast<float>(desc.Width), static_cast<float>(desc.Height));
}
SAFE_RELEASE(pResource);
SAFE_RELEASE(pTexture);
// Restore our view port.
g_Windowing.RestoreViewPort();
// Restore the render target and depth view.
- pContext->OMSetRenderTargets(1, &oldRTView, oldDSView);
+ if (m_bUseHQScaler)
+ pContext->OMSetRenderTargets(1, &oldRTView, oldDSView);
SAFE_RELEASE(oldRTView);
SAFE_RELEASE(oldDSView);
}
void CWinRenderer::Stage2()
{
- m_scalerShader->Render(m_IntermediateTarget, m_sourceWidth, m_sourceHeight, m_destWidth, m_destHeight, m_sourceRect, g_graphicsContext.StereoCorrection(m_destRect));
+ m_scalerShader->Render(m_IntermediateTarget, m_sourceWidth, m_sourceHeight, m_destWidth, m_destHeight
+ , m_sourceRect, g_graphicsContext.StereoCorrection(m_destRect)
+ , (m_renderMethod == RENDER_DXVA && g_Windowing.UseLimitedColor()));
}
void CWinRenderer::RenderProcessor(DWORD flags)
if (!image->pic)
return;
- ID3D11Resource* target;
- if ( m_bUseHQScaler
- || g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN
- || g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA
- || g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE
- || true /* workaround for some GPUs */)
- {
- target = m_IntermediateTarget.Get();
- target->AddRef();
- }
- else // dead code.
- {
- ID3D11RenderTargetView* rtv = nullptr;
- g_Windowing.Get3D11Context()->OMGetRenderTargets(1, &rtv, nullptr);
- if (rtv)
- {
- rtv->GetResource(&target);
- rtv->Release();
- }
- }
-
int past = 0;
int future = 0;
DXVABuffer **buffers = (DXVABuffer**)m_VideoBuffers;
break;
}
- m_processor->Render(m_sourceRect, destRect, target, views, flags, image->frameIdx);
+ m_processor->Render(m_sourceRect, destRect, m_IntermediateTarget.Get(), views, flags, image->frameIdx);
if (m_bUseHQScaler)
{
Stage2();
}
- // uncomment when workaround removed
- else /*if ( g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN
- || g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA
- || g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE)*/
+ else
{
// texels
CRect tu = { destRect.x1 / m_destWidth, destRect.y1 / m_destHeight, destRect.x2 / m_destWidth, destRect.y2 / m_destHeight };
- CD3DTexture::DrawQuad(m_destRect, 0, &m_IntermediateTarget, &tu, SHADER_METHOD_RENDER_TEXTURE_NOBLEND);
+ CD3DTexture::DrawQuad(m_destRect, 0xFFFFFFFF, &m_IntermediateTarget, &tu, SHADER_METHOD_RENDER_TEXTURE_BLEND);
}
- SAFE_RELEASE(target);
}
bool CWinRenderer::RenderCapture(CRenderCapture* capture)
// PS rendering
bool m_bUseHQScaler;
CD3DTexture m_IntermediateTarget;
-
CYUV2RGBShader* m_colorShader;
CConvolutionShader* m_scalerShader;
-
ESCALINGMETHOD m_scalingMethod;
ESCALINGMETHOD m_scalingMethodGui;
-
bool m_bFilterInitialized;
int m_iRequestedMethod;
-
- // clear colour for "black" bars
- DWORD m_clearColour;
unsigned int m_extended_format;
-
// Width and height of the render target
// the separable HQ scalers need this info, but could the m_destRect be used instead?
unsigned int m_destWidth;
unsigned int m_destHeight;
-
int m_neededBuffers;
unsigned int m_frameIdx;
};