Implement VP9 loop filtering
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
@@ -77,65 +77,38 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
bd);
|
||||
}
|
||||
|
||||
private static int RoundMvCompQ4(int value)
|
||||
public static int RoundMvCompQ4(int value)
|
||||
{
|
||||
return (value < 0 ? value - 2 : value + 2) / 4;
|
||||
}
|
||||
|
||||
private static Mv MiMvPredQ4(ref ModeInfo mi, int idx)
|
||||
{
|
||||
return new Mv
|
||||
{
|
||||
Row = (short)RoundMvCompQ4(
|
||||
mi.Bmi[0].Mv[idx].Row + mi.Bmi[1].Mv[idx].Row +
|
||||
mi.Bmi[2].Mv[idx].Row + mi.Bmi[3].Mv[idx].Row),
|
||||
Col = (short)RoundMvCompQ4(
|
||||
mi.Bmi[0].Mv[idx].Col + mi.Bmi[1].Mv[idx].Col +
|
||||
mi.Bmi[2].Mv[idx].Col + mi.Bmi[3].Mv[idx].Col),
|
||||
};
|
||||
}
|
||||
|
||||
private static int RoundMvCompQ2(int value)
|
||||
public static int RoundMvCompQ2(int value)
|
||||
{
|
||||
return (value < 0 ? value - 1 : value + 1) / 2;
|
||||
}
|
||||
|
||||
private static Mv MiMvPredQ2(ref ModeInfo mi, int idx, int block0, int block1)
|
||||
{
|
||||
return new Mv
|
||||
{
|
||||
Row = (short)RoundMvCompQ2(
|
||||
mi.Bmi[block0].Mv[idx].Row +
|
||||
mi.Bmi[block1].Mv[idx].Row),
|
||||
Col = (short)RoundMvCompQ2(
|
||||
mi.Bmi[block0].Mv[idx].Col +
|
||||
mi.Bmi[block1].Mv[idx].Col),
|
||||
};
|
||||
}
|
||||
|
||||
public static Mv ClampMvToUmvBorderSb(ref MacroBlockD xd, ref Mv srcMv, int bw, int bh, int ssX, int ssY)
|
||||
{
|
||||
// If the MV points so far into the UMV border that no visible pixels
|
||||
// are used for reconstruction, the subpel part of the MV can be
|
||||
// discarded and the MV limited to 16 pixels with equivalent results.
|
||||
int spelLeft = (Constants.Vp9InterpExtend + bw) << SubpelBits;
|
||||
int spelLeft = (Constants.InterpExtend + bw) << SubpelBits;
|
||||
int spelRight = spelLeft - SubpelShifts;
|
||||
int spelTop = (Constants.Vp9InterpExtend + bh) << SubpelBits;
|
||||
int spelTop = (Constants.InterpExtend + bh) << SubpelBits;
|
||||
int spelBottom = spelTop - SubpelShifts;
|
||||
Mv clampedMv = new()
|
||||
{
|
||||
Row = (short)(srcMv.Row * (1 << (1 - ssY))),
|
||||
Col = (short)(srcMv.Col * (1 << (1 - ssX))),
|
||||
Row = (short)(srcMv.Row * (1 << (1 - ssY))), Col = (short)(srcMv.Col * (1 << (1 - ssX)))
|
||||
};
|
||||
|
||||
Debug.Assert(ssX <= 1);
|
||||
Debug.Assert(ssY <= 1);
|
||||
|
||||
clampedMv.ClampMv(
|
||||
xd.MbToLeftEdge * (1 << (1 - ssX)) - spelLeft,
|
||||
xd.MbToRightEdge * (1 << (1 - ssX)) + spelRight,
|
||||
xd.MbToTopEdge * (1 << (1 - ssY)) - spelTop,
|
||||
xd.MbToBottomEdge * (1 << (1 - ssY)) + spelBottom);
|
||||
clampedMv.Clamp(
|
||||
(xd.MbToLeftEdge * (1 << (1 - ssX))) - spelLeft,
|
||||
(xd.MbToRightEdge * (1 << (1 - ssX))) + spelRight,
|
||||
(xd.MbToTopEdge * (1 << (1 - ssY))) - spelTop,
|
||||
(xd.MbToBottomEdge * (1 << (1 - ssY))) + spelBottom);
|
||||
|
||||
return clampedMv;
|
||||
}
|
||||
@@ -150,18 +123,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
res = mi.Bmi[block].Mv[refr];
|
||||
break;
|
||||
case 1:
|
||||
res = MiMvPredQ2(ref mi, refr, block, block + 2);
|
||||
res = mi.MvPredQ2(refr, block, block + 2);
|
||||
break;
|
||||
case 2:
|
||||
res = MiMvPredQ2(ref mi, refr, block, block + 1);
|
||||
res = mi.MvPredQ2(refr, block, block + 1);
|
||||
break;
|
||||
case 3:
|
||||
res = MiMvPredQ4(ref mi, refr);
|
||||
res = mi.MvPredQ4(refr);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(ssIdx <= 3 && ssIdx >= 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -169,8 +143,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
int x = !sf.IsNull ? sf.Value.ScaleValueX(xOffset) : xOffset;
|
||||
int y = !sf.IsNull ? sf.Value.ScaleValueY(yOffset) : yOffset;
|
||||
|
||||
return y * stride + x;
|
||||
return (y * stride) + x;
|
||||
}
|
||||
|
||||
private static void SetupPredPlanes(
|
||||
@@ -203,12 +176,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
strides[0] = src.Stride;
|
||||
strides[1] = src.UvStride;
|
||||
strides[2] = src.UvStride;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Constants.MaxMbPlane; ++i)
|
||||
for (int i = 0; i < Constants.MaxMbPlane; ++i)
|
||||
{
|
||||
ref MacroBlockDPlane pd = ref planes[i];
|
||||
SetupPredPlanes(ref pd.Dst, buffers[i], strides[i], miRow, miCol, Ptr<ScaleFactors>.Null, pd.SubsamplingX, pd.SubsamplingY);
|
||||
SetupPredPlanes(ref pd.Dst, buffers[i], strides[i], miRow, miCol, Ptr<ScaleFactors>.Null,
|
||||
pd.SubsamplingX, pd.SubsamplingY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,14 +203,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
strides[0] = src.Stride;
|
||||
strides[1] = src.UvStride;
|
||||
strides[2] = src.UvStride;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Constants.MaxMbPlane; ++i)
|
||||
for (int i = 0; i < Constants.MaxMbPlane; ++i)
|
||||
{
|
||||
ref MacroBlockDPlane pd = ref xd.Plane[i];
|
||||
SetupPredPlanes(ref pd.Pre[idx], buffers[i], strides[i], miRow, miCol, sf, pd.SubsamplingX, pd.SubsamplingY);
|
||||
SetupPredPlanes(ref pd.Pre[idx], buffers[i], strides[i], miRow, miCol, sf, pd.SubsamplingX,
|
||||
pd.SubsamplingY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user