mirror of
https://github.com/GreemDev/Ryujinx.git
synced 2024-12-22 21:35:48 +00:00
[Ryujinx.Graphics.Nvdec.Vp9] Address dotnet-format issues (#5371)
* 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>
This commit is contained in:
parent
9becbd7d72
commit
6aa8d71588
41 changed files with 1240 additions and 1207 deletions
|
@ -51,6 +51,6 @@
|
|||
/*!\brief An iterator reached the end of list.
|
||||
*
|
||||
*/
|
||||
CodecListEnd
|
||||
CodecListEnd,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
|||
{
|
||||
10 => (ushort)Math.Clamp(val, 0, 1023),
|
||||
12 => (ushort)Math.Clamp(val, 0, 4095),
|
||||
_ => (ushort)Math.Clamp(val, 0, 255)
|
||||
_ => (ushort)Math.Clamp(val, 0, 255),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
|||
private static int GetMsb(uint n)
|
||||
{
|
||||
Debug.Assert(n != 0);
|
||||
|
||||
return 31 ^ BitOperations.LeadingZeroCount(n);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
|||
public bool InUse;
|
||||
}
|
||||
|
||||
private PoolItem[] _pool = new PoolItem[PoolEntries];
|
||||
private readonly PoolItem[] _pool = new PoolItem[PoolEntries];
|
||||
|
||||
public ArrayPtr<T> Allocate<T>(int length) where T : unmanaged
|
||||
{
|
||||
|
@ -91,4 +91,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
public const int MaxRefFrames = 4;
|
||||
|
||||
public const int MiSizeLog2 = 3;
|
||||
public const int MiBlockSizeLog2 = 6 - MiSizeLog2; // 64 = 2^6
|
||||
public const int MiBlockSizeLog2 = 6 - MiSizeLog2; // 64 = 2^6
|
||||
|
||||
public const int MiSize = 1 << MiSizeLog2; // pixels per mi-unit
|
||||
public const int MiBlockSize = 1 << MiBlockSizeLog2; // mi-units per max block
|
||||
public const int MiSize = 1 << MiSizeLog2; // pixels per mi-unit
|
||||
public const int MiBlockSize = 1 << MiBlockSizeLog2; // mi-units per max block
|
||||
public const int MiMask = MiBlockSize - 1;
|
||||
|
||||
public const int PartitionPloffset = 4; // number of probability models per block size
|
||||
public const int PartitionPloffset = 4; // number of probability models per block size
|
||||
|
||||
/* Segment Feature Masks */
|
||||
public const int MaxMvRefCandidates = 2;
|
||||
|
@ -48,9 +48,9 @@
|
|||
public const int MvLow = -(1 << MvInUseBits);
|
||||
|
||||
// Coefficient token alphabet
|
||||
public const int ZeroToken = 0; // 0 Extra Bits 0+0
|
||||
public const int OneToken = 1; // 1 Extra Bits 0+1
|
||||
public const int TwoToken = 2; // 2 Extra Bits 0+1
|
||||
public const int ZeroToken = 0; // 0 Extra Bits 0+0
|
||||
public const int OneToken = 1; // 1 Extra Bits 0+1
|
||||
public const int TwoToken = 2; // 2 Extra Bits 0+1
|
||||
|
||||
public const int PivotNode = 2;
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ using System.Diagnostics;
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using Mv = Ryujinx.Graphics.Nvdec.Vp9.Types.Mv;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
|
@ -48,7 +47,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
case TxSize.Tx32x32:
|
||||
Idct.HighbdIdct32x32Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
break;
|
||||
default: Debug.Assert(false, "Invalid transform size"); break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid transform size");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,11 +63,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
switch (txSize)
|
||||
{
|
||||
case TxSize.Tx4x4: Idct.Idct4x4Add(dqcoeff.AsSpan(), dst, stride, eob); break;
|
||||
case TxSize.Tx8x8: Idct.Idct8x8Add(dqcoeff.AsSpan(), dst, stride, eob); break;
|
||||
case TxSize.Tx16x16: Idct.Idct16x16Add(dqcoeff.AsSpan(), dst, stride, eob); break;
|
||||
case TxSize.Tx32x32: Idct.Idct32x32Add(dqcoeff.AsSpan(), dst, stride, eob); break;
|
||||
default: Debug.Assert(false, "Invalid transform size"); return;
|
||||
case TxSize.Tx4x4:
|
||||
Idct.Idct4x4Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx8x8:
|
||||
Idct.Idct8x8Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx16x16:
|
||||
Idct.Idct16x16Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx32x32:
|
||||
Idct.Idct32x32Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid transform size");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,15 +90,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
if (txSize <= TxSize.Tx16x16 && eob <= 10)
|
||||
{
|
||||
dqcoeff.AsSpan().Slice(0, 4 * (4 << (int)txSize)).Fill(0);
|
||||
dqcoeff.AsSpan()[..(4 * (4 << (int)txSize))].Clear();
|
||||
}
|
||||
else if (txSize == TxSize.Tx32x32 && eob <= 34)
|
||||
{
|
||||
dqcoeff.AsSpan().Slice(0, 256).Fill(0);
|
||||
dqcoeff.AsSpan()[..256].Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
dqcoeff.AsSpan().Slice(0, 16 << ((int)txSize << 1)).Fill(0);
|
||||
dqcoeff.AsSpan()[..(16 << ((int)txSize << 1))].Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +138,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
case TxSize.Tx32x32:
|
||||
Idct.HighbdIdct32x32Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
break;
|
||||
default: Debug.Assert(false, "Invalid transform size"); break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid transform size");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,11 +154,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
switch (txSize)
|
||||
{
|
||||
case TxSize.Tx4x4: Idct.Iht4x4Add(txType, dqcoeff.AsSpan(), dst, stride, eob); break;
|
||||
case TxSize.Tx8x8: Idct.Iht8x8Add(txType, dqcoeff.AsSpan(), dst, stride, eob); break;
|
||||
case TxSize.Tx16x16: Idct.Iht16x16Add(txType, dqcoeff.AsSpan(), dst, stride, eob); break;
|
||||
case TxSize.Tx32x32: Idct.Idct32x32Add(dqcoeff.AsSpan(), dst, stride, eob); break;
|
||||
default: Debug.Assert(false, "Invalid transform size"); return;
|
||||
case TxSize.Tx4x4:
|
||||
Idct.Iht4x4Add(txType, dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx8x8:
|
||||
Idct.Iht8x8Add(txType, dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx16x16:
|
||||
Idct.Iht16x16Add(txType, dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx32x32:
|
||||
Idct.Idct32x32Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid transform size");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,15 +181,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
if (txType == TxType.DctDct && txSize <= TxSize.Tx16x16 && eob <= 10)
|
||||
{
|
||||
dqcoeff.AsSpan().Slice(0, 4 * (4 << (int)txSize)).Fill(0);
|
||||
dqcoeff.AsSpan()[..(4 * (4 << (int)txSize))].Clear();
|
||||
}
|
||||
else if (txSize == TxSize.Tx32x32 && eob <= 34)
|
||||
{
|
||||
dqcoeff.AsSpan().Slice(0, 256).Fill(0);
|
||||
dqcoeff.AsSpan()[..256].Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
dqcoeff.AsSpan().Slice(0, 16 << ((int)txSize << 1)).Fill(0);
|
||||
dqcoeff.AsSpan()[..(16 << ((int)txSize << 1))].Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -184,7 +207,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
PredictionMode mode = (plane == 0) ? mi.Mode : mi.UvMode;
|
||||
int dstOffset = 4 * row * pd.Dst.Stride + 4 * col;
|
||||
byte* dst = &pd.Dst.Buf.ToPointer()[dstOffset];
|
||||
Span<byte> dstSpan = pd.Dst.Buf.AsSpan().Slice(dstOffset);
|
||||
Span<byte> dstSpan = pd.Dst.Buf.AsSpan()[dstOffset..];
|
||||
|
||||
if (mi.SbType < BlockSize.Block8x8)
|
||||
{
|
||||
|
@ -223,7 +246,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
ref MacroBlockDPlane pd = ref xd.Plane[plane];
|
||||
var sc = Luts.Vp9DefaultScanOrders[(int)txSize];
|
||||
int eob = Detokenize.DecodeBlockTokens(ref twd, plane, sc, col, row, txSize, mi.SegmentId);
|
||||
Span<byte> dst = pd.Dst.Buf.AsSpan().Slice(4 * row * pd.Dst.Stride + 4 * col);
|
||||
Span<byte> dst = pd.Dst.Buf.AsSpan()[(4 * row * pd.Dst.Stride + 4 * col)..];
|
||||
|
||||
if (eob > 0)
|
||||
{
|
||||
|
@ -589,9 +612,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
refr,
|
||||
xs,
|
||||
ys);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (xd.CurBuf.HighBd)
|
||||
{
|
||||
ReconInter.HighbdInterPredictor(
|
||||
|
@ -793,6 +818,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
xd.SetMiRowCol(ref tile, miRow, bh, miCol, bw, cm.MiRows, cm.MiCols);
|
||||
|
||||
ReconInter.SetupDstPlanes(ref xd.Plane, ref xd.CurBuf, miRow, miCol);
|
||||
|
||||
return ref xd.Mi[0].Value;
|
||||
}
|
||||
|
||||
|
@ -893,7 +919,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
if (!less8x8 && eobtotal == 0)
|
||||
{
|
||||
mi.Skip = 1; // Skip loopfilter
|
||||
mi.Skip = 1; // Skip loopfilter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -928,8 +954,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// Update the partition context at the end notes. Set partition bits
|
||||
// of block sizes larger than the current one to be one, and partition
|
||||
// bits of smaller block sizes to be zero.
|
||||
aboveCtx.Slice(0, bw).Fill(Luts.PartitionContextLookup[(int)subsize].Above);
|
||||
leftCtx.Slice(0, bw).Fill(Luts.PartitionContextLookup[(int)subsize].Left);
|
||||
aboveCtx[..bw].Fill(Luts.PartitionContextLookup[(int)subsize].Above);
|
||||
leftCtx[..bw].Fill(Luts.PartitionContextLookup[(int)subsize].Left);
|
||||
}
|
||||
|
||||
private static PartitionType ReadPartition(
|
||||
|
@ -1030,7 +1056,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
DecodePartition(ref twd, ref cm, miRow + hbs, miCol, subsize, n8x8L2);
|
||||
DecodePartition(ref twd, ref cm, miRow + hbs, miCol + hbs, subsize, n8x8L2);
|
||||
break;
|
||||
default: Debug.Assert(false, "Invalid partition type"); break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid partition type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1134,7 +1162,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
int alignedCols = TileInfo.MiColsAlignedToSb(cm.MiCols);
|
||||
int tileCols = 1 << cm.Log2TileCols;
|
||||
int tileRows = 1 << cm.Log2TileRows;
|
||||
Array4<Array64<TileBuffer>> tileBuffers = new Array4<Array64<TileBuffer>>();
|
||||
Array4<Array64<TileBuffer>> tileBuffers = new();
|
||||
int tileRow, tileCol;
|
||||
int miRow, miCol;
|
||||
|
||||
|
@ -1168,7 +1196,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
for (tileRow = 0; tileRow < tileRows; ++tileRow)
|
||||
{
|
||||
TileInfo tile = new TileInfo();
|
||||
TileInfo tile = new();
|
||||
tile.SetRow(ref cm, tileRow);
|
||||
for (miRow = tile.MiRowStart; miRow < tile.MiRowEnd; miRow += Constants.MiBlockSize)
|
||||
{
|
||||
|
@ -1234,10 +1262,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
} while (!tileData.Xd.Corrupted && ++n <= tileData.BufEnd);
|
||||
|
||||
tileData.DataEnd = bitReaderEnd;
|
||||
|
||||
return !tileData.Xd.Corrupted;
|
||||
}
|
||||
|
||||
public static unsafe ArrayPtr<byte> DecodeTilesMt(ref Vp9Common cm, ArrayPtr<byte> data, int maxThreads)
|
||||
public static ArrayPtr<byte> DecodeTilesMt(ref Vp9Common cm, ArrayPtr<byte> data, int maxThreads)
|
||||
{
|
||||
ArrayPtr<byte> bitReaderEnd = ArrayPtr<byte>.Null;
|
||||
|
||||
|
@ -1250,8 +1279,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
Debug.Assert(tileCols <= (1 << 6));
|
||||
Debug.Assert(tileRows == 1);
|
||||
|
||||
cm.AboveContext.AsSpan().Fill(0);
|
||||
cm.AboveSegContext.AsSpan().Fill(0);
|
||||
cm.AboveContext.AsSpan().Clear();
|
||||
cm.AboveSegContext.AsSpan().Clear();
|
||||
|
||||
for (n = 0; n < numWorkers; ++n)
|
||||
{
|
||||
|
@ -1262,17 +1291,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
tileData.Counts = new Vp9BackwardUpdates();
|
||||
}
|
||||
|
||||
Array64<TileBuffer> tileBuffers = new Array64<TileBuffer>();
|
||||
Array64<TileBuffer> tileBuffers = new();
|
||||
|
||||
GetTileBuffers(ref cm, data, tileCols, ref tileBuffers);
|
||||
|
||||
tileBuffers.AsSpan().Slice(0, tileCols).Sort(CompareTileBuffers);
|
||||
tileBuffers.AsSpan()[..tileCols].Sort(CompareTileBuffers);
|
||||
|
||||
if (numWorkers == tileCols)
|
||||
{
|
||||
TileBuffer largest = tileBuffers[0];
|
||||
Span<TileBuffer> buffers = tileBuffers.AsSpan();
|
||||
buffers.Slice(1).CopyTo(buffers.Slice(0, tileBuffers.Length - 1));
|
||||
buffers[1..].CopyTo(buffers[..(tileBuffers.Length - 1)]);
|
||||
tileBuffers[tileCols - 1] = largest;
|
||||
}
|
||||
else
|
||||
|
@ -1307,9 +1336,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
bufStart += count;
|
||||
}
|
||||
|
||||
Ptr<Vp9Common> cmPtr = new Ptr<Vp9Common>(ref cm);
|
||||
Ptr<Vp9Common> cmPtr = new(ref cm);
|
||||
|
||||
Parallel.For(0, numWorkers, (n) =>
|
||||
Parallel.For(0, numWorkers, n =>
|
||||
{
|
||||
ref TileWorkerData tileData = ref cmPtr.Value.TileWorkerData[n + totalTiles];
|
||||
|
||||
|
@ -1335,6 +1364,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
|
||||
Debug.Assert(!bitReaderEnd.IsNull || cm.Mb.Corrupted);
|
||||
|
||||
return bitReaderEnd;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@ using Ryujinx.Graphics.Video;
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Mv = Ryujinx.Graphics.Nvdec.Vp9.Types.Mv;
|
||||
using MvRef = Ryujinx.Graphics.Nvdec.Vp9.Types.MvRef;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
|
@ -61,10 +59,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
switch (maxTxSize)
|
||||
{
|
||||
case TxSize.Tx8x8: return fc.Tx8x8Prob[ctx].AsSpan();
|
||||
case TxSize.Tx16x16: return fc.Tx16x16Prob[ctx].AsSpan();
|
||||
case TxSize.Tx32x32: return fc.Tx32x32Prob[ctx].AsSpan();
|
||||
default: Debug.Assert(false, "Invalid maxTxSize."); return ReadOnlySpan<byte>.Empty;
|
||||
case TxSize.Tx8x8:
|
||||
return fc.Tx8x8Prob[ctx].AsSpan();
|
||||
case TxSize.Tx16x16:
|
||||
return fc.Tx16x16Prob[ctx].AsSpan();
|
||||
case TxSize.Tx32x32:
|
||||
return fc.Tx32x32Prob[ctx].AsSpan();
|
||||
default:
|
||||
Debug.Assert(false, "Invalid maxTxSize.");
|
||||
|
||||
return ReadOnlySpan<byte>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,10 +76,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
switch (maxTxSize)
|
||||
{
|
||||
case TxSize.Tx8x8: return counts.Tx8x8[ctx].AsSpan();
|
||||
case TxSize.Tx16x16: return counts.Tx16x16[ctx].AsSpan();
|
||||
case TxSize.Tx32x32: return counts.Tx32x32[ctx].AsSpan();
|
||||
default: Debug.Assert(false, "Invalid maxTxSize."); return Span<uint>.Empty;
|
||||
case TxSize.Tx8x8:
|
||||
return counts.Tx8x8[ctx].AsSpan();
|
||||
case TxSize.Tx16x16:
|
||||
return counts.Tx16x16[ctx].AsSpan();
|
||||
case TxSize.Tx32x32:
|
||||
return counts.Tx32x32[ctx].AsSpan();
|
||||
default:
|
||||
Debug.Assert(false, "Invalid maxTxSize.");
|
||||
|
||||
return Span<uint>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,10 +120,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
return ReadSelectedTxSize(ref cm, ref xd, maxTxSize, ref r);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (TxSize)Math.Min((int)maxTxSize, (int)Luts.TxModeToBiggestTxSize[(int)txMode]);
|
||||
}
|
||||
|
||||
return (TxSize)Math.Min((int)maxTxSize, (int)Luts.TxModeToBiggestTxSize[(int)txMode]);
|
||||
}
|
||||
|
||||
private static int DecGetSegmentId(ref Vp9Common cm, ArrayPtr<byte> segmentIds, int miOffset, int xMis, int yMis)
|
||||
|
@ -129,6 +137,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
|
||||
Debug.Assert(segmentId >= 0 && segmentId < Constants.MaxSegments);
|
||||
|
||||
return segmentId;
|
||||
}
|
||||
|
||||
|
@ -173,17 +182,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
if (!seg.Enabled)
|
||||
{
|
||||
return 0; // Default for disabled segmentation
|
||||
return 0; // Default for disabled segmentation
|
||||
}
|
||||
|
||||
if (!seg.UpdateMap)
|
||||
{
|
||||
CopySegmentId(ref cm, cm.LastFrameSegMap, cm.CurrentFrameSegMap, miOffset, xMis, yMis);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
segmentId = ReadSegmentId(ref r, ref cm.Fc.Value.SegTreeProb);
|
||||
SetSegmentId(ref cm, miOffset, xMis, yMis, segmentId);
|
||||
|
||||
return segmentId;
|
||||
}
|
||||
|
||||
|
@ -203,7 +214,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
if (!seg.Enabled)
|
||||
{
|
||||
return 0; // Default for disabled segmentation
|
||||
return 0; // Default for disabled segmentation
|
||||
}
|
||||
|
||||
predictedSegmentId = !cm.LastFrameSegMap.IsNull
|
||||
|
@ -213,6 +224,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
if (!seg.UpdateMap)
|
||||
{
|
||||
CopySegmentId(ref cm, cm.LastFrameSegMap, cm.CurrentFrameSegMap, miOffset, xMis, yMis);
|
||||
|
||||
return predictedSegmentId;
|
||||
}
|
||||
|
||||
|
@ -227,6 +239,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
segmentId = ReadSegmentId(ref r, ref cm.Fc.Value.SegTreeProb);
|
||||
}
|
||||
SetSegmentId(ref cm, miOffset, xMis, yMis, segmentId);
|
||||
|
||||
return segmentId;
|
||||
}
|
||||
|
||||
|
@ -236,17 +249,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ctx = xd.GetSkipContext();
|
||||
int skip = r.Read(cm.Fc.Value.SkipProb[ctx]);
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
++xd.Counts.Value.Skip[ctx][skip];
|
||||
}
|
||||
|
||||
return skip;
|
||||
int ctx = xd.GetSkipContext();
|
||||
int skip = r.Read(cm.Fc.Value.SkipProb[ctx]);
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
++xd.Counts.Value.Skip[ctx][skip];
|
||||
}
|
||||
|
||||
return skip;
|
||||
}
|
||||
|
||||
private static int ReadMvComponent(ref Reader r, ref Vp9EntropyProbs fc, int mvcomp, bool usehp)
|
||||
|
@ -265,7 +276,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
else
|
||||
{
|
||||
int i;
|
||||
int n = (int)mvClass + Constants.Class0Bits - 1; // Number of bits
|
||||
int n = (int)mvClass + Constants.Class0Bits - 1; // Number of bits
|
||||
|
||||
d = 0;
|
||||
for (i = 0; i < n; ++i)
|
||||
|
@ -284,6 +295,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
// Result
|
||||
mag += ((d << 3) | (fr << 1) | hp) + 1;
|
||||
|
||||
return sign ? -mag : mag;
|
||||
}
|
||||
|
||||
|
@ -297,7 +309,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
MvJointType jointType = (MvJointType)r.ReadTree(Luts.Vp9MvJointTree, fc.Joints.AsSpan());
|
||||
bool useHP = allowHP && refr.UseMvHp();
|
||||
Mv diff = new Mv();
|
||||
Mv diff = new();
|
||||
|
||||
if (Mv.MvJointVertical(jointType))
|
||||
{
|
||||
|
@ -326,12 +338,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
++xd.Counts.Value.CompInter[ctx][(int)mode];
|
||||
}
|
||||
|
||||
return mode; // SingleReference or CompoundReference
|
||||
}
|
||||
else
|
||||
{
|
||||
return cm.ReferenceMode;
|
||||
return mode; // SingleReference or CompoundReference
|
||||
}
|
||||
|
||||
return cm.ReferenceMode;
|
||||
}
|
||||
|
||||
// Read the referncence frame
|
||||
|
@ -434,7 +444,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
mi.Bmi[0].Mode = mi.Bmi[1].Mode = ReadIntraModeY(ref cm, ref xd, ref r, 0);
|
||||
mi.Bmi[2].Mode = mi.Bmi[3].Mode = mi.Mode = ReadIntraModeY(ref cm, ref xd, ref r, 0);
|
||||
break;
|
||||
default: mi.Mode = ReadIntraModeY(ref cm, ref xd, ref r, Luts.SizeGroupLookup[(int)bsize]); break;
|
||||
default:
|
||||
mi.Mode = ReadIntraModeY(ref cm, ref xd, ref r, Luts.SizeGroupLookup[(int)bsize]);
|
||||
break;
|
||||
}
|
||||
|
||||
mi.UvMode = ReadIntraModeUv(ref cm, ref xd, ref r, (byte)mi.Mode);
|
||||
|
@ -503,7 +515,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
ZeroMvPair(ref mv);
|
||||
break;
|
||||
}
|
||||
default: return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -514,17 +527,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
return cm.Seg.GetSegData(segmentId, SegLvlFeatures.SegLvlRefFrame) != Constants.IntraFrame;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ctx = xd.GetIntraInterContext();
|
||||
bool isInter = r.Read(cm.Fc.Value.IntraInterProb[ctx]) != 0;
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
++xd.Counts.Value.IntraInter[ctx][isInter ? 1 : 0];
|
||||
}
|
||||
|
||||
return isInter;
|
||||
int ctx = xd.GetIntraInterContext();
|
||||
bool isInter = r.Read(cm.Fc.Value.IntraInterProb[ctx]) != 0;
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
++xd.Counts.Value.IntraInter[ctx][isInter ? 1 : 0];
|
||||
}
|
||||
|
||||
return isInter;
|
||||
}
|
||||
|
||||
private static void DecFindBestRefMvs(bool allowHP, Span<Mv> mvlist, ref Mv bestMv, int refmvCount)
|
||||
|
@ -547,6 +558,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
mvRefList[refMvCount] = mv;
|
||||
refMvCount++;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -605,7 +617,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
// This function searches the neighborhood of a given MB/SB
|
||||
// to try and find candidate reference vectors.
|
||||
private static unsafe int DecFindMvRefs(
|
||||
private static int DecFindMvRefs(
|
||||
ref Vp9Common cm,
|
||||
ref MacroBlockD xd,
|
||||
PredictionMode mode,
|
||||
|
@ -627,7 +639,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
bool earlyBreak = mode != PredictionMode.NearMv;
|
||||
|
||||
// Blank the reference vector list
|
||||
mvRefList.Slice(0, Constants.MaxMvRefCandidates).Fill(new Mv());
|
||||
mvRefList[..Constants.MaxMvRefCandidates].Clear();
|
||||
|
||||
i = 0;
|
||||
if (isSub8X8 != 0)
|
||||
|
@ -805,7 +817,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
switch (block)
|
||||
{
|
||||
case 0: bestSub8x8 = mvList[refmvCount - 1]; break;
|
||||
case 0:
|
||||
bestSub8x8 = mvList[refmvCount - 1];
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
if (bMode == PredictionMode.NearestMv)
|
||||
|
@ -848,7 +862,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
break;
|
||||
default: Debug.Assert(false, "Invalid block index."); break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid block index.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -883,7 +899,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
BlockSize bsize = mi.SbType;
|
||||
bool allowHP = cm.AllowHighPrecisionMv;
|
||||
Array2<Mv> bestRefMvs = new Array2<Mv>();
|
||||
Array2<Mv> bestRefMvs = new();
|
||||
int refr, isCompound;
|
||||
byte interModeCtx;
|
||||
Span<Position> mvRefSearch = Luts.MvRefBlocks[(int)bsize];
|
||||
|
@ -898,6 +914,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
if (bsize < BlockSize.Block8x8)
|
||||
{
|
||||
xd.ErrorInfo.Value.InternalError(CodecErr.CodecUnsupBitstream, "Invalid usage of segement feature on small blocks");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -940,11 +957,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
int num4X4H = 1 << xd.BmodeBlocksHl;
|
||||
int idx, idy;
|
||||
PredictionMode bMode = 0;
|
||||
Array2<Mv> bestSub8x8 = new Array2<Mv>();
|
||||
const uint invalidMv = 0x80008000;
|
||||
Array2<Mv> bestSub8x8 = new();
|
||||
const uint InvalidMv = 0x80008000;
|
||||
// Initialize the 2nd element as even though it won't be used meaningfully
|
||||
// if isCompound is false.
|
||||
Unsafe.As<Mv, uint>(ref bestSub8x8[1]) = invalidMv;
|
||||
Unsafe.As<Mv, uint>(ref bestSub8x8[1]) = InvalidMv;
|
||||
for (idy = 0; idy < 2; idy += num4X4H)
|
||||
{
|
||||
for (idx = 0; idx < 2; idx += num4X4W)
|
||||
|
@ -1026,11 +1043,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
return leftMi.Value.GetYMode(b + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(b == 1 || b == 3);
|
||||
return curMi.Value.Bmi[b - 1].Mode;
|
||||
}
|
||||
|
||||
Debug.Assert(b == 1 || b == 3);
|
||||
|
||||
return curMi.Value.Bmi[b - 1].Mode;
|
||||
}
|
||||
|
||||
private static PredictionMode AboveBlockMode(Ptr<ModeInfo> curMi, Ptr<ModeInfo> aboveMi, int b)
|
||||
|
@ -1044,11 +1060,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
return aboveMi.Value.GetYMode(b + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(b == 2 || b == 3);
|
||||
return curMi.Value.Bmi[b - 2].Mode;
|
||||
}
|
||||
|
||||
Debug.Assert(b == 2 || b == 3);
|
||||
|
||||
return curMi.Value.Bmi[b - 2].Mode;
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> GetYModeProbs(
|
||||
|
@ -1060,6 +1075,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
PredictionMode above = AboveBlockMode(mi, aboveMi, block);
|
||||
PredictionMode left = LeftBlockMode(mi, leftMi, block);
|
||||
|
||||
return fc.KfYModeProb[(int)above][(int)left].AsSpan();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
|||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
using Vp9MvRef = Ryujinx.Graphics.Video.Vp9MvRef;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
|
@ -11,7 +10,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
public bool IsHardwareAccelerated => false;
|
||||
|
||||
private readonly MemoryAllocator _allocator = new MemoryAllocator();
|
||||
private readonly MemoryAllocator _allocator = new();
|
||||
|
||||
public ISurface CreateSurface(int width, int height) => new Surface(width, height);
|
||||
|
||||
|
@ -20,7 +19,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
Constants.EightTapSmooth,
|
||||
Constants.EightTap,
|
||||
Constants.EightTapSharp,
|
||||
Constants.Bilinear
|
||||
Constants.Bilinear,
|
||||
};
|
||||
|
||||
public unsafe bool Decode(
|
||||
|
@ -30,24 +29,25 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
ReadOnlySpan<Vp9MvRef> mvsIn,
|
||||
Span<Vp9MvRef> mvsOut)
|
||||
{
|
||||
Vp9Common cm = new Vp9Common();
|
||||
Vp9Common cm = new()
|
||||
{
|
||||
FrameType = pictureInfo.IsKeyFrame ? FrameType.KeyFrame : FrameType.InterFrame,
|
||||
IntraOnly = pictureInfo.IntraOnly,
|
||||
|
||||
cm.FrameType = pictureInfo.IsKeyFrame ? FrameType.KeyFrame : FrameType.InterFrame;
|
||||
cm.IntraOnly = pictureInfo.IntraOnly;
|
||||
Width = output.Width,
|
||||
Height = output.Height,
|
||||
SubsamplingX = 1,
|
||||
SubsamplingY = 1,
|
||||
|
||||
cm.Width = output.Width;
|
||||
cm.Height = output.Height;
|
||||
cm.SubsamplingX = 1;
|
||||
cm.SubsamplingY = 1;
|
||||
UsePrevFrameMvs = pictureInfo.UsePrevInFindMvRefs,
|
||||
|
||||
cm.UsePrevFrameMvs = pictureInfo.UsePrevInFindMvRefs;
|
||||
RefFrameSignBias = pictureInfo.RefFrameSignBias,
|
||||
|
||||
cm.RefFrameSignBias = pictureInfo.RefFrameSignBias;
|
||||
|
||||
cm.BaseQindex = pictureInfo.BaseQIndex;
|
||||
cm.YDcDeltaQ = pictureInfo.YDcDeltaQ;
|
||||
cm.UvAcDeltaQ = pictureInfo.UvAcDeltaQ;
|
||||
cm.UvDcDeltaQ = pictureInfo.UvDcDeltaQ;
|
||||
BaseQindex = pictureInfo.BaseQIndex,
|
||||
YDcDeltaQ = pictureInfo.YDcDeltaQ,
|
||||
UvAcDeltaQ = pictureInfo.UvAcDeltaQ,
|
||||
UvDcDeltaQ = pictureInfo.UvDcDeltaQ,
|
||||
};
|
||||
|
||||
cm.Mb.Lossless = pictureInfo.Lossless;
|
||||
cm.Mb.Bd = 8;
|
||||
|
|
|
@ -17,9 +17,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
private static int GetCoefContext(ReadOnlySpan<short> neighbors, ReadOnlySpan<byte> tokenCache, int c)
|
||||
{
|
||||
const int maxNeighbors = 2;
|
||||
const int MaxNeighbors = 2;
|
||||
|
||||
return (1 + tokenCache[neighbors[maxNeighbors * c + 0]] + tokenCache[neighbors[maxNeighbors * c + 1]]) >> 1;
|
||||
return (1 + tokenCache[neighbors[MaxNeighbors * c + 0]] + tokenCache[neighbors[MaxNeighbors * c + 1]]) >> 1;
|
||||
}
|
||||
|
||||
private static int ReadCoeff(
|
||||
|
@ -57,13 +57,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
int band, c = 0;
|
||||
ref Array6<Array6<Array3<byte>>> coefProbs = ref fc.CoefProbs[(int)txSize][(int)type][refr];
|
||||
Span<byte> tokenCache = stackalloc byte[32 * 32];
|
||||
ReadOnlySpan<byte> bandTranslate = Luts.get_band_translate(txSize);
|
||||
ReadOnlySpan<byte> bandTranslate = Luts.GetBandTranslate(txSize);
|
||||
int dqShift = (txSize == TxSize.Tx32x32) ? 1 : 0;
|
||||
int v;
|
||||
short dqv = dq[0];
|
||||
ReadOnlySpan<byte> cat6Prob = (xd.Bd == 12)
|
||||
? Luts.Vp9Cat6ProbHigh12
|
||||
: (xd.Bd == 10) ? Luts.Vp9Cat6ProbHigh12.Slice(2) : Luts.Vp9Cat6Prob;
|
||||
: (xd.Bd == 10) ? Luts.Vp9Cat6ProbHigh12[2..] : Luts.Vp9Cat6Prob;
|
||||
int cat6Bits = (xd.Bd == 12) ? 18 : (xd.Bd == 10) ? 16 : 14;
|
||||
// Keep value, range, and count as locals. The compiler produces better
|
||||
// results with the locals than using r directly.
|
||||
|
@ -75,7 +75,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
int val = -1;
|
||||
band = bandTranslate[0];
|
||||
bandTranslate = bandTranslate.Slice(1);
|
||||
bandTranslate = bandTranslate[1..];
|
||||
ref Array3<byte> prob = ref coefProbs[band][ctx];
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
|
@ -107,11 +107,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
r.Value = value;
|
||||
r.Range = range;
|
||||
r.Count = count;
|
||||
return c; // Zero tokens at the end (no eob token)
|
||||
|
||||
return c; // Zero tokens at the end (no eob token)
|
||||
}
|
||||
ctx = GetCoefContext(nb, tokenCache, c);
|
||||
band = bandTranslate[0];
|
||||
bandTranslate = bandTranslate.Slice(1);
|
||||
bandTranslate = bandTranslate[1..];
|
||||
prob = ref coefProbs[band][ctx];
|
||||
}
|
||||
|
||||
|
@ -196,6 +197,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
r.Value = value;
|
||||
r.Range = range;
|
||||
r.Count = count;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -236,8 +238,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
ref MacroBlockDPlane pd = ref xd.Plane[plane];
|
||||
ref Array2<short> dequant = ref pd.SegDequant[segId];
|
||||
int eob;
|
||||
Span<sbyte> a = pd.AboveContext.AsSpan().Slice(x);
|
||||
Span<sbyte> l = pd.LeftContext.AsSpan().Slice(y);
|
||||
Span<sbyte> a = pd.AboveContext.AsSpan()[x..];
|
||||
Span<sbyte> l = pd.LeftContext.AsSpan()[y..];
|
||||
int ctx;
|
||||
int ctxShiftA = 0;
|
||||
int ctxShiftL = 0;
|
||||
|
|
|
@ -117,6 +117,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
if (Sse41.IsSupported && UseIntrinsics && xStepQ4 == 1 << SubpelBits)
|
||||
{
|
||||
ConvolveHorizSse41(src, srcStride, dst, dstStride, xFilters, x0Q4, w, h);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -261,6 +262,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
if (Avx2.IsSupported && UseIntrinsics && yStepQ4 == 1 << SubpelBits)
|
||||
{
|
||||
ConvolveVertAvx2(src, srcStride, dst, dstStride, yFilters, y0Q4, w, h);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -776,7 +778,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Debug.Assert(yStepQ4 <= 32);
|
||||
Debug.Assert(xStepQ4 <= 32);
|
||||
|
||||
HighbdConvolveHoriz(src - srcStride * (SubpelTaps / 2 - 1), srcStride, temp, 64, filter, x0Q4, xStepQ4, w, intermediateHeight, bd);
|
||||
HighbdConvolveHoriz(src - srcStride * (SubpelTaps / 2 - 1), srcStride, temp, 64, filter, x0Q4, xStepQ4, w, intermediateHeight, bd);
|
||||
HighbdConvolveVert(temp + 64 * (SubpelTaps / 2 - 1), 64, dst, dstStride, filter, y0Q4, yStepQ4, w, h, bd);
|
||||
}
|
||||
|
||||
|
@ -811,7 +813,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
int h,
|
||||
int bd)
|
||||
{
|
||||
HighbdConvolveAvgHoriz(src, srcStride, dst, dstStride, filter, x0Q4, xStepQ4, w, h, bd);
|
||||
HighbdConvolveAvgHoriz(src, srcStride, dst, dstStride, filter, x0Q4, xStepQ4, w, h, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdConvolve8Vert(
|
||||
|
|
|
@ -227,7 +227,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
private static unsafe void D135Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int i;
|
||||
byte* border = stackalloc byte[32 + 32 - 1]; // outer border from bottom-left to top-right
|
||||
byte* border = stackalloc byte[32 + 32 - 1]; // outer border from bottom-left to top-right
|
||||
|
||||
// Dst(dst, stride, bs, bs - 2)[0], i.e., border starting at bottom-left
|
||||
for (i = 0; i < bs - 2; ++i)
|
||||
|
@ -607,13 +607,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 0, 2) = Avg2(b, c);
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 1, 2) = Avg2(c, d);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 2, 2) = Avg2(d, e);
|
||||
Dst(dst, stride, 3, 2) = Avg2(e, f); // Differs from vp8
|
||||
Dst(dst, stride, 3, 2) = Avg2(e, f); // Differs from vp8
|
||||
|
||||
Dst(dst, stride, 0, 1) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 3) = Avg3(b, c, d);
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 3) = Avg3(c, d, e);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 3) = Avg3(e, f, g); // Differs from vp8
|
||||
Dst(dst, stride, 3, 3) = Avg3(e, f, g); // Differs from vp8
|
||||
}
|
||||
|
||||
public static unsafe void D63ePredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
|
@ -655,7 +655,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 3) = Avg3(e, f, g);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 3) = Avg3(f, g, h);
|
||||
Dst(dst, stride, 3, 3) = h; // differs from vp8
|
||||
Dst(dst, stride, 3, 3) = h; // differs from vp8
|
||||
}
|
||||
|
||||
public static unsafe void D45ePredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
|
@ -935,7 +935,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
private static unsafe void HighbdD135Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
int i;
|
||||
ushort* border = stackalloc ushort[32 + 32 - 1]; // Outer border from bottom-left to top-right
|
||||
ushort* border = stackalloc ushort[32 + 32 - 1]; // Outer border from bottom-left to top-right
|
||||
|
||||
// Dst(dst, stride, bs, bs - 2)[0], i.e., border starting at bottom-left
|
||||
for (i = 0; i < bs - 2; ++i)
|
||||
|
@ -1281,13 +1281,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 0, 2) = Avg2(b, c);
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 1, 2) = Avg2(c, d);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 2, 2) = Avg2(d, e);
|
||||
Dst(dst, stride, 3, 2) = Avg2(e, f); // Differs from vp8
|
||||
Dst(dst, stride, 3, 2) = Avg2(e, f); // Differs from vp8
|
||||
|
||||
Dst(dst, stride, 0, 1) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 3) = Avg3(b, c, d);
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 3) = Avg3(c, d, e);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 3) = Avg3(e, f, g); // Differs from vp8
|
||||
Dst(dst, stride, 3, 3) = Avg3(e, f, g); // Differs from vp8
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD45Predictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
|
@ -1306,7 +1306,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 3) = Avg3(e, f, g);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 3) = Avg3(f, g, h);
|
||||
Dst(dst, stride, 3, 3) = h; // Differs from vp8
|
||||
Dst(dst, stride, 3, 3) = h; // Differs from vp8
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD117Predictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
// of this range for invalid/corrupt VP9 streams.
|
||||
Debug.Assert(short.MinValue <= input);
|
||||
Debug.Assert(input <= short.MaxValue);
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
|
@ -70,6 +71,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
public static byte ClipPixelAdd(byte dest, long trans)
|
||||
{
|
||||
trans = WrapLow(trans);
|
||||
|
||||
return BitUtils.ClipPixel(dest + (int)trans);
|
||||
}
|
||||
|
||||
|
@ -77,6 +79,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
public static ushort HighbdClipPixelAdd(ushort dest, long trans, int bd)
|
||||
{
|
||||
trans = HighbdWrapLow(trans, bd);
|
||||
|
||||
return BitUtils.ClipPixelHighbd(dest + (int)trans, bd);
|
||||
}
|
||||
|
||||
|
@ -84,6 +87,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
private static long DctConstRoundShift(long input)
|
||||
{
|
||||
long rv = BitUtils.RoundPowerOfTwo(input, DctConstBits);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -115,8 +119,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
op[1] = WrapLow(b1);
|
||||
op[2] = WrapLow(c1);
|
||||
op[3] = WrapLow(d1);
|
||||
ip = ip.Slice(4);
|
||||
op = op.Slice(4);
|
||||
ip = ip[4..];
|
||||
op = op[4..];
|
||||
}
|
||||
|
||||
Span<int> ip2 = output;
|
||||
|
@ -138,8 +142,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[stride * 2] = ClipPixelAdd(dest[stride * 2], WrapLow(c1));
|
||||
dest[stride * 3] = ClipPixelAdd(dest[stride * 3], WrapLow(d1));
|
||||
|
||||
ip2 = ip2.Slice(1);
|
||||
dest = dest.Slice(1);
|
||||
ip2 = ip2[1..];
|
||||
dest = dest[1..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,8 +171,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[stride * 1] = ClipPixelAdd(dest[stride * 1], e1);
|
||||
dest[stride * 2] = ClipPixelAdd(dest[stride * 2], e1);
|
||||
dest[stride * 3] = ClipPixelAdd(dest[stride * 3], e1);
|
||||
ip2 = ip2.Slice(1);
|
||||
dest = dest.Slice(1);
|
||||
ip2 = ip2[1..];
|
||||
dest = dest[1..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,7 +186,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
|
||||
if ((x0 | x1 | x2 | x3) == 0)
|
||||
{
|
||||
output.Slice(0, 4).Fill(0);
|
||||
output[..4].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -247,8 +252,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
Idct4(input, outptr);
|
||||
input = input.Slice(4);
|
||||
outptr = outptr.Slice(4);
|
||||
input = input[4..];
|
||||
outptr = outptr[4..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
|
@ -282,7 +287,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[1] = ClipPixelAdd(dest[1], a1);
|
||||
dest[2] = ClipPixelAdd(dest[2], a1);
|
||||
dest[3] = ClipPixelAdd(dest[3], a1);
|
||||
dest = dest.Slice(stride);
|
||||
dest = dest[stride..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,7 +305,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
|
||||
if ((x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7) == 0)
|
||||
{
|
||||
output.Slice(0, 8).Fill(0);
|
||||
output[..8].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -434,8 +440,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
Idct8(input, outptr);
|
||||
input = input.Slice(8);
|
||||
outptr = outptr.Slice(8);
|
||||
input = input[8..];
|
||||
outptr = outptr[8..];
|
||||
}
|
||||
|
||||
// Then transform columns
|
||||
|
@ -464,15 +470,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Span<int> tempIn = stackalloc int[8];
|
||||
Span<int> tempOut = stackalloc int[8];
|
||||
|
||||
output.Fill(0);
|
||||
output.Clear();
|
||||
|
||||
// First transform rows
|
||||
// Only first 4 row has non-zero coefs
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
Idct8(input, outptr);
|
||||
input = input.Slice(8);
|
||||
outptr = outptr.Slice(8);
|
||||
input = input[8..];
|
||||
outptr = outptr[8..];
|
||||
}
|
||||
|
||||
// Then transform columns
|
||||
|
@ -506,7 +512,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[i] = ClipPixelAdd(dest[i], a1);
|
||||
}
|
||||
|
||||
dest = dest.Slice(stride);
|
||||
dest = dest[stride..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -533,7 +539,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
|
||||
if ((x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15) == 0)
|
||||
{
|
||||
output.Slice(0, 16).Fill(0);
|
||||
output[..16].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -860,8 +867,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
Idct16(input, outptr);
|
||||
input = input.Slice(16);
|
||||
outptr = outptr.Slice(16);
|
||||
input = input[16..];
|
||||
outptr = outptr[16..];
|
||||
}
|
||||
|
||||
// Then transform columns
|
||||
|
@ -889,15 +896,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
|
||||
output.Fill(0);
|
||||
output.Clear();
|
||||
|
||||
// First transform rows. Since all non-zero dct coefficients are in
|
||||
// upper-left 8x8 area, we only need to calculate first 8 rows here.
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
Idct16(input, outptr);
|
||||
input = input.Slice(16);
|
||||
outptr = outptr.Slice(16);
|
||||
input = input[16..];
|
||||
outptr = outptr[16..];
|
||||
}
|
||||
|
||||
// Then transform columns
|
||||
|
@ -925,15 +932,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
|
||||
output.Fill(0);
|
||||
output.Clear();
|
||||
|
||||
// First transform rows. Since all non-zero dct coefficients are in
|
||||
// upper-left 4x4 area, we only need to calculate first 4 rows here.
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
Idct16(input, outptr);
|
||||
input = input.Slice(16);
|
||||
outptr = outptr.Slice(16);
|
||||
input = input[16..];
|
||||
outptr = outptr[16..];
|
||||
}
|
||||
|
||||
// Then transform columns
|
||||
|
@ -967,7 +974,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[i] = ClipPixelAdd(dest[i], a1);
|
||||
}
|
||||
|
||||
dest = dest.Slice(stride);
|
||||
dest = dest[stride..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1365,11 +1372,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
}
|
||||
else
|
||||
{
|
||||
outptr.Slice(0, 32).Fill(0);
|
||||
outptr[..32].Clear();
|
||||
}
|
||||
|
||||
input = input.Slice(32);
|
||||
outptr = outptr.Slice(32);
|
||||
input = input[32..];
|
||||
outptr = outptr[32..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
|
@ -1397,15 +1404,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Span<int> tempIn = stackalloc int[32];
|
||||
Span<int> tempOut = stackalloc int[32];
|
||||
|
||||
output.Fill(0);
|
||||
output.Clear();
|
||||
|
||||
// Rows
|
||||
// Only upper-left 16x16 has non-zero coeff
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
Idct32(input, outptr);
|
||||
input = input.Slice(32);
|
||||
outptr = outptr.Slice(32);
|
||||
input = input[32..];
|
||||
outptr = outptr[32..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
|
@ -1433,15 +1440,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Span<int> tempIn = stackalloc int[32];
|
||||
Span<int> tempOut = stackalloc int[32];
|
||||
|
||||
output.Fill(0);
|
||||
output.Clear();
|
||||
|
||||
// Rows
|
||||
// Only upper-left 8x8 has non-zero coeff
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
Idct32(input, outptr);
|
||||
input = input.Slice(32);
|
||||
outptr = outptr.Slice(32);
|
||||
input = input[32..];
|
||||
outptr = outptr[32..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
|
@ -1476,7 +1483,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[i] = ClipPixelAdd(dest[i], a1);
|
||||
}
|
||||
|
||||
dest = dest.Slice(stride);
|
||||
dest = dest[stride..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1508,8 +1515,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
op[1] = HighbdWrapLow(b1, bd);
|
||||
op[2] = HighbdWrapLow(c1, bd);
|
||||
op[3] = HighbdWrapLow(d1, bd);
|
||||
ip = ip.Slice(4);
|
||||
op = op.Slice(4);
|
||||
ip = ip[4..];
|
||||
op = op[4..];
|
||||
}
|
||||
|
||||
ReadOnlySpan<int> ip2 = output;
|
||||
|
@ -1531,8 +1538,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[stride * 2] = HighbdClipPixelAdd(dest[stride * 2], HighbdWrapLow(c1, bd), bd);
|
||||
dest[stride * 3] = HighbdClipPixelAdd(dest[stride * 3], HighbdWrapLow(d1, bd), bd);
|
||||
|
||||
ip2 = ip2.Slice(1);
|
||||
dest = dest.Slice(1);
|
||||
ip2 = ip2[1..];
|
||||
dest = dest[1..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1560,8 +1567,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[stride * 1] = HighbdClipPixelAdd(dest[stride * 1], e1, bd);
|
||||
dest[stride * 2] = HighbdClipPixelAdd(dest[stride * 2], e1, bd);
|
||||
dest[stride * 3] = HighbdClipPixelAdd(dest[stride * 3], e1, bd);
|
||||
ip2 = ip2.Slice(1);
|
||||
dest = dest.Slice(1);
|
||||
ip2 = ip2[1..];
|
||||
dest = dest[1..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1576,13 +1583,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
if (DetectInvalidHighbdInput(input, 4) != 0)
|
||||
{
|
||||
Debug.Assert(false, "invalid highbd txfm input");
|
||||
output.Slice(0, 4).Fill(0);
|
||||
output[..4].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((x0 | x1 | x2 | x3) == 0)
|
||||
{
|
||||
output.Slice(0, 4).Fill(0);
|
||||
output[..4].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1619,7 +1628,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
if (DetectInvalidHighbdInput(input, 4) != 0)
|
||||
{
|
||||
Debug.Assert(false, "invalid highbd txfm input");
|
||||
output.Slice(0, 4).Fill(0);
|
||||
output[..4].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1653,8 +1663,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
HighbdIdct4(input, outptr, bd);
|
||||
input = input.Slice(4);
|
||||
outptr = outptr.Slice(4);
|
||||
input = input[4..];
|
||||
outptr = outptr[4..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
|
@ -1688,7 +1698,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[1] = HighbdClipPixelAdd(dest[1], a1, bd);
|
||||
dest[2] = HighbdClipPixelAdd(dest[2], a1, bd);
|
||||
dest[3] = HighbdClipPixelAdd(dest[3], a1, bd);
|
||||
dest = dest.Slice(stride);
|
||||
dest = dest[stride..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1707,13 +1717,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
if (DetectInvalidHighbdInput(input, 8) != 0)
|
||||
{
|
||||
Debug.Assert(false, "invalid highbd txfm input");
|
||||
output.Slice(0, 8).Fill(0);
|
||||
output[..8].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7) == 0)
|
||||
{
|
||||
output.Slice(0, 8).Fill(0);
|
||||
output[..8].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1786,7 +1798,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
if (DetectInvalidHighbdInput(input, 8) != 0)
|
||||
{
|
||||
Debug.Assert(false, "invalid highbd txfm input");
|
||||
output.Slice(0, 8).Fill(0);
|
||||
output[..8].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1845,8 +1858,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
HighbdIdct8(input, outptr, bd);
|
||||
input = input.Slice(8);
|
||||
outptr = outptr.Slice(8);
|
||||
input = input[8..];
|
||||
outptr = outptr[8..];
|
||||
}
|
||||
|
||||
// Then transform columns
|
||||
|
@ -1874,15 +1887,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Span<int> tempIn = stackalloc int[8];
|
||||
Span<int> tempOut = stackalloc int[8];
|
||||
|
||||
output.Fill(0);
|
||||
output.Clear();
|
||||
|
||||
// First transform rows
|
||||
// Only first 4 row has non-zero coefs
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
HighbdIdct8(input, outptr, bd);
|
||||
input = input.Slice(8);
|
||||
outptr = outptr.Slice(8);
|
||||
input = input[8..];
|
||||
outptr = outptr[8..];
|
||||
}
|
||||
|
||||
// Then transform columns
|
||||
|
@ -1901,7 +1914,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
}
|
||||
}
|
||||
|
||||
public static void vpx_Highbdidct8x8_1_add_c(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void Vpx_Highbdidct8x8_1_add_c(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
int i, j;
|
||||
long a1;
|
||||
|
@ -1916,7 +1929,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[i] = HighbdClipPixelAdd(dest[i], a1, bd);
|
||||
}
|
||||
|
||||
dest = dest.Slice(stride);
|
||||
dest = dest[stride..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1940,16 +1953,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
int x13 = input[12];
|
||||
int x14 = input[1];
|
||||
int x15 = input[14];
|
||||
|
||||
if (DetectInvalidHighbdInput(input, 16) != 0)
|
||||
{
|
||||
Debug.Assert(false, "invalid highbd txfm input");
|
||||
output.Slice(0, 16).Fill(0);
|
||||
output[..16].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15) == 0)
|
||||
{
|
||||
output.Slice(0, 16).Fill(0);
|
||||
output[..16].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2105,7 +2121,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
if (DetectInvalidHighbdInput(input, 16) != 0)
|
||||
{
|
||||
Debug.Assert(false, "invalid highbd txfm input");
|
||||
output.Slice(0, 16).Fill(0);
|
||||
output[..16].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2283,8 +2300,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
HighbdIdct16(input, outptr, bd);
|
||||
input = input.Slice(16);
|
||||
outptr = outptr.Slice(16);
|
||||
input = input[16..];
|
||||
outptr = outptr[16..];
|
||||
}
|
||||
|
||||
// Then transform columns
|
||||
|
@ -2312,15 +2329,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
|
||||
output.Fill(0);
|
||||
output.Clear();
|
||||
|
||||
// First transform rows. Since all non-zero dct coefficients are in
|
||||
// upper-left 8x8 area, we only need to calculate first 8 rows here.
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
HighbdIdct16(input, outptr, bd);
|
||||
input = input.Slice(16);
|
||||
outptr = outptr.Slice(16);
|
||||
input = input[16..];
|
||||
outptr = outptr[16..];
|
||||
}
|
||||
|
||||
// Then transform columns
|
||||
|
@ -2336,7 +2353,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
for (j = 0; j < 16; ++j)
|
||||
{
|
||||
destT[i] = HighbdClipPixelAdd(destT[i], BitUtils.RoundPowerOfTwo(tempOut[j], 6), bd);
|
||||
destT = destT.Slice(stride);
|
||||
destT = destT[stride..];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2350,15 +2367,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
|
||||
output.Fill(0);
|
||||
output.Clear();
|
||||
|
||||
// First transform rows. Since all non-zero dct coefficients are in
|
||||
// upper-left 4x4 area, we only need to calculate first 4 rows here.
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
HighbdIdct16(input, outptr, bd);
|
||||
input = input.Slice(16);
|
||||
outptr = outptr.Slice(16);
|
||||
input = input[16..];
|
||||
outptr = outptr[16..];
|
||||
}
|
||||
|
||||
// Then transform columns
|
||||
|
@ -2392,7 +2409,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[i] = HighbdClipPixelAdd(dest[i], a1, bd);
|
||||
}
|
||||
|
||||
dest = dest.Slice(stride);
|
||||
dest = dest[stride..];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2406,7 +2423,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
if (DetectInvalidHighbdInput(input, 32) != 0)
|
||||
{
|
||||
Debug.Assert(false, "invalid highbd txfm input");
|
||||
output.Slice(0, 32).Fill(0);
|
||||
output[..32].Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2797,11 +2815,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
}
|
||||
else
|
||||
{
|
||||
outptr.Slice(0, 32).Fill(0);
|
||||
outptr[..32].Clear();
|
||||
}
|
||||
|
||||
input = input.Slice(32);
|
||||
outptr = outptr.Slice(32);
|
||||
input = input[32..];
|
||||
outptr = outptr[32..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
|
@ -2829,15 +2847,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Span<int> tempIn = stackalloc int[32];
|
||||
Span<int> tempOut = stackalloc int[32];
|
||||
|
||||
output.Fill(0);
|
||||
output.Clear();
|
||||
|
||||
// Rows
|
||||
// Only upper-left 16x16 has non-zero coeff
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
HighbdIdct32(input, outptr, bd);
|
||||
input = input.Slice(32);
|
||||
outptr = outptr.Slice(32);
|
||||
input = input[32..];
|
||||
outptr = outptr[32..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
|
@ -2853,7 +2871,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
for (j = 0; j < 32; ++j)
|
||||
{
|
||||
destT[i] = HighbdClipPixelAdd(destT[i], BitUtils.RoundPowerOfTwo(tempOut[j], 6), bd);
|
||||
destT = destT.Slice(stride);
|
||||
destT = destT[stride..];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2867,15 +2885,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Span<int> tempIn = stackalloc int[32];
|
||||
Span<int> tempOut = stackalloc int[32];
|
||||
|
||||
output.Fill(0);
|
||||
output.Clear();
|
||||
|
||||
// Rows
|
||||
// Only upper-left 8x8 has non-zero coeff
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
HighbdIdct32(input, outptr, bd);
|
||||
input = input.Slice(32);
|
||||
outptr = outptr.Slice(32);
|
||||
input = input[32..];
|
||||
outptr = outptr[32..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
|
@ -2910,7 +2928,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
dest[i] = HighbdClipPixelAdd(dest[i], a1, bd);
|
||||
}
|
||||
|
||||
dest = dest.Slice(stride);
|
||||
dest = dest[stride..];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
int p = (int)(((ulong)num * 256 + (den >> 1)) / den);
|
||||
// (p > 255) ? 255 : (p < 1) ? 1 : p;
|
||||
int clippedProb = p | ((255 - p) >> 23) | (p == 0 ? 1 : 0);
|
||||
|
||||
return (byte)clippedProb;
|
||||
}
|
||||
}
|
||||
|
@ -26,10 +27,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
}
|
||||
|
||||
// MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT;
|
||||
private static readonly uint[] CountToUpdateFactor = new uint[]
|
||||
{
|
||||
private static readonly uint[] _countToUpdateFactor = {
|
||||
0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64,
|
||||
70, 76, 83, 89, 96, 102, 108, 115, 121, 128
|
||||
70, 76, 83, 89, 96, 102, 108, 115, 121, 128,
|
||||
};
|
||||
|
||||
private const int ModeMvCountSat = 20;
|
||||
|
@ -44,8 +44,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
else
|
||||
{
|
||||
uint count = Math.Min(den, ModeMvCountSat);
|
||||
uint factor = CountToUpdateFactor[(int)count];
|
||||
uint factor = _countToUpdateFactor[(int)count];
|
||||
byte prob = GetProb(ct0, den);
|
||||
|
||||
return WeightedProb(preProb, prob, (int)factor);
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +63,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
int r = tree[i + 1];
|
||||
uint rightCount = (r <= 0) ? counts[-r] : TreeMergeProbsImpl((uint)r, tree, preProbs, counts, probs);
|
||||
probs[(int)(i >> 1)] = ModeMvMergeProbs(preProbs[(int)(i >> 1)], leftCount, rightCount);
|
||||
|
||||
return leftCount + rightCount;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
{
|
||||
internal struct Reader
|
||||
{
|
||||
private static readonly byte[] Norm = new byte[]
|
||||
{
|
||||
private static readonly byte[] _norm = {
|
||||
0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
|
@ -17,7 +16,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
private const int BdValueSize = sizeof(ulong) * 8;
|
||||
|
||||
|
@ -44,7 +43,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Count = -8;
|
||||
Range = 255;
|
||||
Fill();
|
||||
return ReadBit() != 0; // Marker bit
|
||||
|
||||
return ReadBit() != 0; // Marker bit
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
ulong bigEndianValues = BinaryPrimitives.ReadUInt64BigEndian(buffer);
|
||||
nv = bigEndianValues >> (BdValueSize - bits);
|
||||
count += bits;
|
||||
buffer = buffer.Slice(bits >> 3);
|
||||
buffer = buffer[(bits >> 3)..];
|
||||
value = Value | (nv << (shift & 0x7));
|
||||
}
|
||||
else
|
||||
|
@ -84,7 +84,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
{
|
||||
count += 8;
|
||||
value |= (ulong)buffer[0] << shift;
|
||||
buffer = buffer.Slice(1);
|
||||
buffer = buffer[1..];
|
||||
shift -= 8;
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
Count = count;
|
||||
}
|
||||
|
||||
public bool HasError()
|
||||
public readonly bool HasError()
|
||||
{
|
||||
// Check if we have reached the end of the buffer.
|
||||
//
|
||||
|
@ -146,7 +146,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
}
|
||||
|
||||
{
|
||||
int shift = Norm[range];
|
||||
int shift = _norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
|
@ -160,7 +160,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
|
||||
public int ReadBit()
|
||||
{
|
||||
return Read(128); // vpx_prob_half
|
||||
return Read(128); // vpx_prob_half
|
||||
}
|
||||
|
||||
public int ReadLiteral(int bits)
|
||||
|
@ -181,7 +181,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
|
||||
while ((i = tree[i + Read(probs[i >> 1])]) > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return -i;
|
||||
|
@ -203,10 +202,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
|
||||
if (value >= bigsplit)
|
||||
{
|
||||
range = range - split;
|
||||
value = value - bigsplit;
|
||||
range -= split;
|
||||
value -= bigsplit;
|
||||
{
|
||||
int shift = Norm[range];
|
||||
int shift = _norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
|
@ -215,7 +214,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
|||
}
|
||||
range = split;
|
||||
{
|
||||
int shift = Norm[range];
|
||||
int shift = _norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
private struct Transform2D
|
||||
{
|
||||
public Transform1D Cols, Rows; // Vertical and horizontal
|
||||
public Transform1D Cols, Rows; // Vertical and horizontal
|
||||
|
||||
public Transform2D(Transform1D cols, Transform1D rows)
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
private struct HighbdTransform2D
|
||||
{
|
||||
public HighbdTransform1D Cols, Rows; // Vertical and horizontal
|
||||
public HighbdTransform1D Cols, Rows; // Vertical and horizontal
|
||||
|
||||
public HighbdTransform2D(HighbdTransform1D cols, HighbdTransform1D rows)
|
||||
{
|
||||
|
@ -32,12 +32,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] Iht4 = new Transform2D[]
|
||||
{
|
||||
new Transform2D(Idct4, Idct4), // DCT_DCT = 0
|
||||
new Transform2D(Iadst4, Idct4), // ADST_DCT = 1
|
||||
new Transform2D(Idct4, Iadst4), // DCT_ADST = 2
|
||||
new Transform2D(Iadst4, Iadst4) // ADST_ADST = 3
|
||||
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)
|
||||
|
@ -51,9 +50,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// Inverse transform row vectors
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
Iht4[txType].Rows(input, outptr);
|
||||
input = input.Slice(4);
|
||||
outptr = outptr.Slice(4);
|
||||
_iht4[txType].Rows(input, outptr);
|
||||
input = input[4..];
|
||||
outptr = outptr[4..];
|
||||
}
|
||||
|
||||
// Inverse transform column vectors
|
||||
|
@ -64,7 +63,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
tempIn[j] = output[j * 4 + i];
|
||||
}
|
||||
|
||||
Iht4[txType].Cols(tempIn, tempOut);
|
||||
_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));
|
||||
|
@ -72,12 +71,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] Iht8 = new Transform2D[]
|
||||
{
|
||||
new Transform2D(Idct8, Idct8), // DCT_DCT = 0
|
||||
new Transform2D(Iadst8, Idct8), // ADST_DCT = 1
|
||||
new Transform2D(Idct8, Iadst8), // DCT_ADST = 2
|
||||
new Transform2D(Iadst8, Iadst8) // ADST_ADST = 3
|
||||
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)
|
||||
|
@ -87,14 +85,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[8];
|
||||
Span<int> tempOut = stackalloc int[8];
|
||||
Transform2D ht = Iht8[txType];
|
||||
Transform2D ht = _iht8[txType];
|
||||
|
||||
// Inverse transform row vectors
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr);
|
||||
input = input.Slice(8);
|
||||
outptr = outptr.Slice(8);
|
||||
input = input[8..];
|
||||
outptr = outptr[8..];
|
||||
}
|
||||
|
||||
// Inverse transform column vectors
|
||||
|
@ -113,12 +111,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] Iht16 = new Transform2D[]
|
||||
{
|
||||
new Transform2D(Idct16, Idct16), // DCT_DCT = 0
|
||||
new Transform2D(Iadst16, Idct16), // ADST_DCT = 1
|
||||
new Transform2D(Idct16, Iadst16), // DCT_ADST = 2
|
||||
new Transform2D(Iadst16, Iadst16) // ADST_ADST = 3
|
||||
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)
|
||||
|
@ -128,14 +125,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
Transform2D ht = Iht16[txType];
|
||||
Transform2D ht = _iht16[txType];
|
||||
|
||||
// Rows
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr);
|
||||
input = input.Slice(16);
|
||||
outptr = outptr.Slice(16);
|
||||
input = input[16..];
|
||||
outptr = outptr[16..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
|
@ -283,12 +280,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] HighbdIht4 = new HighbdTransform2D[]
|
||||
{
|
||||
new HighbdTransform2D(HighbdIdct4, HighbdIdct4), // DCT_DCT = 0
|
||||
new HighbdTransform2D(HighbdIadst4, HighbdIdct4), // ADST_DCT = 1
|
||||
new HighbdTransform2D(HighbdIdct4, HighbdIadst4), // DCT_ADST = 2
|
||||
new HighbdTransform2D(HighbdIadst4, HighbdIadst4) // ADST_ADST = 3
|
||||
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)
|
||||
|
@ -302,9 +298,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// Inverse transform row vectors.
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
HighbdIht4[txType].Rows(input, outptr, bd);
|
||||
input = input.Slice(4);
|
||||
outptr = outptr.Slice(4);
|
||||
_highbdIht4[txType].Rows(input, outptr, bd);
|
||||
input = input[4..];
|
||||
outptr = outptr[4..];
|
||||
}
|
||||
|
||||
// Inverse transform column vectors.
|
||||
|
@ -315,7 +311,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
tempIn[j] = output[j * 4 + i];
|
||||
}
|
||||
|
||||
HighbdIht4[txType].Cols(tempIn, tempOut, bd);
|
||||
_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);
|
||||
|
@ -323,12 +319,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] HighIht8 = new HighbdTransform2D[]
|
||||
{
|
||||
new HighbdTransform2D(HighbdIdct8, HighbdIdct8), // DCT_DCT = 0
|
||||
new HighbdTransform2D(HighbdIadst8, HighbdIdct8), // ADST_DCT = 1
|
||||
new HighbdTransform2D(HighbdIdct8, HighbdIadst8), // DCT_ADST = 2
|
||||
new HighbdTransform2D(HighbdIadst8, HighbdIadst8) // ADST_ADST = 3
|
||||
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)
|
||||
|
@ -338,14 +333,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[8];
|
||||
Span<int> tempOut = stackalloc int[8];
|
||||
HighbdTransform2D ht = HighIht8[txType];
|
||||
HighbdTransform2D ht = _highIht8[txType];
|
||||
|
||||
// Inverse transform row vectors.
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr, bd);
|
||||
input = input.Slice(8);
|
||||
outptr = output.Slice(8);
|
||||
input = input[8..];
|
||||
outptr = output[8..];
|
||||
}
|
||||
|
||||
// Inverse transform column vectors.
|
||||
|
@ -364,12 +359,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] HighIht16 = new HighbdTransform2D[]
|
||||
{
|
||||
new HighbdTransform2D(HighbdIdct16, HighbdIdct16), // DCT_DCT = 0
|
||||
new HighbdTransform2D(HighbdIadst16, HighbdIdct16), // ADST_DCT = 1
|
||||
new HighbdTransform2D(HighbdIdct16, HighbdIadst16), // DCT_ADST = 2
|
||||
new HighbdTransform2D(HighbdIadst16, HighbdIadst16) // ADST_ADST = 3
|
||||
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)
|
||||
|
@ -379,14 +373,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
HighbdTransform2D ht = HighIht16[txType];
|
||||
HighbdTransform2D ht = _highIht16[txType];
|
||||
|
||||
// Rows
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr, bd);
|
||||
input = input.Slice(16);
|
||||
outptr = output.Slice(16);
|
||||
input = input[16..];
|
||||
outptr = output[16..];
|
||||
}
|
||||
|
||||
// Columns
|
||||
|
@ -440,7 +434,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// DC only DCT coefficient
|
||||
if (eob == 1)
|
||||
{
|
||||
vpx_Highbdidct8x8_1_add_c(input, dest, stride, bd);
|
||||
Vpx_Highbdidct8x8_1_add_c(input, dest, stride, bd);
|
||||
}
|
||||
else if (eob <= 12)
|
||||
{
|
||||
|
|
|
@ -30,12 +30,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// 10101010
|
||||
//
|
||||
// A loopfilter should be applied to every other 8x8 horizontally.
|
||||
private static readonly ulong[] Left64X64TxformMask = new ulong[]
|
||||
{
|
||||
0xffffffffffffffffUL, // TX_4X4
|
||||
0xffffffffffffffffUL, // TX_8x8
|
||||
0x5555555555555555UL, // TX_16x16
|
||||
0x1111111111111111UL, // TX_32x32
|
||||
private static readonly ulong[] _left64X64TxformMask = {
|
||||
0xffffffffffffffffUL, // TX_4X4
|
||||
0xffffffffffffffffUL, // TX_8x8
|
||||
0x5555555555555555UL, // TX_16x16
|
||||
0x1111111111111111UL, // TX_32x32
|
||||
};
|
||||
|
||||
// 64 bit masks for above transform size. Each 1 represents a position where
|
||||
|
@ -55,12 +54,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// 00000000
|
||||
//
|
||||
// A loopfilter should be applied to every other 4 the row vertically.
|
||||
private static readonly ulong[] Above64X64TxformMask = new ulong[]
|
||||
{
|
||||
0xffffffffffffffffUL, // TX_4X4
|
||||
0xffffffffffffffffUL, // TX_8x8
|
||||
0x00ff00ff00ff00ffUL, // TX_16x16
|
||||
0x000000ff000000ffUL, // TX_32x32
|
||||
private static readonly ulong[] _above64X64TxformMask = {
|
||||
0xffffffffffffffffUL, // TX_4X4
|
||||
0xffffffffffffffffUL, // TX_8x8
|
||||
0x00ff00ff00ff00ffUL, // TX_16x16
|
||||
0x000000ff000000ffUL, // TX_32x32
|
||||
};
|
||||
|
||||
// 64 bit masks for prediction sizes (left). Each 1 represents a position
|
||||
|
@ -78,148 +76,143 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// 00000000
|
||||
// 00000000
|
||||
// 00000000
|
||||
private static readonly ulong[] LeftPredictionMask = new ulong[]
|
||||
{
|
||||
0x0000000000000001UL, // BLOCK_4X4,
|
||||
0x0000000000000001UL, // BLOCK_4X8,
|
||||
0x0000000000000001UL, // BLOCK_8X4,
|
||||
0x0000000000000001UL, // BLOCK_8X8,
|
||||
0x0000000000000101UL, // BLOCK_8X16,
|
||||
0x0000000000000001UL, // BLOCK_16X8,
|
||||
0x0000000000000101UL, // BLOCK_16X16,
|
||||
0x0000000001010101UL, // BLOCK_16X32,
|
||||
0x0000000000000101UL, // BLOCK_32X16,
|
||||
0x0000000001010101UL, // BLOCK_32X32,
|
||||
0x0101010101010101UL, // BLOCK_32X64,
|
||||
0x0000000001010101UL, // BLOCK_64X32,
|
||||
0x0101010101010101UL, // BLOCK_64X64
|
||||
private static readonly ulong[] _leftPredictionMask = {
|
||||
0x0000000000000001UL, // BLOCK_4X4,
|
||||
0x0000000000000001UL, // BLOCK_4X8,
|
||||
0x0000000000000001UL, // BLOCK_8X4,
|
||||
0x0000000000000001UL, // BLOCK_8X8,
|
||||
0x0000000000000101UL, // BLOCK_8X16,
|
||||
0x0000000000000001UL, // BLOCK_16X8,
|
||||
0x0000000000000101UL, // BLOCK_16X16,
|
||||
0x0000000001010101UL, // BLOCK_16X32,
|
||||
0x0000000000000101UL, // BLOCK_32X16,
|
||||
0x0000000001010101UL, // BLOCK_32X32,
|
||||
0x0101010101010101UL, // BLOCK_32X64,
|
||||
0x0000000001010101UL, // BLOCK_64X32,
|
||||
0x0101010101010101UL, // BLOCK_64X64
|
||||
};
|
||||
|
||||
// 64 bit mask to shift and set for each prediction size.
|
||||
private static readonly ulong[] AbovePredictionMask = new ulong[]
|
||||
{
|
||||
0x0000000000000001UL, // BLOCK_4X4
|
||||
0x0000000000000001UL, // BLOCK_4X8
|
||||
0x0000000000000001UL, // BLOCK_8X4
|
||||
0x0000000000000001UL, // BLOCK_8X8
|
||||
0x0000000000000001UL, // BLOCK_8X16,
|
||||
0x0000000000000003UL, // BLOCK_16X8
|
||||
0x0000000000000003UL, // BLOCK_16X16
|
||||
0x0000000000000003UL, // BLOCK_16X32,
|
||||
0x000000000000000fUL, // BLOCK_32X16,
|
||||
0x000000000000000fUL, // BLOCK_32X32,
|
||||
0x000000000000000fUL, // BLOCK_32X64,
|
||||
0x00000000000000ffUL, // BLOCK_64X32,
|
||||
0x00000000000000ffUL, // BLOCK_64X64
|
||||
private static readonly ulong[] _abovePredictionMask = {
|
||||
0x0000000000000001UL, // BLOCK_4X4
|
||||
0x0000000000000001UL, // BLOCK_4X8
|
||||
0x0000000000000001UL, // BLOCK_8X4
|
||||
0x0000000000000001UL, // BLOCK_8X8
|
||||
0x0000000000000001UL, // BLOCK_8X16,
|
||||
0x0000000000000003UL, // BLOCK_16X8
|
||||
0x0000000000000003UL, // BLOCK_16X16
|
||||
0x0000000000000003UL, // BLOCK_16X32,
|
||||
0x000000000000000fUL, // BLOCK_32X16,
|
||||
0x000000000000000fUL, // BLOCK_32X32,
|
||||
0x000000000000000fUL, // BLOCK_32X64,
|
||||
0x00000000000000ffUL, // BLOCK_64X32,
|
||||
0x00000000000000ffUL, // BLOCK_64X64
|
||||
};
|
||||
|
||||
// 64 bit mask to shift and set for each prediction size. A bit is set for
|
||||
// each 8x8 block that would be in the left most block of the given block
|
||||
// size in the 64x64 block.
|
||||
private static readonly ulong[] SizeMask = new ulong[]
|
||||
{
|
||||
0x0000000000000001UL, // BLOCK_4X4
|
||||
0x0000000000000001UL, // BLOCK_4X8
|
||||
0x0000000000000001UL, // BLOCK_8X4
|
||||
0x0000000000000001UL, // BLOCK_8X8
|
||||
0x0000000000000101UL, // BLOCK_8X16,
|
||||
0x0000000000000003UL, // BLOCK_16X8
|
||||
0x0000000000000303UL, // BLOCK_16X16
|
||||
0x0000000003030303UL, // BLOCK_16X32,
|
||||
0x0000000000000f0fUL, // BLOCK_32X16,
|
||||
0x000000000f0f0f0fUL, // BLOCK_32X32,
|
||||
0x0f0f0f0f0f0f0f0fUL, // BLOCK_32X64,
|
||||
0x00000000ffffffffUL, // BLOCK_64X32,
|
||||
0xffffffffffffffffUL, // BLOCK_64X64
|
||||
private static readonly ulong[] _sizeMask = {
|
||||
0x0000000000000001UL, // BLOCK_4X4
|
||||
0x0000000000000001UL, // BLOCK_4X8
|
||||
0x0000000000000001UL, // BLOCK_8X4
|
||||
0x0000000000000001UL, // BLOCK_8X8
|
||||
0x0000000000000101UL, // BLOCK_8X16,
|
||||
0x0000000000000003UL, // BLOCK_16X8
|
||||
0x0000000000000303UL, // BLOCK_16X16
|
||||
0x0000000003030303UL, // BLOCK_16X32,
|
||||
0x0000000000000f0fUL, // BLOCK_32X16,
|
||||
0x000000000f0f0f0fUL, // BLOCK_32X32,
|
||||
0x0f0f0f0f0f0f0f0fUL, // BLOCK_32X64,
|
||||
0x00000000ffffffffUL, // BLOCK_64X32,
|
||||
0xffffffffffffffffUL, // BLOCK_64X64
|
||||
};
|
||||
|
||||
// These are used for masking the left and above borders.
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
private const ulong LeftBorder = 0x1111111111111111UL;
|
||||
private const ulong AboveBorder = 0x000000ff000000ffUL;
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
// 16 bit masks for uv transform sizes.
|
||||
private static readonly ushort[] Left64X64TxformMaskUv = new ushort[]
|
||||
{
|
||||
0xffff, // TX_4X4
|
||||
0xffff, // TX_8x8
|
||||
0x5555, // TX_16x16
|
||||
0x1111, // TX_32x32
|
||||
private static readonly ushort[] _left64X64TxformMaskUv = {
|
||||
0xffff, // TX_4X4
|
||||
0xffff, // TX_8x8
|
||||
0x5555, // TX_16x16
|
||||
0x1111, // TX_32x32
|
||||
};
|
||||
|
||||
private static readonly ushort[] Above64X64TxformMaskUv = new ushort[]
|
||||
{
|
||||
0xffff, // TX_4X4
|
||||
0xffff, // TX_8x8
|
||||
0x0f0f, // TX_16x16
|
||||
0x000f, // TX_32x32
|
||||
private static readonly ushort[] _above64X64TxformMaskUv = {
|
||||
0xffff, // TX_4X4
|
||||
0xffff, // TX_8x8
|
||||
0x0f0f, // TX_16x16
|
||||
0x000f, // TX_32x32
|
||||
};
|
||||
|
||||
// 16 bit left mask to shift and set for each uv prediction size.
|
||||
private static readonly ushort[] LeftPredictionMaskUv = new ushort[]
|
||||
{
|
||||
0x0001, // BLOCK_4X4,
|
||||
0x0001, // BLOCK_4X8,
|
||||
0x0001, // BLOCK_8X4,
|
||||
0x0001, // BLOCK_8X8,
|
||||
0x0001, // BLOCK_8X16,
|
||||
0x0001, // BLOCK_16X8,
|
||||
0x0001, // BLOCK_16X16,
|
||||
0x0011, // BLOCK_16X32,
|
||||
0x0001, // BLOCK_32X16,
|
||||
0x0011, // BLOCK_32X32,
|
||||
0x1111, // BLOCK_32X64
|
||||
0x0011, // BLOCK_64X32,
|
||||
0x1111, // BLOCK_64X64
|
||||
private static readonly ushort[] _leftPredictionMaskUv = {
|
||||
0x0001, // BLOCK_4X4,
|
||||
0x0001, // BLOCK_4X8,
|
||||
0x0001, // BLOCK_8X4,
|
||||
0x0001, // BLOCK_8X8,
|
||||
0x0001, // BLOCK_8X16,
|
||||
0x0001, // BLOCK_16X8,
|
||||
0x0001, // BLOCK_16X16,
|
||||
0x0011, // BLOCK_16X32,
|
||||
0x0001, // BLOCK_32X16,
|
||||
0x0011, // BLOCK_32X32,
|
||||
0x1111, // BLOCK_32X64
|
||||
0x0011, // BLOCK_64X32,
|
||||
0x1111, // BLOCK_64X64
|
||||
};
|
||||
|
||||
// 16 bit above mask to shift and set for uv each prediction size.
|
||||
private static readonly ushort[] AbovePredictionMaskUv = new ushort[]
|
||||
{
|
||||
0x0001, // BLOCK_4X4
|
||||
0x0001, // BLOCK_4X8
|
||||
0x0001, // BLOCK_8X4
|
||||
0x0001, // BLOCK_8X8
|
||||
0x0001, // BLOCK_8X16,
|
||||
0x0001, // BLOCK_16X8
|
||||
0x0001, // BLOCK_16X16
|
||||
0x0001, // BLOCK_16X32,
|
||||
0x0003, // BLOCK_32X16,
|
||||
0x0003, // BLOCK_32X32,
|
||||
0x0003, // BLOCK_32X64,
|
||||
0x000f, // BLOCK_64X32,
|
||||
0x000f, // BLOCK_64X64
|
||||
private static readonly ushort[] _abovePredictionMaskUv = {
|
||||
0x0001, // BLOCK_4X4
|
||||
0x0001, // BLOCK_4X8
|
||||
0x0001, // BLOCK_8X4
|
||||
0x0001, // BLOCK_8X8
|
||||
0x0001, // BLOCK_8X16,
|
||||
0x0001, // BLOCK_16X8
|
||||
0x0001, // BLOCK_16X16
|
||||
0x0001, // BLOCK_16X32,
|
||||
0x0003, // BLOCK_32X16,
|
||||
0x0003, // BLOCK_32X32,
|
||||
0x0003, // BLOCK_32X64,
|
||||
0x000f, // BLOCK_64X32,
|
||||
0x000f, // BLOCK_64X64
|
||||
};
|
||||
|
||||
// 64 bit mask to shift and set for each uv prediction size
|
||||
private static readonly ushort[] SizeMaskUv = new ushort[]
|
||||
{
|
||||
0x0001, // BLOCK_4X4
|
||||
0x0001, // BLOCK_4X8
|
||||
0x0001, // BLOCK_8X4
|
||||
0x0001, // BLOCK_8X8
|
||||
0x0001, // BLOCK_8X16,
|
||||
0x0001, // BLOCK_16X8
|
||||
0x0001, // BLOCK_16X16
|
||||
0x0011, // BLOCK_16X32,
|
||||
0x0003, // BLOCK_32X16,
|
||||
0x0033, // BLOCK_32X32,
|
||||
0x3333, // BLOCK_32X64,
|
||||
0x00ff, // BLOCK_64X32,
|
||||
0xffff, // BLOCK_64X64
|
||||
private static readonly ushort[] _sizeMaskUv = {
|
||||
0x0001, // BLOCK_4X4
|
||||
0x0001, // BLOCK_4X8
|
||||
0x0001, // BLOCK_8X4
|
||||
0x0001, // BLOCK_8X8
|
||||
0x0001, // BLOCK_8X16,
|
||||
0x0001, // BLOCK_16X8
|
||||
0x0001, // BLOCK_16X16
|
||||
0x0011, // BLOCK_16X32,
|
||||
0x0003, // BLOCK_32X16,
|
||||
0x0033, // BLOCK_32X32,
|
||||
0x3333, // BLOCK_32X64,
|
||||
0x00ff, // BLOCK_64X32,
|
||||
0xffff, // BLOCK_64X64
|
||||
};
|
||||
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
private const ushort LeftBorderUv = 0x1111;
|
||||
private const ushort AboveBorderUv = 0x000f;
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
private static readonly int[] ModeLfLut = new int[]
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // INTRA_MODES
|
||||
1, 1, 0, 1 // INTER_MODES (ZEROMV == 0)
|
||||
private static readonly int[] _modeLfLut = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // INTRA_MODES
|
||||
1, 1, 0, 1, // INTER_MODES (ZEROMV == 0)
|
||||
};
|
||||
|
||||
private static byte GetFilterLevel(ref LoopFilterInfoN lfiN, ref ModeInfo mi)
|
||||
{
|
||||
return lfiN.Lvl[mi.SegmentId][mi.RefFrame[0]][ModeLfLut[(int)mi.Mode]];
|
||||
return lfiN.Lvl[mi.SegmentId][mi.RefFrame[0]][_modeLfLut[(int)mi.Mode]];
|
||||
}
|
||||
|
||||
private static ref LoopFilterMask GetLfm(ref Types.LoopFilter lf, int miRow, int miCol)
|
||||
|
@ -229,12 +222,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
// 8x8 blocks in a superblock. A "1" represents the first block in a 16x16
|
||||
// or greater area.
|
||||
private static readonly byte[][] FirstBlockIn16x16 = new byte[][]
|
||||
{
|
||||
private static readonly byte[][] _firstBlockIn16X16 = {
|
||||
new byte[] { 1, 0, 1, 0, 1, 0, 1, 0 }, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
new byte[] { 1, 0, 1, 0, 1, 0, 1, 0 }, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
new byte[] { 1, 0, 1, 0, 1, 0, 1, 0 }, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
new byte[] { 1, 0, 1, 0, 1, 0, 1, 0 }, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
new byte[] { 1, 0, 1, 0, 1, 0, 1, 0 }, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
// This function sets up the bit masks for a block represented
|
||||
|
@ -257,21 +249,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
int colInSb = (miCol & 7);
|
||||
int shiftY = colInSb + (rowInSb << 3);
|
||||
int shiftUv = (colInSb >> 1) + ((rowInSb >> 1) << 2);
|
||||
int buildUv = FirstBlockIn16x16[rowInSb][colInSb];
|
||||
int buildUv = _firstBlockIn16X16[rowInSb][colInSb];
|
||||
|
||||
if (filterLevel == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
int index = shiftY;
|
||||
int i;
|
||||
for (i = 0; i < bh; i++)
|
||||
{
|
||||
int index = shiftY;
|
||||
int i;
|
||||
for (i = 0; i < bh; i++)
|
||||
{
|
||||
MemoryMarshal.CreateSpan(ref lfm.LflY[index], 64 - index).Slice(0, bw).Fill((byte)filterLevel);
|
||||
index += 8;
|
||||
}
|
||||
MemoryMarshal.CreateSpan(ref lfm.LflY[index], 64 - index)[..bw].Fill((byte)filterLevel);
|
||||
index += 8;
|
||||
}
|
||||
|
||||
// These set 1 in the current block size for the block size edges.
|
||||
|
@ -286,13 +276,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
//
|
||||
// U and V set things on a 16 bit scale.
|
||||
//
|
||||
aboveY |= AbovePredictionMask[(int)blockSize] << shiftY;
|
||||
leftY |= LeftPredictionMask[(int)blockSize] << shiftY;
|
||||
aboveY |= _abovePredictionMask[(int)blockSize] << shiftY;
|
||||
leftY |= _leftPredictionMask[(int)blockSize] << shiftY;
|
||||
|
||||
if (buildUv != 0)
|
||||
{
|
||||
aboveUv |= (ushort)(AbovePredictionMaskUv[(int)blockSize] << shiftUv);
|
||||
leftUv |= (ushort)(LeftPredictionMaskUv[(int)blockSize] << shiftUv);
|
||||
aboveUv |= (ushort)(_abovePredictionMaskUv[(int)blockSize] << shiftUv);
|
||||
leftUv |= (ushort)(_leftPredictionMaskUv[(int)blockSize] << shiftUv);
|
||||
}
|
||||
|
||||
// If the block has no coefficients and is not intra we skip applying
|
||||
|
@ -305,13 +295,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// Add a mask for the transform size. The transform size mask is set to
|
||||
// be correct for a 64x64 prediction block size. Mask to match the size of
|
||||
// the block we are working on and then shift it into place.
|
||||
aboveY |= (SizeMask[(int)blockSize] & Above64X64TxformMask[(int)txSizeY]) << shiftY;
|
||||
leftY |= (SizeMask[(int)blockSize] & Left64X64TxformMask[(int)txSizeY]) << shiftY;
|
||||
aboveY |= (_sizeMask[(int)blockSize] & _above64X64TxformMask[(int)txSizeY]) << shiftY;
|
||||
leftY |= (_sizeMask[(int)blockSize] & _left64X64TxformMask[(int)txSizeY]) << shiftY;
|
||||
|
||||
if (buildUv != 0)
|
||||
{
|
||||
aboveUv |= (ushort)((SizeMaskUv[(int)blockSize] & Above64X64TxformMaskUv[(int)txSizeUv]) << shiftUv);
|
||||
leftUv |= (ushort)((SizeMaskUv[(int)blockSize] & Left64X64TxformMaskUv[(int)txSizeUv]) << shiftUv);
|
||||
aboveUv |= (ushort)((_sizeMaskUv[(int)blockSize] & _above64X64TxformMaskUv[(int)txSizeUv]) << shiftUv);
|
||||
leftUv |= (ushort)((_sizeMaskUv[(int)blockSize] & _left64X64TxformMaskUv[(int)txSizeUv]) << shiftUv);
|
||||
}
|
||||
|
||||
// Try to determine what to do with the internal 4x4 block boundaries. These
|
||||
|
@ -319,12 +309,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// internal ones can be skipped and don't depend on the prediction block size.
|
||||
if (txSizeY == TxSize.Tx4x4)
|
||||
{
|
||||
int4X4Y |= SizeMask[(int)blockSize] << shiftY;
|
||||
int4X4Y |= _sizeMask[(int)blockSize] << shiftY;
|
||||
}
|
||||
|
||||
if (buildUv != 0 && txSizeUv == TxSize.Tx4x4)
|
||||
{
|
||||
int4X4Uv |= (ushort)((SizeMaskUv[(int)blockSize] & 0xffff) << shiftUv);
|
||||
int4X4Uv |= (ushort)((_sizeMaskUv[(int)blockSize] & 0xffff) << shiftUv);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// left of the entries corresponding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialized to 0.
|
||||
if (!xd.AboveMi.IsNull && !xd.LeftMi.IsNull)
|
||||
{ // both edges available
|
||||
{ // both edges available
|
||||
if (!xd.AboveMi.Value.HasSecondRef() && !xd.LeftMi.Value.HasSecondRef())
|
||||
{
|
||||
// Neither edge uses comp pred (0/1)
|
||||
|
@ -30,13 +30,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// One of two edges uses comp pred (2/3)
|
||||
ctx = 2 + (xd.LeftMi.Value.RefFrame[0] == cm.CompFixedRef || !xd.LeftMi.Value.IsInterBlock() ? 1 : 0);
|
||||
}
|
||||
else // Both edges use comp pred (4)
|
||||
else // Both edges use comp pred (4)
|
||||
{
|
||||
ctx = 4;
|
||||
}
|
||||
}
|
||||
else if (!xd.AboveMi.IsNull || !xd.LeftMi.IsNull)
|
||||
{ // One edge available
|
||||
{ // One edge available
|
||||
ref ModeInfo edgeMi = ref !xd.AboveMi.IsNull ? ref xd.AboveMi.Value : ref xd.LeftMi.Value;
|
||||
|
||||
if (!edgeMi.HasSecondRef())
|
||||
|
@ -51,10 +51,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else
|
||||
{ // No edges available (1)
|
||||
{ // No edges available (1)
|
||||
ctx = 1;
|
||||
}
|
||||
Debug.Assert(ctx >= 0 && ctx < Constants.CompInterContexts);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
@ -70,29 +71,29 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
int varRefIdx = fixRefIdx == 0 ? 1 : 0;
|
||||
|
||||
if (!xd.AboveMi.IsNull && !xd.LeftMi.IsNull)
|
||||
{ // Both edges available
|
||||
{ // Both edges available
|
||||
bool aboveIntra = !xd.AboveMi.Value.IsInterBlock();
|
||||
bool leftIntra = !xd.LeftMi.Value.IsInterBlock();
|
||||
|
||||
if (aboveIntra && leftIntra)
|
||||
{ // Intra/Intra (2)
|
||||
{ // Intra/Intra (2)
|
||||
predContext = 2;
|
||||
}
|
||||
else if (aboveIntra || leftIntra)
|
||||
{ // Intra/Inter
|
||||
{ // Intra/Inter
|
||||
ref ModeInfo edgeMi = ref aboveIntra ? ref xd.LeftMi.Value : ref xd.AboveMi.Value;
|
||||
|
||||
if (!edgeMi.HasSecondRef()) // single pred (1/3)
|
||||
if (!edgeMi.HasSecondRef()) // single pred (1/3)
|
||||
{
|
||||
predContext = 1 + 2 * (edgeMi.RefFrame[0] != cm.CompVarRef[1] ? 1 : 0);
|
||||
}
|
||||
else // Comp pred (1/3)
|
||||
else // Comp pred (1/3)
|
||||
{
|
||||
predContext = 1 + 2 * (edgeMi.RefFrame[varRefIdx] != cm.CompVarRef[1] ? 1 : 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Inter/Inter
|
||||
{ // Inter/Inter
|
||||
bool lSg = !xd.LeftMi.Value.HasSecondRef();
|
||||
bool aSg = !xd.AboveMi.Value.HasSecondRef();
|
||||
sbyte vrfa = aSg ? xd.AboveMi.Value.RefFrame[0] : xd.AboveMi.Value.RefFrame[varRefIdx];
|
||||
|
@ -103,7 +104,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
predContext = 0;
|
||||
}
|
||||
else if (lSg && aSg)
|
||||
{ // Single/Single
|
||||
{ // Single/Single
|
||||
if ((vrfa == cm.CompFixedRef && vrfl == cm.CompVarRef[0]) ||
|
||||
(vrfl == cm.CompFixedRef && vrfa == cm.CompVarRef[0]))
|
||||
{
|
||||
|
@ -119,7 +120,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else if (lSg || aSg)
|
||||
{ // Single/Comp
|
||||
{ // Single/Comp
|
||||
sbyte vrfc = lSg ? vrfa : vrfl;
|
||||
sbyte rfs = aSg ? vrfa : vrfl;
|
||||
if (vrfc == cm.CompVarRef[1] && rfs != cm.CompVarRef[1])
|
||||
|
@ -136,7 +137,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else if (vrfa == vrfl)
|
||||
{ // Comp/Comp
|
||||
{ // Comp/Comp
|
||||
predContext = 4;
|
||||
}
|
||||
else
|
||||
|
@ -146,7 +147,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else if (!xd.AboveMi.IsNull || !xd.LeftMi.IsNull)
|
||||
{ // One edge available
|
||||
{ // One edge available
|
||||
ref ModeInfo edgeMi = ref !xd.AboveMi.IsNull ? ref xd.AboveMi.Value : ref xd.LeftMi.Value;
|
||||
|
||||
if (!edgeMi.IsInterBlock())
|
||||
|
@ -166,10 +167,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else
|
||||
{ // No edges available (2)
|
||||
{ // No edges available (2)
|
||||
predContext = 2;
|
||||
}
|
||||
Debug.Assert(predContext >= 0 && predContext < Constants.RefContexts);
|
||||
|
||||
return predContext;
|
||||
}
|
||||
|
||||
|
@ -181,16 +183,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// left of the entries corresponding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialized to 0.
|
||||
if (!xd.AboveMi.IsNull && !xd.LeftMi.IsNull)
|
||||
{ // Both edges available
|
||||
{ // Both edges available
|
||||
bool aboveIntra = !xd.AboveMi.Value.IsInterBlock();
|
||||
bool leftIntra = !xd.LeftMi.Value.IsInterBlock();
|
||||
|
||||
if (aboveIntra && leftIntra)
|
||||
{ // Intra/Intra
|
||||
{ // Intra/Intra
|
||||
predContext = 2;
|
||||
}
|
||||
else if (aboveIntra || leftIntra)
|
||||
{ // Intra/Inter or Inter/Intra
|
||||
{ // Intra/Inter or Inter/Intra
|
||||
ref ModeInfo edgeMi = ref aboveIntra ? ref xd.LeftMi.Value : ref xd.AboveMi.Value;
|
||||
if (!edgeMi.HasSecondRef())
|
||||
{
|
||||
|
@ -203,7 +205,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else
|
||||
{ // Inter/Inter
|
||||
{ // Inter/Inter
|
||||
bool aboveHasSecond = xd.AboveMi.Value.HasSecondRef();
|
||||
bool leftHasSecond = xd.LeftMi.Value.HasSecondRef();
|
||||
sbyte above0 = xd.AboveMi.Value.RefFrame[0];
|
||||
|
@ -238,14 +240,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else if (!xd.AboveMi.IsNull || !xd.LeftMi.IsNull)
|
||||
{ // One edge available
|
||||
{ // One edge available
|
||||
ref ModeInfo edgeMi = ref !xd.AboveMi.IsNull ? ref xd.AboveMi.Value : ref xd.LeftMi.Value;
|
||||
if (!edgeMi.IsInterBlock())
|
||||
{ // Intra
|
||||
{ // Intra
|
||||
predContext = 2;
|
||||
}
|
||||
else
|
||||
{ // Inter
|
||||
{ // Inter
|
||||
if (!edgeMi.HasSecondRef())
|
||||
{
|
||||
predContext = 4 * (edgeMi.RefFrame[0] == Constants.LastFrame ? 1 : 0);
|
||||
|
@ -258,10 +260,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else
|
||||
{ // No edges available
|
||||
{ // No edges available
|
||||
predContext = 2;
|
||||
}
|
||||
Debug.Assert(predContext >= 0 && predContext < Constants.RefContexts);
|
||||
|
||||
return predContext;
|
||||
}
|
||||
|
||||
|
@ -274,16 +277,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
// left of the entries corresponding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialized to 0.
|
||||
if (!xd.AboveMi.IsNull && !xd.LeftMi.IsNull)
|
||||
{ // Both edges available
|
||||
{ // Both edges available
|
||||
bool aboveIntra = !xd.AboveMi.Value.IsInterBlock();
|
||||
bool leftIntra = !xd.LeftMi.Value.IsInterBlock();
|
||||
|
||||
if (aboveIntra && leftIntra)
|
||||
{ // Intra/Intra
|
||||
{ // Intra/Intra
|
||||
predContext = 2;
|
||||
}
|
||||
else if (aboveIntra || leftIntra)
|
||||
{ // Intra/Inter or Inter/Intra
|
||||
{ // Intra/Inter or Inter/Intra
|
||||
ref ModeInfo edgeMi = ref aboveIntra ? ref xd.LeftMi.Value : ref xd.AboveMi.Value;
|
||||
if (!edgeMi.HasSecondRef())
|
||||
{
|
||||
|
@ -303,7 +306,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else
|
||||
{ // Inter/Inter
|
||||
{ // Inter/Inter
|
||||
bool aboveHasSecond = xd.AboveMi.Value.HasSecondRef();
|
||||
bool leftHasSecond = xd.LeftMi.Value.HasSecondRef();
|
||||
sbyte above0 = xd.AboveMi.Value.RefFrame[0];
|
||||
|
@ -361,7 +364,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else if (!xd.AboveMi.IsNull || !xd.LeftMi.IsNull)
|
||||
{ // One edge available
|
||||
{ // One edge available
|
||||
ref ModeInfo edgeMi = ref !xd.AboveMi.IsNull ? ref xd.AboveMi.Value : ref xd.LeftMi.Value;
|
||||
|
||||
if (!edgeMi.IsInterBlock() || (edgeMi.RefFrame[0] == Constants.LastFrame && !edgeMi.HasSecondRef()))
|
||||
|
@ -379,10 +382,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
}
|
||||
}
|
||||
else
|
||||
{ // No edges available (2)
|
||||
{ // No edges available (2)
|
||||
predContext = 2;
|
||||
}
|
||||
Debug.Assert(predContext >= 0 && predContext < Constants.RefContexts);
|
||||
|
||||
return predContext;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
public const int MinQ = 0;
|
||||
public const int MaxQ = 255;
|
||||
|
||||
private static readonly short[] DcQlookup = new short[]
|
||||
{
|
||||
private static readonly short[] _dcQlookup = {
|
||||
4, 8, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 29, 30,
|
||||
31, 32, 32, 33, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42,
|
||||
|
@ -32,8 +31,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
1184, 1232, 1282, 1336,
|
||||
};
|
||||
|
||||
private static readonly short[] DcQlookup10 = new short[]
|
||||
{
|
||||
private static readonly short[] _dcQlookup10 = {
|
||||
4, 9, 10, 13, 15, 17, 20, 22, 25, 28, 31, 34, 37,
|
||||
40, 43, 47, 50, 53, 57, 60, 64, 68, 71, 75, 78, 82,
|
||||
86, 90, 93, 97, 101, 105, 109, 113, 116, 120, 124, 128, 132,
|
||||
|
@ -56,8 +54,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
3953, 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347,
|
||||
};
|
||||
|
||||
private static readonly short[] DcQlookup12 = new short[]
|
||||
{
|
||||
private static readonly short[] _dcQlookup12 = {
|
||||
4, 12, 18, 25, 33, 41, 50, 60, 70, 80, 91,
|
||||
103, 115, 127, 140, 153, 166, 180, 194, 208, 222, 237,
|
||||
251, 266, 281, 296, 312, 327, 343, 358, 374, 390, 405,
|
||||
|
@ -84,8 +81,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
19718, 20521, 21387,
|
||||
};
|
||||
|
||||
private static readonly short[] AcQlookup = new short[]
|
||||
{
|
||||
private static readonly short[] _acQlookup = {
|
||||
4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
|
||||
|
@ -108,8 +104,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
1567, 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
|
||||
};
|
||||
|
||||
private static readonly short[] AcQlookup10 = new short[]
|
||||
{
|
||||
private static readonly short[] _acQlookup10 = {
|
||||
4, 9, 11, 13, 16, 18, 21, 24, 27, 30, 33, 37, 40,
|
||||
44, 48, 51, 55, 59, 63, 67, 71, 75, 79, 83, 88, 92,
|
||||
96, 100, 105, 109, 114, 118, 122, 127, 131, 136, 140, 145, 149,
|
||||
|
@ -132,8 +127,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
6268, 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312,
|
||||
};
|
||||
|
||||
private static readonly short[] AcQlookup12 = new short[]
|
||||
{
|
||||
private static readonly short[] _acQlookup12 = {
|
||||
4, 13, 19, 27, 35, 44, 54, 64, 75, 87, 99,
|
||||
112, 126, 139, 154, 168, 183, 199, 214, 230, 247, 263,
|
||||
280, 297, 314, 331, 349, 366, 384, 402, 420, 438, 456,
|
||||
|
@ -164,11 +158,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
switch (bitDepth)
|
||||
{
|
||||
case BitDepth.Bits8: return DcQlookup[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits10: return DcQlookup10[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits12: return DcQlookup12[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits8:
|
||||
return _dcQlookup[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits10:
|
||||
return _dcQlookup10[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits12:
|
||||
return _dcQlookup12[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
default:
|
||||
Debug.Assert(false, "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12");
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -177,11 +175,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
switch (bitDepth)
|
||||
{
|
||||
case BitDepth.Bits8: return AcQlookup[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits10: return AcQlookup10[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits12: return AcQlookup12[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits8:
|
||||
return _acQlookup[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits10:
|
||||
return _acQlookup10[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits12:
|
||||
return _acQlookup12[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
default:
|
||||
Debug.Assert(false, "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12");
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -192,12 +194,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
int data = seg.GetSegData(segmentId, SegLvlFeatures.SegLvlAltQ);
|
||||
int segQIndex = seg.AbsDelta == Constants.SegmentAbsData ? data : baseQIndex + data;
|
||||
|
||||
return Math.Clamp(segQIndex, 0, MaxQ);
|
||||
}
|
||||
else
|
||||
{
|
||||
return baseQIndex;
|
||||
}
|
||||
|
||||
return baseQIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,16 +84,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
private static Mv MiMvPredQ4(ref ModeInfo mi, int idx)
|
||||
{
|
||||
Mv res = new Mv()
|
||||
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)
|
||||
mi.Bmi[2].Mv[idx].Col + mi.Bmi[3].Mv[idx].Col),
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
private static int RoundMvCompQ2(int value)
|
||||
|
@ -103,16 +102,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
private static Mv MiMvPredQ2(ref ModeInfo mi, int idx, int block0, int block1)
|
||||
{
|
||||
Mv res = new Mv()
|
||||
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)
|
||||
mi.Bmi[block1].Mv[idx].Col),
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
public static Mv ClampMvToUmvBorderSb(ref MacroBlockD xd, ref Mv srcMv, int bw, int bh, int ssX, int ssY)
|
||||
|
@ -124,10 +122,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
int spelRight = spelLeft - SubpelShifts;
|
||||
int spelTop = (Constants.Vp9InterpExtend + bh) << SubpelBits;
|
||||
int spelBottom = spelTop - SubpelShifts;
|
||||
Mv clampedMv = new Mv()
|
||||
Mv clampedMv = new()
|
||||
{
|
||||
Row = (short)(srcMv.Row * (1 << (1 - ssY))),
|
||||
Col = (short)(srcMv.Col * (1 << (1 - ssX)))
|
||||
Col = (short)(srcMv.Col * (1 << (1 - ssX))),
|
||||
};
|
||||
|
||||
Debug.Assert(ssX <= 1);
|
||||
|
@ -145,14 +143,24 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
public static Mv AverageSplitMvs(ref MacroBlockDPlane pd, ref ModeInfo mi, int refr, int block)
|
||||
{
|
||||
int ssIdx = ((pd.SubsamplingX > 0 ? 1 : 0) << 1) | (pd.SubsamplingY > 0 ? 1 : 0);
|
||||
Mv res = new Mv();
|
||||
Mv res = new();
|
||||
switch (ssIdx)
|
||||
{
|
||||
case 0: res = mi.Bmi[block].Mv[refr]; break;
|
||||
case 1: res = MiMvPredQ2(ref mi, refr, block, block + 2); break;
|
||||
case 2: res = MiMvPredQ2(ref mi, refr, block, block + 1); break;
|
||||
case 3: res = MiMvPredQ4(ref mi, refr); break;
|
||||
default: Debug.Assert(ssIdx <= 3 && ssIdx >= 0); break;
|
||||
case 0:
|
||||
res = mi.Bmi[block].Mv[refr];
|
||||
break;
|
||||
case 1:
|
||||
res = MiMvPredQ2(ref mi, refr, block, block + 2);
|
||||
break;
|
||||
case 2:
|
||||
res = MiMvPredQ2(ref mi, refr, block, block + 1);
|
||||
break;
|
||||
case 3:
|
||||
res = MiMvPredQ4(ref mi, refr);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(ssIdx <= 3 && ssIdx >= 0);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -161,6 +169,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,18 +7,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
{
|
||||
internal static class ReconIntra
|
||||
{
|
||||
public static readonly TxType[] IntraModeToTxTypeLookup = new TxType[]
|
||||
{
|
||||
TxType.DctDct, // DC
|
||||
TxType.AdstDct, // V
|
||||
TxType.DctAdst, // H
|
||||
TxType.DctDct, // D45
|
||||
TxType.AdstAdst, // D135
|
||||
TxType.AdstDct, // D117
|
||||
TxType.DctAdst, // D153
|
||||
TxType.DctAdst, // D207
|
||||
TxType.AdstDct, // D63
|
||||
TxType.AdstAdst // TM
|
||||
public static readonly TxType[] IntraModeToTxTypeLookup = {
|
||||
TxType.DctDct, // DC
|
||||
TxType.AdstDct, // V
|
||||
TxType.DctAdst, // H
|
||||
TxType.DctDct, // D45
|
||||
TxType.AdstAdst, // D135
|
||||
TxType.AdstDct, // D117
|
||||
TxType.DctAdst, // D153
|
||||
TxType.DctAdst, // D207
|
||||
TxType.AdstDct, // D63
|
||||
TxType.AdstAdst, // TM
|
||||
};
|
||||
|
||||
private const int NeedLeft = 1 << 1;
|
||||
|
@ -27,244 +26,240 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
|
||||
private static ReadOnlySpan<byte> ExtendModes => new byte[]
|
||||
{
|
||||
NeedAbove | NeedLeft, // DC
|
||||
NeedAbove, // V
|
||||
NeedLeft, // H
|
||||
NeedAboveRight, // D45
|
||||
NeedLeft | NeedAbove, // D135
|
||||
NeedLeft | NeedAbove, // D117
|
||||
NeedLeft | NeedAbove, // D153
|
||||
NeedLeft, // D207
|
||||
NeedAboveRight, // D63
|
||||
NeedLeft | NeedAbove, // TM
|
||||
NeedAbove | NeedLeft, // DC
|
||||
NeedAbove, // V
|
||||
NeedLeft, // H
|
||||
NeedAboveRight, // D45
|
||||
NeedLeft | NeedAbove, // D135
|
||||
NeedLeft | NeedAbove, // D117
|
||||
NeedLeft | NeedAbove, // D153
|
||||
NeedLeft, // D207
|
||||
NeedAboveRight, // D63
|
||||
NeedLeft | NeedAbove, // TM
|
||||
};
|
||||
|
||||
private unsafe delegate void IntraPredFn(byte* dst, int stride, byte* above, byte* left);
|
||||
|
||||
private static unsafe IntraPredFn[][] _pred = new IntraPredFn[][]
|
||||
{
|
||||
private static readonly unsafe IntraPredFn[][] _pred = {
|
||||
new IntraPredFn[]
|
||||
{
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
null,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
VPredictor4x4,
|
||||
VPredictor8x8,
|
||||
VPredictor16x16,
|
||||
VPredictor32x32
|
||||
VPredictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
HPredictor4x4,
|
||||
HPredictor8x8,
|
||||
HPredictor16x16,
|
||||
HPredictor32x32
|
||||
HPredictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D45Predictor4x4,
|
||||
D45Predictor8x8,
|
||||
D45Predictor16x16,
|
||||
D45Predictor32x32
|
||||
D45Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D135Predictor4x4,
|
||||
D135Predictor8x8,
|
||||
D135Predictor16x16,
|
||||
D135Predictor32x32
|
||||
D135Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D117Predictor4x4,
|
||||
D117Predictor8x8,
|
||||
D117Predictor16x16,
|
||||
D117Predictor32x32
|
||||
D117Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D153Predictor4x4,
|
||||
D153Predictor8x8,
|
||||
D153Predictor16x16,
|
||||
D153Predictor32x32
|
||||
D153Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D207Predictor4x4,
|
||||
D207Predictor8x8,
|
||||
D207Predictor16x16,
|
||||
D207Predictor32x32
|
||||
D207Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D63Predictor4x4,
|
||||
D63Predictor8x8,
|
||||
D63Predictor16x16,
|
||||
D63Predictor32x32
|
||||
D63Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
TMPredictor4x4,
|
||||
TMPredictor8x8,
|
||||
TMPredictor16x16,
|
||||
TMPredictor32x32
|
||||
}
|
||||
TMPredictor32x32,
|
||||
},
|
||||
};
|
||||
|
||||
private static unsafe IntraPredFn[][][] _dcPred = new IntraPredFn[][][]
|
||||
{
|
||||
new IntraPredFn[][]
|
||||
private static readonly unsafe IntraPredFn[][][] _dcPred = {
|
||||
new[]
|
||||
{
|
||||
new IntraPredFn[]
|
||||
{
|
||||
Dc128Predictor4x4,
|
||||
Dc128Predictor8x8,
|
||||
Dc128Predictor16x16,
|
||||
Dc128Predictor32x32
|
||||
Dc128Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
DcTopPredictor4x4,
|
||||
DcTopPredictor8x8,
|
||||
DcTopPredictor16x16,
|
||||
DcTopPredictor32x32
|
||||
}
|
||||
DcTopPredictor32x32,
|
||||
},
|
||||
},
|
||||
new IntraPredFn[][]
|
||||
new[]
|
||||
{
|
||||
new IntraPredFn[]
|
||||
{
|
||||
DcLeftPredictor4x4,
|
||||
DcLeftPredictor8x8,
|
||||
DcLeftPredictor16x16,
|
||||
DcLeftPredictor32x32
|
||||
DcLeftPredictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
DcPredictor4x4,
|
||||
DcPredictor8x8,
|
||||
DcPredictor16x16,
|
||||
DcPredictor32x32
|
||||
}
|
||||
}
|
||||
DcPredictor32x32,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
private unsafe delegate void IntraHighPredFn(ushort* dst, int stride, ushort* above, ushort* left, int bd);
|
||||
|
||||
private static unsafe IntraHighPredFn[][] _predHigh = new IntraHighPredFn[][]
|
||||
{
|
||||
private static readonly unsafe IntraHighPredFn[][] _predHigh = {
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
null,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdVPredictor4x4,
|
||||
HighbdVPredictor8x8,
|
||||
HighbdVPredictor16x16,
|
||||
HighbdVPredictor32x32
|
||||
HighbdVPredictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdHPredictor4x4,
|
||||
HighbdHPredictor8x8,
|
||||
HighbdHPredictor16x16,
|
||||
HighbdHPredictor32x32
|
||||
HighbdHPredictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD45Predictor4x4,
|
||||
HighbdD45Predictor8x8,
|
||||
HighbdD45Predictor16x16,
|
||||
HighbdD45Predictor32x32
|
||||
HighbdD45Predictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD135Predictor4x4,
|
||||
HighbdD135Predictor8x8,
|
||||
HighbdD135Predictor16x16,
|
||||
HighbdD135Predictor32x32
|
||||
HighbdD135Predictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD117Predictor4x4,
|
||||
HighbdD117Predictor8x8,
|
||||
HighbdD117Predictor16x16,
|
||||
HighbdD117Predictor32x32
|
||||
HighbdD117Predictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD153Predictor4x4,
|
||||
HighbdD153Predictor8x8,
|
||||
HighbdD153Predictor16x16,
|
||||
HighbdD153Predictor32x32
|
||||
HighbdD153Predictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD207Predictor4x4,
|
||||
HighbdD207Predictor8x8,
|
||||
HighbdD207Predictor16x16,
|
||||
HighbdD207Predictor32x32
|
||||
HighbdD207Predictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD63Predictor4x4,
|
||||
HighbdD63Predictor8x8,
|
||||
HighbdD63Predictor16x16,
|
||||
HighbdD63Predictor32x32
|
||||
HighbdD63Predictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdTMPredictor4x4,
|
||||
HighbdTMPredictor8x8,
|
||||
HighbdTMPredictor16x16,
|
||||
HighbdTMPredictor32x32
|
||||
}
|
||||
HighbdTMPredictor32x32,
|
||||
},
|
||||
};
|
||||
|
||||
private static unsafe IntraHighPredFn[][][] _dcPredHigh = new IntraHighPredFn[][][]
|
||||
{
|
||||
new IntraHighPredFn[][]
|
||||
private static readonly unsafe IntraHighPredFn[][][] _dcPredHigh = {
|
||||
new[]
|
||||
{
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDc128Predictor4x4,
|
||||
HighbdDc128Predictor8x8,
|
||||
HighbdDc128Predictor16x16,
|
||||
HighbdDc128Predictor32x32
|
||||
HighbdDc128Predictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDcTopPredictor4x4,
|
||||
HighbdDcTopPredictor8x8,
|
||||
HighbdDcTopPredictor16x16,
|
||||
HighbdDcTopPredictor32x32
|
||||
}
|
||||
HighbdDcTopPredictor32x32,
|
||||
},
|
||||
},
|
||||
new IntraHighPredFn[][]
|
||||
new[]
|
||||
{
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDcLeftPredictor4x4,
|
||||
HighbdDcLeftPredictor8x8,
|
||||
HighbdDcLeftPredictor16x16,
|
||||
HighbdDcLeftPredictor32x32
|
||||
HighbdDcLeftPredictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDcPredictor4x4,
|
||||
HighbdDcPredictor8x8,
|
||||
HighbdDcPredictor16x16,
|
||||
HighbdDcPredictor32x32
|
||||
}
|
||||
}
|
||||
HighbdDcPredictor32x32,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
private static unsafe void BuildIntraPredictorsHigh(
|
||||
|
@ -741,6 +736,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||
x,
|
||||
y,
|
||||
plane);
|
||||
|
||||
return;
|
||||
}
|
||||
BuildIntraPredictors(
|
||||
|
|
|
@ -5,6 +5,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
internal struct BModeInfo
|
||||
{
|
||||
public PredictionMode Mode;
|
||||
public Array2<Mv> Mv; // First, second inter predictor motion vectors
|
||||
public Array2<Mv> Mv; // First, second inter predictor motion vectors
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
Block64x32 = 11,
|
||||
Block64x64 = 12,
|
||||
BlockSizes = 13,
|
||||
BlockInvalid = BlockSizes
|
||||
BlockInvalid = BlockSizes,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
internal enum FrameType
|
||||
{
|
||||
KeyFrame = 0,
|
||||
InterFrame = 1
|
||||
InterFrame = 1,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
// passed it can be loaded into vector registers.
|
||||
internal struct LoopFilterThresh
|
||||
{
|
||||
#pragma warning disable CS0649
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Array16<byte> Mblim;
|
||||
public Array16<byte> Lim;
|
||||
public Array16<byte> HevThr;
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
|
||||
public Ptr<InternalErrorInfo> ErrorInfo;
|
||||
|
||||
public int GetPredContextSegId()
|
||||
public readonly int GetPredContextSegId()
|
||||
{
|
||||
sbyte aboveSip = !AboveMi.IsNull ? AboveMi.Value.SegIdPredicted : (sbyte)0;
|
||||
sbyte leftSip = !LeftMi.IsNull ? LeftMi.Value.SegIdPredicted : (sbyte)0;
|
||||
|
@ -62,14 +62,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
return aboveSip + leftSip;
|
||||
}
|
||||
|
||||
public int GetSkipContext()
|
||||
public readonly int GetSkipContext()
|
||||
{
|
||||
int aboveSkip = !AboveMi.IsNull ? AboveMi.Value.Skip : 0;
|
||||
int leftSkip = !LeftMi.IsNull ? LeftMi.Value.Skip : 0;
|
||||
|
||||
return aboveSkip + leftSkip;
|
||||
}
|
||||
|
||||
public int GetPredContextSwitchableInterp()
|
||||
public readonly int GetPredContextSwitchableInterp()
|
||||
{
|
||||
// Note:
|
||||
// The mode info data structure has a one element border above and to the
|
||||
|
@ -103,16 +104,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
// 1 - intra/inter, inter/intra
|
||||
// 2 - intra/--, --/intra
|
||||
// 3 - intra/intra
|
||||
public int GetIntraInterContext()
|
||||
public readonly int GetIntraInterContext()
|
||||
{
|
||||
if (!AboveMi.IsNull && !LeftMi.IsNull)
|
||||
{ // Both edges available
|
||||
{ // Both edges available
|
||||
bool aboveIntra = !AboveMi.Value.IsInterBlock();
|
||||
bool leftIntra = !LeftMi.Value.IsInterBlock();
|
||||
|
||||
return leftIntra && aboveIntra ? 3 : (leftIntra || aboveIntra ? 1 : 0);
|
||||
}
|
||||
else if (!AboveMi.IsNull || !LeftMi.IsNull)
|
||||
{ // One edge available
|
||||
|
||||
if (!AboveMi.IsNull || !LeftMi.IsNull)
|
||||
{ // One edge available
|
||||
return 2 * (!(!AboveMi.IsNull ? AboveMi.Value : LeftMi.Value).IsInterBlock() ? 1 : 0);
|
||||
}
|
||||
return 0;
|
||||
|
@ -122,7 +125,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
// The mode info data structure has a one element border above and to the
|
||||
// left of the entries corresponding to real blocks.
|
||||
// The prediction flags in these dummy entries are initialized to 0.
|
||||
public int GetTxSizeContext()
|
||||
public readonly int GetTxSizeContext()
|
||||
{
|
||||
int maxTxSize = (int)Luts.MaxTxSizeLookup[(int)Mi[0].Value.SbType];
|
||||
int aboveCtx = (!AboveMi.IsNull && AboveMi.Value.Skip == 0) ? (int)AboveMi.Value.TxSize : maxTxSize;
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
public TxSize TxSize;
|
||||
public sbyte Skip;
|
||||
public sbyte SegmentId;
|
||||
public sbyte SegIdPredicted; // Valid only when TemporalUpdate is enabled
|
||||
public sbyte SegIdPredicted; // Valid only when TemporalUpdate is enabled
|
||||
|
||||
// Only for Intra blocks
|
||||
public PredictionMode UvMode;
|
||||
|
@ -32,10 +32,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
return SbType < BlockSize.Block8x8 ? Bmi[block].Mode : Mode;
|
||||
}
|
||||
|
||||
public TxSize GetUvTxSize(ref MacroBlockDPlane pd)
|
||||
public readonly TxSize GetUvTxSize(ref MacroBlockDPlane pd)
|
||||
{
|
||||
Debug.Assert(SbType < BlockSize.Block8x8 ||
|
||||
Luts.SsSizeLookup[(int)SbType][pd.SubsamplingX][pd.SubsamplingY] != BlockSize.BlockInvalid);
|
||||
|
||||
return Luts.UvTxsizeLookup[(int)SbType][(int)TxSize][pd.SubsamplingX][pd.SubsamplingY];
|
||||
}
|
||||
|
||||
|
@ -49,9 +50,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
return RefFrame[1] > Constants.IntraFrame;
|
||||
}
|
||||
|
||||
private static readonly int[][] IdxNColumnToSubblock = new int[][]
|
||||
{
|
||||
new int[] { 1, 2 }, new int[] { 1, 3 }, new int[] { 3, 2 }, new int[] { 3, 3 }
|
||||
private static readonly int[][] _idxNColumnToSubblock = {
|
||||
new[] { 1, 2 }, new[] { 1, 3 }, new[] { 3, 2 }, new[] { 3, 3 },
|
||||
};
|
||||
|
||||
// This function returns either the appropriate sub block or block's mv
|
||||
|
@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
public Mv GetSubBlockMv(int whichMv, int searchCol, int blockIdx)
|
||||
{
|
||||
return blockIdx >= 0 && SbType < BlockSize.Block8x8
|
||||
? Bmi[IdxNColumnToSubblock[blockIdx][searchCol == 0 ? 1 : 0]].Mv[whichMv]
|
||||
? Bmi[_idxNColumnToSubblock[blockIdx][searchCol == 0 ? 1 : 0]].Mv[whichMv]
|
||||
: Mv[whichMv];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
BothNew = 4,
|
||||
IntraPlusNonIntra = 5,
|
||||
BothIntra = 6,
|
||||
InvalidCase = 9
|
||||
InvalidCase = 9,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,13 +51,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10,
|
||||
};
|
||||
|
||||
public bool UseMvHp()
|
||||
public readonly bool UseMvHp()
|
||||
{
|
||||
const int kMvRefThresh = 64; // Threshold for use of high-precision 1/8 mv
|
||||
return Math.Abs(Row) < kMvRefThresh && Math.Abs(Col) < kMvRefThresh;
|
||||
const int KMvRefThresh = 64; // Threshold for use of high-precision 1/8 mv
|
||||
return Math.Abs(Row) < KMvRefThresh && Math.Abs(Col) < KMvRefThresh;
|
||||
}
|
||||
|
||||
public static bool MvJointVertical(MvJointType type)
|
||||
|
@ -110,7 +110,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
else
|
||||
{
|
||||
int i;
|
||||
int b = c + Constants.Class0Bits - 1; // Number of bits
|
||||
int b = c + Constants.Class0Bits - 1; // Number of bits
|
||||
for (i = 0; i < b; ++i)
|
||||
{
|
||||
counts.Bits[comp][i][((d >> i) & 1)] += (uint)incr;
|
||||
|
@ -121,19 +121,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
}
|
||||
}
|
||||
|
||||
private MvJointType GetMvJoint()
|
||||
private readonly MvJointType GetMvJoint()
|
||||
{
|
||||
if (Row == 0)
|
||||
{
|
||||
return Col == 0 ? MvJointType.MvJointZero : MvJointType.MvJointHnzvz;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Col == 0 ? MvJointType.MvJointHzvnz : MvJointType.MvJointHnzvnz;
|
||||
}
|
||||
|
||||
return Col == 0 ? MvJointType.MvJointHzvnz : MvJointType.MvJointHnzvnz;
|
||||
}
|
||||
|
||||
internal void IncMv(Ptr<Vp9BackwardUpdates> counts)
|
||||
internal readonly void IncMv(Ptr<Vp9BackwardUpdates> counts)
|
||||
{
|
||||
if (!counts.IsNull)
|
||||
{
|
||||
|
@ -158,7 +156,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
Row = (short)Math.Clamp(Row, minRow, maxRow);
|
||||
}
|
||||
|
||||
private const int MvBorder = (16 << 3); // Allow 16 pels in 1/8th pel units
|
||||
private const int MvBorder = (16 << 3); // Allow 16 pels in 1/8th pel units
|
||||
|
||||
public void ClampMvRef(ref MacroBlockD xd)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
PartitionVert,
|
||||
PartitionSplit,
|
||||
PartitionTypes,
|
||||
PartitionInvalid = PartitionTypes
|
||||
PartitionInvalid = PartitionTypes,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
{
|
||||
Y = 0,
|
||||
Uv = 1,
|
||||
PlaneTypes
|
||||
PlaneTypes,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
{
|
||||
internal enum PredictionMode
|
||||
{
|
||||
DcPred = 0, // Average of above and left pixels
|
||||
VPred = 1, // Vertical
|
||||
HPred = 2, // Horizontal
|
||||
D45Pred = 3, // Directional 45 deg = round(arctan(1 / 1) * 180 / pi)
|
||||
D135Pred = 4, // Directional 135 deg = 180 - 45
|
||||
D117Pred = 5, // Directional 117 deg = 180 - 63
|
||||
D153Pred = 6, // Directional 153 deg = 180 - 27
|
||||
D207Pred = 7, // Directional 207 deg = 180 + 27
|
||||
D63Pred = 8, // Directional 63 deg = round(arctan(2 / 1) * 180 / pi)
|
||||
TmPred = 9, // True-motion
|
||||
DcPred = 0, // Average of above and left pixels
|
||||
VPred = 1, // Vertical
|
||||
HPred = 2, // Horizontal
|
||||
D45Pred = 3, // Directional 45 deg = round(arctan(1 / 1) * 180 / pi)
|
||||
D135Pred = 4, // Directional 135 deg = 180 - 45
|
||||
D117Pred = 5, // Directional 117 deg = 180 - 63
|
||||
D153Pred = 6, // Directional 153 deg = 180 - 27
|
||||
D207Pred = 7, // Directional 207 deg = 180 + 27
|
||||
D63Pred = 8, // Directional 63 deg = round(arctan(2 / 1) * 180 / pi)
|
||||
TmPred = 9, // True-motion
|
||||
NearestMv = 10,
|
||||
NearMv = 11,
|
||||
ZeroMv = 12,
|
||||
NewMv = 13,
|
||||
MbModeCount = 14
|
||||
MbModeCount = 14,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
SingleReference = 0,
|
||||
CompoundReference = 1,
|
||||
ReferenceModeSelect = 2,
|
||||
ReferenceModes = 3
|
||||
ReferenceModes = 3,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,263 +38,255 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
int h,
|
||||
int bd);
|
||||
|
||||
private static readonly unsafe ConvolveFn[][][] PredictX16Y16 = new ConvolveFn[][][]
|
||||
{
|
||||
new ConvolveFn[][]
|
||||
private static readonly unsafe ConvolveFn[][][] _predictX16Y16 = {
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[]
|
||||
{
|
||||
ConvolveCopy,
|
||||
ConvolveAvg
|
||||
ConvolveAvg,
|
||||
},
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Convolve8Vert,
|
||||
Convolve8AvgVert
|
||||
}
|
||||
Convolve8AvgVert,
|
||||
},
|
||||
},
|
||||
new ConvolveFn[][]
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Convolve8Horiz,
|
||||
Convolve8AvgHoriz
|
||||
Convolve8AvgHoriz,
|
||||
},
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Convolve8,
|
||||
Convolve8Avg
|
||||
}
|
||||
}
|
||||
Convolve8Avg,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
private static readonly unsafe ConvolveFn[][][] PredictX16 = new ConvolveFn[][][]
|
||||
{
|
||||
new ConvolveFn[][]
|
||||
private static readonly unsafe ConvolveFn[][][] _predictX16 = {
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[]
|
||||
{
|
||||
ScaledVert,
|
||||
ScaledAvgVert
|
||||
ScaledAvgVert,
|
||||
},
|
||||
new ConvolveFn[]
|
||||
{
|
||||
ScaledVert,
|
||||
ScaledAvgVert
|
||||
}
|
||||
ScaledAvgVert,
|
||||
},
|
||||
},
|
||||
new ConvolveFn[][]
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Scaled2D,
|
||||
ScaledAvg2D
|
||||
ScaledAvg2D,
|
||||
},
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Scaled2D,
|
||||
ScaledAvg2D
|
||||
}
|
||||
}
|
||||
ScaledAvg2D,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
private static readonly unsafe ConvolveFn[][][] PredictY16 = new ConvolveFn[][][]
|
||||
{
|
||||
new ConvolveFn[][]
|
||||
private static readonly unsafe ConvolveFn[][][] _predictY16 = {
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[]
|
||||
{
|
||||
ScaledHoriz,
|
||||
ScaledAvgHoriz
|
||||
ScaledAvgHoriz,
|
||||
},
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Scaled2D,
|
||||
ScaledAvg2D
|
||||
}
|
||||
ScaledAvg2D,
|
||||
},
|
||||
},
|
||||
new ConvolveFn[][]
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[]
|
||||
{
|
||||
ScaledHoriz,
|
||||
ScaledAvgHoriz
|
||||
ScaledAvgHoriz,
|
||||
},
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Scaled2D,
|
||||
ScaledAvg2D
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static readonly unsafe ConvolveFn[][][] Predict = new ConvolveFn[][][]
|
||||
{
|
||||
new ConvolveFn[][]
|
||||
{
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Scaled2D,
|
||||
ScaledAvg2D
|
||||
ScaledAvg2D,
|
||||
},
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Scaled2D,
|
||||
ScaledAvg2D
|
||||
}
|
||||
},
|
||||
new ConvolveFn[][]
|
||||
};
|
||||
|
||||
private static readonly unsafe ConvolveFn[][][] _predict = {
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Scaled2D,
|
||||
ScaledAvg2D
|
||||
ScaledAvg2D,
|
||||
},
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Scaled2D,
|
||||
ScaledAvg2D
|
||||
}
|
||||
}
|
||||
ScaledAvg2D,
|
||||
},
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Scaled2D,
|
||||
ScaledAvg2D,
|
||||
},
|
||||
new ConvolveFn[]
|
||||
{
|
||||
Scaled2D,
|
||||
ScaledAvg2D,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
private static readonly unsafe HighbdConvolveFn[][][] HighbdPredictX16Y16 = new HighbdConvolveFn[][][]
|
||||
{
|
||||
new HighbdConvolveFn[][]
|
||||
private static readonly unsafe HighbdConvolveFn[][][] _highbdPredictX16Y16 = {
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolveCopy,
|
||||
HighbdConvolveAvg
|
||||
HighbdConvolveAvg,
|
||||
},
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8Vert,
|
||||
HighbdConvolve8AvgVert
|
||||
}
|
||||
HighbdConvolve8AvgVert,
|
||||
},
|
||||
},
|
||||
new HighbdConvolveFn[][]
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8Horiz,
|
||||
HighbdConvolve8AvgHoriz
|
||||
HighbdConvolve8AvgHoriz,
|
||||
},
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg
|
||||
}
|
||||
}
|
||||
HighbdConvolve8Avg,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
private static readonly unsafe HighbdConvolveFn[][][] HighbdPredictX16 = new HighbdConvolveFn[][][]
|
||||
{
|
||||
new HighbdConvolveFn[][]
|
||||
private static readonly unsafe HighbdConvolveFn[][][] _highbdPredictX16 = {
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8Vert,
|
||||
HighbdConvolve8AvgVert
|
||||
HighbdConvolve8AvgVert,
|
||||
},
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8Vert,
|
||||
HighbdConvolve8AvgVert
|
||||
}
|
||||
HighbdConvolve8AvgVert,
|
||||
},
|
||||
},
|
||||
new HighbdConvolveFn[][]
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg
|
||||
HighbdConvolve8Avg,
|
||||
},
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg
|
||||
}
|
||||
}
|
||||
HighbdConvolve8Avg,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
private static readonly unsafe HighbdConvolveFn[][][] HighbdPredictY16 = new HighbdConvolveFn[][][]
|
||||
{
|
||||
new HighbdConvolveFn[][]
|
||||
private static readonly unsafe HighbdConvolveFn[][][] _highbdPredictY16 = {
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8Horiz,
|
||||
HighbdConvolve8AvgHoriz
|
||||
HighbdConvolve8AvgHoriz,
|
||||
},
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg
|
||||
}
|
||||
HighbdConvolve8Avg,
|
||||
},
|
||||
},
|
||||
new HighbdConvolveFn[][]
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8Horiz,
|
||||
HighbdConvolve8AvgHoriz
|
||||
HighbdConvolve8AvgHoriz,
|
||||
},
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static readonly unsafe HighbdConvolveFn[][][] HighbdPredict = new HighbdConvolveFn[][][]
|
||||
{
|
||||
new HighbdConvolveFn[][]
|
||||
{
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg
|
||||
HighbdConvolve8Avg,
|
||||
},
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg
|
||||
}
|
||||
},
|
||||
new HighbdConvolveFn[][]
|
||||
};
|
||||
|
||||
private static readonly unsafe HighbdConvolveFn[][][] _highbdPredict = {
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg
|
||||
HighbdConvolve8Avg,
|
||||
},
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg
|
||||
}
|
||||
}
|
||||
HighbdConvolve8Avg,
|
||||
},
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg,
|
||||
},
|
||||
new HighbdConvolveFn[]
|
||||
{
|
||||
HighbdConvolve8,
|
||||
HighbdConvolve8Avg,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
public int XScaleFP; // Horizontal fixed point scale factor
|
||||
public int YScaleFP; // Vertical fixed point scale factor
|
||||
public int XScaleFP; // Horizontal fixed point scale factor
|
||||
public int YScaleFP; // Vertical fixed point scale factor
|
||||
public int XStepQ4;
|
||||
public int YStepQ4;
|
||||
|
||||
public int ScaleValueX(int val)
|
||||
public readonly int ScaleValueX(int val)
|
||||
{
|
||||
return IsScaled() ? ScaledX(val) : val;
|
||||
}
|
||||
|
||||
public int ScaleValueY(int val)
|
||||
public readonly int ScaleValueY(int val)
|
||||
{
|
||||
return IsScaled() ? ScaledY(val) : val;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public unsafe void InterPredict(
|
||||
public readonly unsafe void InterPredict(
|
||||
int horiz,
|
||||
int vert,
|
||||
int avg,
|
||||
|
@ -315,12 +307,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
if (YStepQ4 == 16)
|
||||
{
|
||||
// No scaling in either direction.
|
||||
PredictX16Y16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h);
|
||||
_predictX16Y16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No scaling in x direction. Must always scale in the y direction.
|
||||
PredictX16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h);
|
||||
_predictX16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -328,18 +320,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
if (YStepQ4 == 16)
|
||||
{
|
||||
// No scaling in the y direction. Must always scale in the x direction.
|
||||
PredictY16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h);
|
||||
_predictY16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Must always scale in both directions.
|
||||
Predict[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h);
|
||||
_predict[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public unsafe void HighbdInterPredict(
|
||||
public readonly unsafe void HighbdInterPredict(
|
||||
int horiz,
|
||||
int vert,
|
||||
int avg,
|
||||
|
@ -361,12 +353,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
if (YStepQ4 == 16)
|
||||
{
|
||||
// No scaling in either direction.
|
||||
HighbdPredictX16Y16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h, bd);
|
||||
_highbdPredictX16Y16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h, bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No scaling in x direction. Must always scale in the y direction.
|
||||
HighbdPredictX16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h, bd);
|
||||
_highbdPredictX16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h, bd);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -374,22 +366,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
if (YStepQ4 == 16)
|
||||
{
|
||||
// No scaling in the y direction. Must always scale in the x direction.
|
||||
HighbdPredictY16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h, bd);
|
||||
_highbdPredictY16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h, bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Must always scale in both directions.
|
||||
HighbdPredict[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h, bd);
|
||||
_highbdPredict[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w, h, bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int ScaledX(int val)
|
||||
private readonly int ScaledX(int val)
|
||||
{
|
||||
return (int)((long)val * XScaleFP >> RefScaleShift);
|
||||
}
|
||||
|
||||
private int ScaledY(int val)
|
||||
private readonly int ScaledY(int val)
|
||||
{
|
||||
return (int)((long)val * YScaleFP >> RefScaleShift);
|
||||
}
|
||||
|
@ -407,20 +399,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
{
|
||||
int xOffQ4 = ScaledX(x << SubpelBits) & SubpelMask;
|
||||
int yOffQ4 = ScaledY(y << SubpelBits) & SubpelMask;
|
||||
Mv32 res = new Mv32()
|
||||
Mv32 res = new()
|
||||
{
|
||||
Row = ScaledY(mv.Row) + yOffQ4,
|
||||
Col = ScaledX(mv.Col) + xOffQ4
|
||||
Col = ScaledX(mv.Col) + xOffQ4,
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public bool IsValidScale()
|
||||
public readonly bool IsValidScale()
|
||||
{
|
||||
return XScaleFP != RefInvalidScale && YScaleFP != RefInvalidScale;
|
||||
}
|
||||
|
||||
public bool IsScaled()
|
||||
public readonly bool IsScaled()
|
||||
{
|
||||
return IsValidScale() && (XScaleFP != RefNoScale || YScaleFP != RefNoScale);
|
||||
}
|
||||
|
@ -439,6 +432,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
{
|
||||
XScaleFP = RefInvalidScale;
|
||||
YScaleFP = RefInvalidScale;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
{
|
||||
internal enum SegLvlFeatures
|
||||
{
|
||||
SegLvlAltQ = 0, // Use alternate Quantizer ....
|
||||
SegLvlAltLf = 1, // Use alternate loop filter value...
|
||||
SegLvlRefFrame = 2, // Optional Segment reference frame
|
||||
SegLvlSkip = 3, // Optional Segment (0,0) + skip mode
|
||||
SegLvlMax = 4 // Number of features supported
|
||||
SegLvlAltQ = 0, // Use alternate Quantizer ....
|
||||
SegLvlAltLf = 1, // Use alternate loop filter value...
|
||||
SegLvlRefFrame = 2, // Optional Segment reference frame
|
||||
SegLvlSkip = 3, // Optional Segment (0,0) + skip mode
|
||||
SegLvlMax = 4, // Number of features supported
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
{
|
||||
internal struct Segmentation
|
||||
{
|
||||
private static readonly int[] SegFeatureDataSigned = new int[] { 1, 1, 0, 0 };
|
||||
private static readonly int[] SegFeatureDataMax = new int[] { QuantCommon.MaxQ, Vp9.LoopFilter.MaxLoopFilter, 3, 0 };
|
||||
private static readonly int[] _segFeatureDataSigned = { 1, 1, 0, 0 };
|
||||
private static readonly int[] _segFeatureDataMax = { QuantCommon.MaxQ, Vp9.LoopFilter.MaxLoopFilter, 3, 0 };
|
||||
|
||||
public bool Enabled;
|
||||
public bool UpdateMap;
|
||||
|
@ -26,8 +26,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
|
||||
public void ClearAllSegFeatures()
|
||||
{
|
||||
MemoryMarshal.CreateSpan(ref FeatureData[0][0], 8 * 4).Fill(0);
|
||||
MemoryMarshal.CreateSpan(ref FeatureMask[0], 8).Fill(0);
|
||||
MemoryMarshal.CreateSpan(ref FeatureData[0][0], 8 * 4).Clear();
|
||||
MemoryMarshal.CreateSpan(ref FeatureMask[0], 8).Clear();
|
||||
AqAvOffset = 0;
|
||||
}
|
||||
|
||||
|
@ -38,21 +38,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
|
||||
internal static int FeatureDataMax(SegLvlFeatures featureId)
|
||||
{
|
||||
return SegFeatureDataMax[(int)featureId];
|
||||
return _segFeatureDataMax[(int)featureId];
|
||||
}
|
||||
|
||||
internal static int IsSegFeatureSigned(SegLvlFeatures featureId)
|
||||
{
|
||||
return SegFeatureDataSigned[(int)featureId];
|
||||
return _segFeatureDataSigned[(int)featureId];
|
||||
}
|
||||
|
||||
internal void SetSegData(int segmentId, SegLvlFeatures featureId, int segData)
|
||||
{
|
||||
Debug.Assert(segData <= SegFeatureDataMax[(int)featureId]);
|
||||
Debug.Assert(segData <= _segFeatureDataMax[(int)featureId]);
|
||||
if (segData < 0)
|
||||
{
|
||||
Debug.Assert(SegFeatureDataSigned[(int)featureId] != 0);
|
||||
Debug.Assert(-segData <= SegFeatureDataMax[(int)featureId]);
|
||||
Debug.Assert(_segFeatureDataSigned[(int)featureId] != 0);
|
||||
Debug.Assert(-segData <= _segFeatureDataMax[(int)featureId]);
|
||||
}
|
||||
|
||||
FeatureData[segmentId][(int)featureId] = (short)segData;
|
||||
|
|
|
@ -11,11 +11,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
public ArrayPtr<byte> UBuffer;
|
||||
public ArrayPtr<byte> VBuffer;
|
||||
|
||||
public unsafe Plane YPlane => new Plane((IntPtr)YBuffer.ToPointer(), YBuffer.Length);
|
||||
public unsafe Plane UPlane => new Plane((IntPtr)UBuffer.ToPointer(), UBuffer.Length);
|
||||
public unsafe Plane VPlane => new Plane((IntPtr)VBuffer.ToPointer(), VBuffer.Length);
|
||||
public readonly unsafe Plane YPlane => new((IntPtr)YBuffer.ToPointer(), YBuffer.Length);
|
||||
public readonly unsafe Plane UPlane => new((IntPtr)UBuffer.ToPointer(), UBuffer.Length);
|
||||
public readonly unsafe Plane VPlane => new((IntPtr)VBuffer.ToPointer(), VBuffer.Length);
|
||||
|
||||
public FrameField Field => FrameField.Progressive;
|
||||
public readonly FrameField Field => FrameField.Progressive;
|
||||
|
||||
public int Width { get; }
|
||||
public int Height { get; }
|
||||
|
@ -27,29 +27,31 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
public int UvAlignedWidth { get; }
|
||||
public int UvAlignedHeight { get; }
|
||||
public int UvStride { get; }
|
||||
public bool HighBd => false;
|
||||
|
||||
public bool HighBd { get; }
|
||||
|
||||
private readonly IntPtr _pointer;
|
||||
|
||||
public Surface(int width, int height)
|
||||
{
|
||||
const int border = 32;
|
||||
const int ssX = 1;
|
||||
const int ssY = 1;
|
||||
const bool highbd = false;
|
||||
HighBd = false;
|
||||
|
||||
const int Border = 32;
|
||||
const int SsX = 1;
|
||||
const int SsY = 1;
|
||||
|
||||
int alignedWidth = (width + 7) & ~7;
|
||||
int alignedHeight = (height + 7) & ~7;
|
||||
int yStride = ((alignedWidth + 2 * border) + 31) & ~31;
|
||||
int yplaneSize = (alignedHeight + 2 * border) * yStride;
|
||||
int uvWidth = alignedWidth >> ssX;
|
||||
int uvHeight = alignedHeight >> ssY;
|
||||
int uvStride = yStride >> ssX;
|
||||
int uvBorderW = border >> ssX;
|
||||
int uvBorderH = border >> ssY;
|
||||
int yStride = ((alignedWidth + 2 * Border) + 31) & ~31;
|
||||
int yplaneSize = (alignedHeight + 2 * Border) * yStride;
|
||||
int uvWidth = alignedWidth >> SsX;
|
||||
int uvHeight = alignedHeight >> SsY;
|
||||
int uvStride = yStride >> SsX;
|
||||
int uvBorderW = Border >> SsX;
|
||||
int uvBorderH = Border >> SsY;
|
||||
int uvplaneSize = (uvHeight + 2 * uvBorderH) * uvStride;
|
||||
|
||||
int frameSize = (highbd ? 2 : 1) * (yplaneSize + 2 * uvplaneSize);
|
||||
int frameSize = (HighBd ? 2 : 1) * (yplaneSize + 2 * uvplaneSize);
|
||||
|
||||
IntPtr pointer = Marshal.AllocHGlobal(frameSize);
|
||||
_pointer = pointer;
|
||||
|
@ -58,23 +60,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
AlignedWidth = alignedWidth;
|
||||
AlignedHeight = alignedHeight;
|
||||
Stride = yStride;
|
||||
UvWidth = (width + ssX) >> ssX;
|
||||
UvHeight = (height + ssY) >> ssY;
|
||||
UvWidth = (width + SsX) >> SsX;
|
||||
UvHeight = (height + SsY) >> SsY;
|
||||
UvAlignedWidth = uvWidth;
|
||||
UvAlignedHeight = uvHeight;
|
||||
UvStride = uvStride;
|
||||
|
||||
ArrayPtr<byte> NewPlane(int start, int size, int border)
|
||||
ArrayPtr<byte> NewPlane(int start, int size, int planeBorder)
|
||||
{
|
||||
return new ArrayPtr<byte>(pointer + start + border, size - border);
|
||||
return new ArrayPtr<byte>(pointer + start + planeBorder, size - planeBorder);
|
||||
}
|
||||
|
||||
YBuffer = NewPlane(0, yplaneSize, (border * yStride) + border);
|
||||
YBuffer = NewPlane(0, yplaneSize, (Border * yStride) + Border);
|
||||
UBuffer = NewPlane(yplaneSize, uvplaneSize, (uvBorderH * uvStride) + uvBorderW);
|
||||
VBuffer = NewPlane(yplaneSize + uvplaneSize, uvplaneSize, (uvBorderH * uvStride) + uvBorderW);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
Marshal.FreeHGlobal(_pointer);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
{
|
||||
int sbCols = MiColsAlignedToSb(mis) >> Constants.MiBlockSizeLog2;
|
||||
int offset = ((idx * sbCols) >> log2) << Constants.MiBlockSizeLog2;
|
||||
|
||||
return Math.Min(offset, mis);
|
||||
}
|
||||
|
||||
|
@ -44,7 +45,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
|
||||
// Checks that the given miRow, miCol and search point
|
||||
// are inside the borders of the tile.
|
||||
public bool IsInside(int miCol, int miRow, int miRows, ref Position miPos)
|
||||
public readonly bool IsInside(int miCol, int miRow, int miRows, ref Position miPos)
|
||||
{
|
||||
return !(miRow + miPos.Row < 0 ||
|
||||
miCol + miPos.Col < MiColStart ||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
{
|
||||
public enum TxMode
|
||||
{
|
||||
Only4X4 = 0, // Only 4x4 transform used
|
||||
Allow8X8 = 1, // Allow block transform size up to 8x8
|
||||
Allow16X16 = 2, // Allow block transform size up to 16x16
|
||||
Allow32X32 = 3, // Allow block transform size up to 32x32
|
||||
Only4X4 = 0, // Only 4x4 transform used
|
||||
Allow8X8 = 1, // Allow block transform size up to 8x8
|
||||
Allow16X16 = 2, // Allow block transform size up to 16x16
|
||||
Allow32X32 = 3, // Allow block transform size up to 32x32
|
||||
TxModeSelect = 4, // Transform specified for each block
|
||||
TxModes = 5
|
||||
TxModes = 5,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
{
|
||||
public enum TxSize
|
||||
{
|
||||
Tx4x4 = 0, // 4x4 transform
|
||||
Tx8x8 = 1, // 8x8 transform
|
||||
Tx4x4 = 0, // 4x4 transform
|
||||
Tx8x8 = 1, // 8x8 transform
|
||||
Tx16x16 = 2, // 16x16 transform
|
||||
Tx32x32 = 3, // 32x32 transform
|
||||
TxSizes = 4
|
||||
TxSizes = 4,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
{
|
||||
internal enum TxType
|
||||
{
|
||||
DctDct = 0, // DCT in both horizontal and vertical
|
||||
AdstDct = 1, // ADST in vertical, DCT in horizontal
|
||||
DctAdst = 2, // DCT in vertical, ADST in horizontal
|
||||
DctDct = 0, // DCT in both horizontal and vertical
|
||||
AdstDct = 1, // ADST in vertical, DCT in horizontal
|
||||
DctAdst = 2, // DCT in vertical, ADST in horizontal
|
||||
AdstAdst = 3, // ADST in both directions
|
||||
TxTypes = 4
|
||||
TxTypes = 4,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
public ArrayPtr<sbyte> AboveSegContext;
|
||||
public ArrayPtr<sbyte> AboveContext;
|
||||
|
||||
public bool FrameIsIntraOnly()
|
||||
public readonly bool FrameIsIntraOnly()
|
||||
{
|
||||
return FrameType == FrameType.KeyFrame || IntraOnly;
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
TileWorkerData = allocator.Allocate<TileWorkerData>(tileCols * tileRows + (maxThreads > 1 ? maxThreads : 0));
|
||||
}
|
||||
|
||||
public void FreeTileWorkerData(MemoryAllocator allocator)
|
||||
public readonly void FreeTileWorkerData(MemoryAllocator allocator)
|
||||
{
|
||||
allocator.Free(TileWorkerData);
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
}
|
||||
}
|
||||
|
||||
private void SetPartitionProbs(ref MacroBlockD xd)
|
||||
private readonly void SetPartitionProbs(ref MacroBlockD xd)
|
||||
{
|
||||
xd.PartitionProbs = FrameIsIntraOnly()
|
||||
? new ArrayPtr<Array3<byte>>(ref Fc.Value.KfPartitionProb[0], 16)
|
||||
|
@ -293,7 +293,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
|
||||
public void SetupSegmentationDequant()
|
||||
{
|
||||
const BitDepth bitDepth = BitDepth.Bits8; // TODO: Configurable
|
||||
const BitDepth BitDepth = BitDepth.Bits8; // TODO: Configurable
|
||||
// Build y/uv dequant values based on segmentation.
|
||||
if (Seg.Enabled)
|
||||
{
|
||||
|
@ -301,10 +301,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
for (i = 0; i < Constants.MaxSegments; ++i)
|
||||
{
|
||||
int qIndex = QuantCommon.GetQIndex(ref Seg, i, BaseQindex);
|
||||
YDequant[i][0] = QuantCommon.DcQuant(qIndex, YDcDeltaQ, bitDepth);
|
||||
YDequant[i][1] = QuantCommon.AcQuant(qIndex, 0, bitDepth);
|
||||
UvDequant[i][0] = QuantCommon.DcQuant(qIndex, UvDcDeltaQ, bitDepth);
|
||||
UvDequant[i][1] = QuantCommon.AcQuant(qIndex, UvAcDeltaQ, bitDepth);
|
||||
YDequant[i][0] = QuantCommon.DcQuant(qIndex, YDcDeltaQ, BitDepth);
|
||||
YDequant[i][1] = QuantCommon.AcQuant(qIndex, 0, BitDepth);
|
||||
UvDequant[i][0] = QuantCommon.DcQuant(qIndex, UvDcDeltaQ, BitDepth);
|
||||
UvDequant[i][1] = QuantCommon.AcQuant(qIndex, UvAcDeltaQ, BitDepth);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -312,10 +312,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|||
int qIndex = BaseQindex;
|
||||
// When segmentation is disabled, only the first value is used. The
|
||||
// remaining are don't cares.
|
||||
YDequant[0][0] = QuantCommon.DcQuant(qIndex, YDcDeltaQ, bitDepth);
|
||||
YDequant[0][1] = QuantCommon.AcQuant(qIndex, 0, bitDepth);
|
||||
UvDequant[0][0] = QuantCommon.DcQuant(qIndex, UvDcDeltaQ, bitDepth);
|
||||
UvDequant[0][1] = QuantCommon.AcQuant(qIndex, UvAcDeltaQ, bitDepth);
|
||||
YDequant[0][0] = QuantCommon.DcQuant(qIndex, YDcDeltaQ, BitDepth);
|
||||
YDequant[0][1] = QuantCommon.AcQuant(qIndex, 0, BitDepth);
|
||||
UvDequant[0][0] = QuantCommon.DcQuant(qIndex, UvDcDeltaQ, BitDepth);
|
||||
UvDequant[0][1] = QuantCommon.AcQuant(qIndex, UvAcDeltaQ, BitDepth);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue