forked from Mirror/Ryujinx
6aa8d71588
* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Address or silence dotnet format IDE1006 warnings * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Add comments to disabled warnings * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Address IDE0251 warnings * Address a few disabled IDE0060 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * Fix empty lines before return Co-authored-by: Ac_K <Acoustik666@gmail.com> * Add trailing commas, remove redundant code and remove static modifier from Surface.HighBd * Fix naming rule violations * Fix naming rule violations * Fix empty line before return * Fix comment style Co-authored-by: Ac_K <Acoustik666@gmail.com> * Remove comment alignment * Address review feedback * Separate comments by 2 spaces and fix other formatting issues * Make HighBd an auto-property * Replace if-chain with if-else-chain * Fix new naming rule violations --------- Co-authored-by: Ac_K <Acoustik666@gmail.com>
530 lines
17 KiB
C#
530 lines
17 KiB
C#
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
|
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
|
using System;
|
|
using static Ryujinx.Graphics.Nvdec.Vp9.Dsp.InvTxfm;
|
|
|
|
namespace Ryujinx.Graphics.Nvdec.Vp9
|
|
{
|
|
internal static class Idct
|
|
{
|
|
private delegate void Transform1D(ReadOnlySpan<int> input, Span<int> output);
|
|
private delegate void HighbdTransform1D(ReadOnlySpan<int> input, Span<int> output, int bd);
|
|
|
|
private struct Transform2D
|
|
{
|
|
public Transform1D Cols, Rows; // Vertical and horizontal
|
|
|
|
public Transform2D(Transform1D cols, Transform1D rows)
|
|
{
|
|
Cols = cols;
|
|
Rows = rows;
|
|
}
|
|
}
|
|
|
|
private struct HighbdTransform2D
|
|
{
|
|
public HighbdTransform1D Cols, Rows; // Vertical and horizontal
|
|
|
|
public HighbdTransform2D(HighbdTransform1D cols, HighbdTransform1D rows)
|
|
{
|
|
Cols = cols;
|
|
Rows = rows;
|
|
}
|
|
}
|
|
|
|
private static readonly Transform2D[] _iht4 = {
|
|
new(Idct4, Idct4), // DCT_DCT = 0
|
|
new(Iadst4, Idct4), // ADST_DCT = 1
|
|
new(Idct4, Iadst4), // DCT_ADST = 2
|
|
new(Iadst4, Iadst4), // ADST_ADST = 3
|
|
};
|
|
|
|
public static void Iht4x416Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
|
{
|
|
int i, j;
|
|
Span<int> output = stackalloc int[4 * 4];
|
|
Span<int> outptr = output;
|
|
Span<int> tempIn = stackalloc int[4];
|
|
Span<int> tempOut = stackalloc int[4];
|
|
|
|
// Inverse transform row vectors
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
_iht4[txType].Rows(input, outptr);
|
|
input = input[4..];
|
|
outptr = outptr[4..];
|
|
}
|
|
|
|
// Inverse transform column vectors
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
for (j = 0; j < 4; ++j)
|
|
{
|
|
tempIn[j] = output[j * 4 + i];
|
|
}
|
|
|
|
_iht4[txType].Cols(tempIn, tempOut);
|
|
for (j = 0; j < 4; ++j)
|
|
{
|
|
dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 4));
|
|
}
|
|
}
|
|
}
|
|
|
|
private static readonly Transform2D[] _iht8 = {
|
|
new(Idct8, Idct8), // DCT_DCT = 0
|
|
new(Iadst8, Idct8), // ADST_DCT = 1
|
|
new(Idct8, Iadst8), // DCT_ADST = 2
|
|
new(Iadst8, Iadst8), // ADST_ADST = 3
|
|
};
|
|
|
|
public static void Iht8x864Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
|
{
|
|
int i, j;
|
|
Span<int> output = stackalloc int[8 * 8];
|
|
Span<int> outptr = output;
|
|
Span<int> tempIn = stackalloc int[8];
|
|
Span<int> tempOut = stackalloc int[8];
|
|
Transform2D ht = _iht8[txType];
|
|
|
|
// Inverse transform row vectors
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
ht.Rows(input, outptr);
|
|
input = input[8..];
|
|
outptr = outptr[8..];
|
|
}
|
|
|
|
// Inverse transform column vectors
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
for (j = 0; j < 8; ++j)
|
|
{
|
|
tempIn[j] = output[j * 8 + i];
|
|
}
|
|
|
|
ht.Cols(tempIn, tempOut);
|
|
for (j = 0; j < 8; ++j)
|
|
{
|
|
dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 5));
|
|
}
|
|
}
|
|
}
|
|
|
|
private static readonly Transform2D[] _iht16 = {
|
|
new(Idct16, Idct16), // DCT_DCT = 0
|
|
new(Iadst16, Idct16), // ADST_DCT = 1
|
|
new(Idct16, Iadst16), // DCT_ADST = 2
|
|
new(Iadst16, Iadst16), // ADST_ADST = 3
|
|
};
|
|
|
|
public static void Iht16x16256Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
|
{
|
|
int i, j;
|
|
Span<int> output = stackalloc int[16 * 16];
|
|
Span<int> outptr = output;
|
|
Span<int> tempIn = stackalloc int[16];
|
|
Span<int> tempOut = stackalloc int[16];
|
|
Transform2D ht = _iht16[txType];
|
|
|
|
// Rows
|
|
for (i = 0; i < 16; ++i)
|
|
{
|
|
ht.Rows(input, outptr);
|
|
input = input[16..];
|
|
outptr = outptr[16..];
|
|
}
|
|
|
|
// Columns
|
|
for (i = 0; i < 16; ++i)
|
|
{
|
|
for (j = 0; j < 16; ++j)
|
|
{
|
|
tempIn[j] = output[j * 16 + i];
|
|
}
|
|
|
|
ht.Cols(tempIn, tempOut);
|
|
for (j = 0; j < 16; ++j)
|
|
{
|
|
dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 6));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Idct
|
|
public static void Idct4x4Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
|
{
|
|
if (eob > 1)
|
|
{
|
|
Idct4x416Add(input, dest, stride);
|
|
}
|
|
else
|
|
{
|
|
Idct4x41Add(input, dest, stride);
|
|
}
|
|
}
|
|
|
|
public static void Iwht4x4Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
|
{
|
|
if (eob > 1)
|
|
{
|
|
Iwht4x416Add(input, dest, stride);
|
|
}
|
|
else
|
|
{
|
|
Iwht4x41Add(input, dest, stride);
|
|
}
|
|
}
|
|
|
|
public static void Idct8x8Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
|
{
|
|
// If dc is 1, then input[0] is the reconstructed value, do not need
|
|
// dequantization. Also, when dc is 1, dc is counted in eobs, namely eobs >=1.
|
|
|
|
// The calculation can be simplified if there are not many non-zero dct
|
|
// coefficients. Use eobs to decide what to do.
|
|
if (eob == 1)
|
|
{
|
|
// DC only DCT coefficient
|
|
Idct8x81Add(input, dest, stride);
|
|
}
|
|
else if (eob <= 12)
|
|
{
|
|
Idct8x812Add(input, dest, stride);
|
|
}
|
|
else
|
|
{
|
|
Idct8x864Add(input, dest, stride);
|
|
}
|
|
}
|
|
|
|
public static void Idct16x16Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
|
{
|
|
/* The calculation can be simplified if there are not many non-zero dct
|
|
* coefficients. Use eobs to separate different cases. */
|
|
if (eob == 1) /* DC only DCT coefficient. */
|
|
{
|
|
Idct16x161Add(input, dest, stride);
|
|
}
|
|
else if (eob <= 10)
|
|
{
|
|
Idct16x1610Add(input, dest, stride);
|
|
}
|
|
else if (eob <= 38)
|
|
{
|
|
Idct16x1638Add(input, dest, stride);
|
|
}
|
|
else
|
|
{
|
|
Idct16x16256Add(input, dest, stride);
|
|
}
|
|
}
|
|
|
|
public static void Idct32x32Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
|
{
|
|
if (eob == 1)
|
|
{
|
|
Idct32x321Add(input, dest, stride);
|
|
}
|
|
else if (eob <= 34)
|
|
{
|
|
// Non-zero coeff only in upper-left 8x8
|
|
Idct32x3234Add(input, dest, stride);
|
|
}
|
|
else if (eob <= 135)
|
|
{
|
|
// Non-zero coeff only in upper-left 16x16
|
|
Idct32x32135Add(input, dest, stride);
|
|
}
|
|
else
|
|
{
|
|
Idct32x321024Add(input, dest, stride);
|
|
}
|
|
}
|
|
|
|
// Iht
|
|
public static void Iht4x4Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
|
{
|
|
if (txType == TxType.DctDct)
|
|
{
|
|
Idct4x4Add(input, dest, stride, eob);
|
|
}
|
|
else
|
|
{
|
|
Iht4x416Add(input, dest, stride, (int)txType);
|
|
}
|
|
}
|
|
|
|
public static void Iht8x8Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
|
{
|
|
if (txType == TxType.DctDct)
|
|
{
|
|
Idct8x8Add(input, dest, stride, eob);
|
|
}
|
|
else
|
|
{
|
|
Iht8x864Add(input, dest, stride, (int)txType);
|
|
}
|
|
}
|
|
|
|
public static void Iht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest,
|
|
int stride, int eob)
|
|
{
|
|
if (txType == TxType.DctDct)
|
|
{
|
|
Idct16x16Add(input, dest, stride, eob);
|
|
}
|
|
else
|
|
{
|
|
Iht16x16256Add(input, dest, stride, (int)txType);
|
|
}
|
|
}
|
|
|
|
private static readonly HighbdTransform2D[] _highbdIht4 = {
|
|
new(HighbdIdct4, HighbdIdct4), // DCT_DCT = 0
|
|
new(HighbdIadst4, HighbdIdct4), // ADST_DCT = 1
|
|
new(HighbdIdct4, HighbdIadst4), // DCT_ADST = 2
|
|
new(HighbdIadst4, HighbdIadst4), // ADST_ADST = 3
|
|
};
|
|
|
|
public static void HighbdIht4x416Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
|
{
|
|
int i, j;
|
|
Span<int> output = stackalloc int[4 * 4];
|
|
Span<int> outptr = output;
|
|
Span<int> tempIn = stackalloc int[4];
|
|
Span<int> tempOut = stackalloc int[4];
|
|
|
|
// Inverse transform row vectors.
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
_highbdIht4[txType].Rows(input, outptr, bd);
|
|
input = input[4..];
|
|
outptr = outptr[4..];
|
|
}
|
|
|
|
// Inverse transform column vectors.
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
for (j = 0; j < 4; ++j)
|
|
{
|
|
tempIn[j] = output[j * 4 + i];
|
|
}
|
|
|
|
_highbdIht4[txType].Cols(tempIn, tempOut, bd);
|
|
for (j = 0; j < 4; ++j)
|
|
{
|
|
dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 4), bd);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static readonly HighbdTransform2D[] _highIht8 = {
|
|
new(HighbdIdct8, HighbdIdct8), // DCT_DCT = 0
|
|
new(HighbdIadst8, HighbdIdct8), // ADST_DCT = 1
|
|
new(HighbdIdct8, HighbdIadst8), // DCT_ADST = 2
|
|
new(HighbdIadst8, HighbdIadst8), // ADST_ADST = 3
|
|
};
|
|
|
|
public static void HighbdIht8x864Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
|
{
|
|
int i, j;
|
|
Span<int> output = stackalloc int[8 * 8];
|
|
Span<int> outptr = output;
|
|
Span<int> tempIn = stackalloc int[8];
|
|
Span<int> tempOut = stackalloc int[8];
|
|
HighbdTransform2D ht = _highIht8[txType];
|
|
|
|
// Inverse transform row vectors.
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
ht.Rows(input, outptr, bd);
|
|
input = input[8..];
|
|
outptr = output[8..];
|
|
}
|
|
|
|
// Inverse transform column vectors.
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
for (j = 0; j < 8; ++j)
|
|
{
|
|
tempIn[j] = output[j * 8 + i];
|
|
}
|
|
|
|
ht.Cols(tempIn, tempOut, bd);
|
|
for (j = 0; j < 8; ++j)
|
|
{
|
|
dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 5), bd);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static readonly HighbdTransform2D[] _highIht16 = {
|
|
new(HighbdIdct16, HighbdIdct16), // DCT_DCT = 0
|
|
new(HighbdIadst16, HighbdIdct16), // ADST_DCT = 1
|
|
new(HighbdIdct16, HighbdIadst16), // DCT_ADST = 2
|
|
new(HighbdIadst16, HighbdIadst16), // ADST_ADST = 3
|
|
};
|
|
|
|
public static void HighbdIht16x16256Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
|
{
|
|
int i, j;
|
|
Span<int> output = stackalloc int[16 * 16];
|
|
Span<int> outptr = output;
|
|
Span<int> tempIn = stackalloc int[16];
|
|
Span<int> tempOut = stackalloc int[16];
|
|
HighbdTransform2D ht = _highIht16[txType];
|
|
|
|
// Rows
|
|
for (i = 0; i < 16; ++i)
|
|
{
|
|
ht.Rows(input, outptr, bd);
|
|
input = input[16..];
|
|
outptr = output[16..];
|
|
}
|
|
|
|
// Columns
|
|
for (i = 0; i < 16; ++i)
|
|
{
|
|
for (j = 0; j < 16; ++j)
|
|
{
|
|
tempIn[j] = output[j * 16 + i];
|
|
}
|
|
|
|
ht.Cols(tempIn, tempOut, bd);
|
|
for (j = 0; j < 16; ++j)
|
|
{
|
|
dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 6), bd);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Idct
|
|
public static void HighbdIdct4x4Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
|
{
|
|
if (eob > 1)
|
|
{
|
|
HighbdIdct4x416Add(input, dest, stride, bd);
|
|
}
|
|
else
|
|
{
|
|
HighbdIdct4x41Add(input, dest, stride, bd);
|
|
}
|
|
}
|
|
|
|
public static void HighbdIwht4x4Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
|
{
|
|
if (eob > 1)
|
|
{
|
|
HighbdIwht4x416Add(input, dest, stride, bd);
|
|
}
|
|
else
|
|
{
|
|
HighbdIwht4x41Add(input, dest, stride, bd);
|
|
}
|
|
}
|
|
|
|
public static void HighbdIdct8x8Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
|
{
|
|
// If dc is 1, then input[0] is the reconstructed value, do not need
|
|
// dequantization. Also, when dc is 1, dc is counted in eobs, namely eobs >=1.
|
|
|
|
// The calculation can be simplified if there are not many non-zero dct
|
|
// coefficients. Use eobs to decide what to do.
|
|
// DC only DCT coefficient
|
|
if (eob == 1)
|
|
{
|
|
Vpx_Highbdidct8x8_1_add_c(input, dest, stride, bd);
|
|
}
|
|
else if (eob <= 12)
|
|
{
|
|
HighbdIdct8x812Add(input, dest, stride, bd);
|
|
}
|
|
else
|
|
{
|
|
HighbdIdct8x864Add(input, dest, stride, bd);
|
|
}
|
|
}
|
|
|
|
public static void HighbdIdct16x16Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
|
{
|
|
// The calculation can be simplified if there are not many non-zero dct
|
|
// coefficients. Use eobs to separate different cases.
|
|
// DC only DCT coefficient.
|
|
if (eob == 1)
|
|
{
|
|
HighbdIdct16x161Add(input, dest, stride, bd);
|
|
}
|
|
else if (eob <= 10)
|
|
{
|
|
HighbdIdct16x1610Add(input, dest, stride, bd);
|
|
}
|
|
else if (eob <= 38)
|
|
{
|
|
HighbdIdct16x1638Add(input, dest, stride, bd);
|
|
}
|
|
else
|
|
{
|
|
HighbdIdct16x16256Add(input, dest, stride, bd);
|
|
}
|
|
}
|
|
|
|
public static void HighbdIdct32x32Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
|
{
|
|
// Non-zero coeff only in upper-left 8x8
|
|
if (eob == 1)
|
|
{
|
|
HighbdIdct32x321Add(input, dest, stride, bd);
|
|
}
|
|
else if (eob <= 34)
|
|
{
|
|
HighbdIdct32x3234Add(input, dest, stride, bd);
|
|
}
|
|
else if (eob <= 135)
|
|
{
|
|
HighbdIdct32x32135Add(input, dest, stride, bd);
|
|
}
|
|
else
|
|
{
|
|
HighbdIdct32x321024Add(input, dest, stride, bd);
|
|
}
|
|
}
|
|
|
|
// Iht
|
|
public static void HighbdIht4x4Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
|
{
|
|
if (txType == TxType.DctDct)
|
|
{
|
|
HighbdIdct4x4Add(input, dest, stride, eob, bd);
|
|
}
|
|
else
|
|
{
|
|
HighbdIht4x416Add(input, dest, stride, (int)txType, bd);
|
|
}
|
|
}
|
|
|
|
public static void HighbdIht8x8Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
|
{
|
|
if (txType == TxType.DctDct)
|
|
{
|
|
HighbdIdct8x8Add(input, dest, stride, eob, bd);
|
|
}
|
|
else
|
|
{
|
|
HighbdIht8x864Add(input, dest, stride, (int)txType, bd);
|
|
}
|
|
}
|
|
|
|
public static void HighbdIht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
|
{
|
|
if (txType == TxType.DctDct)
|
|
{
|
|
HighbdIdct16x16Add(input, dest, stride, eob, bd);
|
|
}
|
|
else
|
|
{
|
|
HighbdIht16x16256Add(input, dest, stride, (int)txType, bd);
|
|
}
|
|
}
|
|
}
|
|
}
|