public override IFilter CreateFilter(IFilter sourceFilter) { Cleanup(); if (sourceFilter.OutputSize == Renderer.TargetSize) { return(sourceFilter); } try { m_DxvaHd = Renderer.CreateDxvaHd((Size)sourceFilter.OutputSize, TextureFormat.Unorm8, Renderer.TargetSize, TextureFormat.Unorm8, Quality); } catch (DxvaHdException) { // DXVA HD not available; fallback Renderer.FallbackOccurred = true; return(sourceFilter); } var input = YuvMode ? sourceFilter.ConvertToYuv() : sourceFilter; if (sourceFilter.OutputFormat != TextureFormat.Unorm8) { // Convert input to Unorm8 (and unforunately murdering quality at the same time) var copy = CompileShader("Copy.hlsl").Configure(linearSampling: false, format: TextureFormat.Unorm8); input = new ShaderFilter(copy, input); } var result = new DxvaHdResizeFilter(m_DxvaHd, input); return(YuvMode ? result.ConvertToRgb() : result); }
public override IFilter CreateFilter(IFilter input) { DisposeHelper.Dispose(ref m_Buffer1); DisposeHelper.Dispose(ref m_Buffer2); if (!Renderer.IsOpenClAvail || Renderer.RenderQuality.PerformanceMode()) { Renderer.FallbackOccurred = true; // Warn user via player stats OSD return(input); // OpenCL is not available, or UNORM8 textures used (not supported); fallback } Func <TextureSize, TextureSize> transformWidth = s => new TextureSize(2 * s.Width, s.Height); Func <TextureSize, TextureSize> transformHeight = s => new TextureSize(s.Width, 2 * s.Height); var kernel = CompileKernel(); var shaderH = kernel.Configure(transform: transformWidth); var shaderV = kernel.Configure(transform: transformHeight); var combine = CompileShader("Combine.hlsl"); var neuronCount1 = s_NeuronCount[(int)Neurons1]; var neuronCount2 = s_NeuronCount[(int)Neurons2]; var weights1 = s_Weights[(int)Neurons1]; m_Buffer1 = Renderer.CreateClBuffer(weights1); var differentWeights = neuronCount1 != neuronCount2; if (differentWeights) { var weights2 = s_Weights[(int)Neurons2]; m_Buffer2 = Renderer.CreateClBuffer(weights2); } var sourceSize = input.OutputSize; if (!IsUpscalingFrom(sourceSize)) { return(input); } var yuv = input.ConvertToYuv(); var chroma = new ResizeFilter(yuv, new TextureSize(sourceSize.Width * 2, sourceSize.Height * 2), TextureChannels.ChromaOnly, new Vector2(-0.25f, -0.25f), Renderer.ChromaUpscaler, Renderer.ChromaDownscaler); var localWorkSizes = new[] { 8, 8 }; var nnedi3H = new NNedi3HKernelFilter(shaderH, m_Buffer1, neuronCount1, new TextureSize(yuv.OutputSize.Width, yuv.OutputSize.Height), localWorkSizes, yuv); var nnedi3V = new NNedi3VKernelFilter(shaderV, m_Buffer2, neuronCount2, differentWeights, new TextureSize(nnedi3H.OutputSize.Width, nnedi3H.OutputSize.Height), localWorkSizes, nnedi3H); var result = new ShaderFilter(combine, nnedi3V, chroma); return(new ResizeFilter(result.ConvertToRgb(), result.OutputSize, new Vector2(0.5f, 0.5f), Renderer.LumaUpscaler, Renderer.LumaDownscaler)); }
public override IFilter CreateFilter(IFilter input) { if (Renderer.InputFormat.IsRgb()) { return(input); } int bits = Renderer.InputFormat.GetBitDepth(); if (bits > maxbitdepth) { return(input); } float[] consts = { (1 << bits) - 1, power }; var Deband = CompileShader("Deband.hlsl", macroDefinitions: !grain ? "SkipDithering=1" : "") .Configure(arguments: consts, perTextureLinearSampling: new[] { true, false }); /*var Subtract = CompileShader("Subtract.hlsl") * .Configure(perTextureLinearSampling: new[] { false, true }, format: TextureFormat.Float16); * var SubtractLimited = CompileShader("SubtractLimited.hlsl") * .Configure(perTextureLinearSampling: new[] { false, true }, arguments: Consts);*/ IFilter yuv = input.ConvertToYuv(); var inputsize = yuv.OutputSize; var deband = yuv; double factor = 2.0;// 0.5 * Math.Sqrt(5) + 0.5; int max = (int)Math.Floor(Math.Log(Math.Min(inputsize.Width, inputsize.Height) / 3.0, factor)); for (int i = max; i >= 0; i--) { double scale = Math.Pow(factor, i); var size = new TextureSize((int)Math.Round(inputsize.Width / scale), (int)Math.Round(inputsize.Height / scale)); if (size.Width == 0 || size.Height == 0) { continue; } if (i == 0) { size = inputsize; } deband = new ShaderFilter(Deband.Configure(transform: s => size), yuv, deband); } return(deband.ConvertToRgb()); }
public override IFilter CreateFilter(IFilter input) { if (!Renderer.IsDx11Avail) { Renderer.FallbackOccurred = true; // Warn user via player stats OSD return(input); // DX11 is not available; fallback } Func <TextureSize, TextureSize> Transformation = s => new TextureSize(2 * s.Height, s.Width); var NNEDI3 = LoadShader11(string.Format("NNEDI3_{0}_{1}.cso", s_NeuronCount[(int)Neurons], s_CodePath[(int)CodePath])); var Interleave = CompileShader("Interleave.hlsl").Configure(transform: Transformation); var Combine = CompileShader("Combine.hlsl").Configure(transform: Transformation); var sourceSize = input.OutputSize; if (!IsUpscalingFrom(sourceSize)) { return(input); } var yuv = input.ConvertToYuv(); var chroma = new ResizeFilter(yuv, new TextureSize(sourceSize.Width * 2, sourceSize.Height * 2), TextureChannels.ChromaOnly, new Vector2(-0.25f, -0.25f), Renderer.ChromaUpscaler, Renderer.ChromaDownscaler); IFilter resultY, result; var pass1 = NNedi3Helpers.CreateFilter(NNEDI3, yuv, Neurons); resultY = new ShaderFilter(Interleave, yuv, pass1); var pass2 = NNedi3Helpers.CreateFilter(NNEDI3, resultY, Neurons); result = new ShaderFilter(Combine, resultY, pass2, chroma); return(new ResizeFilter(result.ConvertToRgb(), result.OutputSize, new Vector2(0.5f, 0.5f), Renderer.LumaUpscaler, Renderer.LumaDownscaler)); }
public override IFilter CreateFilter(IFilter input) { Cleanup(); if (!Renderer.IsDx11Avail) { Renderer.FallbackOccurred = true; // Warn user via player stats OSD return(input); // DX11 is not available; fallback } Func <TextureSize, TextureSize> transform = s => new TextureSize(2 * s.Height, s.Width); var shaderPass1 = LoadShader11(GetShaderFileName(Neurons1)); var shaderPass2 = LoadShader11(GetShaderFileName(Neurons2)); var interleave = CompileShader("Interleave.hlsl").Configure(transform: transform); var combine = CompileShader("Combine.hlsl").Configure(transform: transform); var sourceSize = input.OutputSize; if (!IsUpscalingFrom(sourceSize)) { return(input); } var yuv = input.ConvertToYuv(); var chroma = new ResizeFilter(yuv, new TextureSize(sourceSize.Width * 2, sourceSize.Height * 2), TextureChannels.ChromaOnly, new Vector2(-0.25f, -0.25f), Renderer.ChromaUpscaler, Renderer.ChromaDownscaler); m_Filter1 = NNedi3Helpers.CreateFilter(shaderPass1, yuv, Neurons1, Structured); var resultY = new ShaderFilter(interleave, yuv, m_Filter1); m_Filter2 = NNedi3Helpers.CreateFilter(shaderPass2, resultY, Neurons2, Structured); var result = new ShaderFilter(combine, resultY, m_Filter2, chroma); return(new ResizeFilter(result.ConvertToRgb(), result.OutputSize, new Vector2(0.5f, 0.5f), Renderer.LumaUpscaler, Renderer.LumaDownscaler)); }
public override IFilter CreateFilter(IFilter input) { if (Renderer.InputFormat.IsRgb()) { return(input); } IFilter hiRes; var chromaSize = (TextureSize)Renderer.ChromaSize; var targetSize = input.OutputSize; // Original values var yInput = new YSourceFilter(); var uInput = new USourceFilter(); var vInput = new VSourceFilter(); float[] yuvConsts = Renderer.Colorimetric.GetYuvConsts(); int bitdepth = Renderer.InputFormat.GetBitDepth(); bool limited = Renderer.Colorimetric.IsLimitedRange(); // Skip if downscaling if (targetSize.Width <= chromaSize.Width && targetSize.Height <= chromaSize.Height) { return(input); } Vector2 offset = Renderer.ChromaOffset; Vector2 adjointOffset = -offset * targetSize / chromaSize; string superResMacros = ""; if (IsIntegral(Strength)) { superResMacros += String.Format("strength = {0};", Strength); } if (IsIntegral(Softness)) { superResMacros += String.Format("softness = {0};", Softness); } string diffMacros = string.Format("LimitedRange = {0}; range = {1}", limited ? 1 : 0, (1 << bitdepth) - 1); var CopyLuma = CompileShader("CopyLuma.hlsl"); var CopyChroma = CompileShader("CopyChroma.hlsl"); var MergeChroma = CompileShader("MergeChroma.hlsl").Configure(format: TextureFormat.Float16); var Diff = CompileShader("Diff.hlsl", macroDefinitions: diffMacros) .Configure(arguments: yuvConsts, format: TextureFormat.Float16); var SuperRes = CompileShader("SuperResEx.hlsl", macroDefinitions: superResMacros) .Configure( arguments: new[] { Strength, Softness, yuvConsts[0], yuvConsts[1], offset.X, offset.Y } ); var CrossBilateral = CompileShader("CrossBilateral.hlsl") .Configure( arguments: new[] { offset.X, offset.Y, yuvConsts[0], yuvConsts[1] }, perTextureLinearSampling: new[] { true, false } ); var GammaToLab = CompileShader("../../Common/GammaToLab.hlsl"); var LabToGamma = CompileShader("../../Common/LabToGamma.hlsl"); var LinearToGamma = CompileShader("../../Common/LinearToGamma.hlsl"); var GammaToLinear = CompileShader("../../Common/GammaToLinear.hlsl"); var LabToLinear = CompileShader("../../Common/LabToLinear.hlsl"); var LinearToLab = CompileShader("../../Common/LinearToLab.hlsl"); hiRes = Prescaler ? new ShaderFilter(CrossBilateral, yInput, uInput, vInput) : input.ConvertToYuv(); for (int i = 1; i <= Passes; i++) { IFilter diff, linear; // Compare to chroma var rgb = new RgbFilter(hiRes, limitChroma: false); linear = new ShaderFilter(GammaToLinear, rgb); linear = new ResizeFilter(linear, chromaSize, adjointOffset, upscaler, downscaler); diff = new ShaderFilter(Diff, linear, uInput, vInput); // Update result hiRes = new ShaderFilter(SuperRes, hiRes, diff); } return(hiRes.ConvertToRgb()); }
public override IFilter CreateFilter(IFilter input) { IFilter hiRes; var chromaSize = (TextureSize)Renderer.ChromaSize; var targetSize = input.OutputSize; // Original values var yInput = new YSourceFilter(); var uInput = new USourceFilter(); var vInput = new VSourceFilter(); float[] yuvConsts = new float[0]; int bitdepth = (uInput.OutputFormat == TextureFormat.Unorm8) ? 8 : 10; float range = (1 << bitdepth) - 1; switch (Renderer.Colorimetric) { case YuvColorimetric.Auto: return(input); case YuvColorimetric.FullRangePc601: yuvConsts = new[] { 0.114f, 0.299f, 0.0f, range }; break; case YuvColorimetric.FullRangePc709: yuvConsts = new[] { 0.0722f, 0.2126f, 0.0f, range }; break; case YuvColorimetric.FullRangePc2020: yuvConsts = new[] { 0.0593f, 0.2627f, 0.0f, range }; break; case YuvColorimetric.ItuBt601: yuvConsts = new[] { 0.114f, 0.299f, 1.0f, range }; break; case YuvColorimetric.ItuBt709: yuvConsts = new[] { 0.0722f, 0.2126f, 1.0f, range }; break; case YuvColorimetric.ItuBt2020: yuvConsts = new[] { 0.0593f, 0.2627f, 1.0f, range }; break; } // Skip if downscaling if (targetSize.Width <= chromaSize.Width && targetSize.Height <= chromaSize.Height) { return(input); } Vector2 offset = Renderer.ChromaOffset; Vector2 adjointOffset = -offset * targetSize / chromaSize; string macroDefinitions = ""; if (IsIntegral(Strength)) { macroDefinitions += String.Format("strength = {0};", Strength); } if (IsIntegral(Softness)) { macroDefinitions += String.Format("softness = {0};", Softness); } var CopyLuma = CompileShader("CopyLuma.hlsl"); var CopyChroma = CompileShader("CopyChroma.hlsl"); var MergeChroma = CompileShader("MergeChroma.hlsl").Configure(format: TextureFormat.Float16); var Diff = CompileShader("Diff.hlsl") .Configure(arguments: yuvConsts, format: TextureFormat.Float16); var SuperRes = CompileShader("SuperResEx.hlsl", macroDefinitions: macroDefinitions) .Configure( arguments: new[] { Strength, Softness, yuvConsts[0], yuvConsts[1], offset.X, offset.Y } ); var CrossBilateral = CompileShader("CrossBilateral.hlsl") .Configure( arguments: new[] { offset.X, offset.Y, yuvConsts[0], yuvConsts[1] }, perTextureLinearSampling: new[] { true, false } ); var GammaToLab = CompileShader("../../Common/GammaToLab.hlsl"); var LabToGamma = CompileShader("../../Common/LabToGamma.hlsl"); var LinearToGamma = CompileShader("../../Common/LinearToGamma.hlsl"); var GammaToLinear = CompileShader("../../Common/GammaToLinear.hlsl"); var LabToLinear = CompileShader("../../Common/LabToLinear.hlsl"); var LinearToLab = CompileShader("../../Common/LinearToLab.hlsl"); hiRes = Prescaler ? new ShaderFilter(CrossBilateral, yInput, uInput, vInput) : input.ConvertToYuv(); for (int i = 1; i <= Passes; i++) { IFilter diff, linear; // Compare to chroma linear = new ShaderFilter(GammaToLinear, hiRes.ConvertToRgb()); linear = new ResizeFilter(linear, chromaSize, adjointOffset, upscaler, downscaler); diff = new ShaderFilter(Diff, linear, uInput, vInput); // Update result hiRes = new ShaderFilter(SuperRes, hiRes, diff); } return(hiRes.ConvertToRgb()); }