Compare commits
13 Commits
Canary-1.2
...
810b3eecb8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
810b3eecb8 | ||
|
|
c2ed0fd5fd | ||
|
|
de16d8fa3e | ||
|
|
9b1fb3a27b | ||
|
|
b9150a0092 | ||
|
|
c1002d4826 | ||
|
|
b1de7696ee | ||
|
|
0282b216fd | ||
|
|
f2ade5f1f8 | ||
|
|
965fb9dd5f | ||
|
|
e2a5e69f4c | ||
|
|
7f27b791f8 | ||
|
|
3ca8618f5f |
@@ -42,7 +42,7 @@
|
||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||
<PackageVersion Include="Gommon" Version="2.7.1" />
|
||||
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace ARMeilleure.Translation.Cache
|
||||
private static readonly Lock _lock = new();
|
||||
private static bool _initialized;
|
||||
|
||||
private static readonly List<ReservedRegion> _jitRegions = new();
|
||||
private static readonly List<ReservedRegion> _jitRegions = [];
|
||||
private static int _activeRegionIndex = 0;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
@@ -180,7 +180,7 @@ namespace ARMeilleure.Translation.Cache
|
||||
}
|
||||
|
||||
int exhaustedRegion = _activeRegionIndex;
|
||||
var newRegion = new ReservedRegion(_jitRegions[0].Allocator, CacheSize);
|
||||
ReservedRegion newRegion = new(_jitRegions[0].Allocator, CacheSize);
|
||||
_jitRegions.Add(newRegion);
|
||||
_activeRegionIndex = _jitRegions.Count - 1;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
||||
|
||||
private static readonly Lock _lock = new();
|
||||
private static bool _initialized;
|
||||
private static readonly List<ReservedRegion> _jitRegions = new();
|
||||
private static readonly List<ReservedRegion> _jitRegions = [];
|
||||
private static int _activeRegionIndex = 0;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
||||
|
||||
// Make sure all pending uniform buffer data is written to memory.
|
||||
_3dEngine.FlushUboDirty();
|
||||
|
||||
|
||||
uint qmdAddress = _state.State.SendPcasA;
|
||||
|
||||
ComputeQmd qmd = _channel.MemoryManager.Read<ComputeQmd>((ulong)qmdAddress << 8);
|
||||
@@ -106,6 +106,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
||||
ulong shaderGpuVa = ((ulong)_state.State.SetProgramRegionAAddressUpper << 32) | _state.State.SetProgramRegionB;
|
||||
|
||||
shaderGpuVa += (uint)qmd.ProgramOffset;
|
||||
|
||||
ShaderCache shaderCache = memoryManager.GetBackingMemory(shaderGpuVa).ShaderCache;
|
||||
|
||||
int localMemorySize = qmd.ShaderLocalMemoryLowSize + qmd.ShaderLocalMemoryHighSize;
|
||||
|
||||
@@ -142,7 +144,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
||||
sharedMemorySize,
|
||||
_channel.BufferManager.HasUnalignedStorageBuffers);
|
||||
|
||||
CachedShaderProgram cs = memoryManager.Physical.ShaderCache.GetComputeShader(_channel, samplerPoolMaximumId, poolState, computeState, shaderGpuVa);
|
||||
CachedShaderProgram cs = shaderCache.GetComputeShader(_channel, samplerPoolMaximumId, poolState, computeState, shaderGpuVa);
|
||||
|
||||
_context.Renderer.Pipeline.SetProgram(cs.HostProgram);
|
||||
|
||||
@@ -156,10 +158,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
||||
{
|
||||
BufferDescriptor sb = info.SBuffers[index];
|
||||
|
||||
ulong sbDescAddress = _channel.BufferManager.GetComputeUniformBufferAddress(sb.SbCbSlot);
|
||||
(PhysicalMemory physical, ulong sbDescAddress) = _channel.BufferManager.GetComputeUniformBufferAddress(sb.SbCbSlot);
|
||||
sbDescAddress += (ulong)sb.SbCbOffset * 4;
|
||||
|
||||
SbDescriptor sbDescriptor = _channel.MemoryManager.Physical.Read<SbDescriptor>(sbDescAddress);
|
||||
SbDescriptor sbDescriptor = physical.Read<SbDescriptor>(sbDescAddress);
|
||||
|
||||
uint size;
|
||||
if (sb.SbCbSlot == Constants.DriverReservedUniformBuffer)
|
||||
@@ -187,7 +189,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
||||
sharedMemorySize,
|
||||
_channel.BufferManager.HasUnalignedStorageBuffers);
|
||||
|
||||
cs = memoryManager.Physical.ShaderCache.GetComputeShader(_channel, samplerPoolMaximumId, poolState, computeState, shaderGpuVa);
|
||||
cs = shaderCache.GetComputeShader(_channel, samplerPoolMaximumId, poolState, computeState, shaderGpuVa);
|
||||
|
||||
_context.Renderer.Pipeline.SetProgram(cs.HostProgram);
|
||||
}
|
||||
|
||||
@@ -215,7 +215,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
_channel.TextureManager.RefreshModifiedTextures();
|
||||
_3dEngine.CreatePendingSyncs();
|
||||
_3dEngine.FlushUboDirty();
|
||||
|
||||
|
||||
PhysicalMemory srcPhysical = memoryManager.GetBackingMemory(srcGpuVa);
|
||||
PhysicalMemory dstPhysical = memoryManager.GetBackingMemory(dstGpuVa);
|
||||
|
||||
if (copy2D)
|
||||
{
|
||||
// Buffer to texture copy.
|
||||
@@ -293,7 +296,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
|
||||
if (completeSource && completeDest && !srcLinear && isIdentityRemap)
|
||||
{
|
||||
Image.Texture source = memoryManager.Physical.TextureCache.FindTexture(
|
||||
Image.Texture source = srcPhysical.TextureCache.FindTexture(
|
||||
memoryManager,
|
||||
srcGpuVa,
|
||||
srcBpp,
|
||||
@@ -309,7 +312,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
{
|
||||
source.SynchronizeMemory();
|
||||
|
||||
Image.Texture target = memoryManager.Physical.TextureCache.FindOrCreateTexture(
|
||||
Image.Texture target = dstPhysical.TextureCache.FindOrCreateTexture(
|
||||
memoryManager,
|
||||
source.Info.FormatInfo,
|
||||
dstGpuVa,
|
||||
@@ -339,7 +342,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
|
||||
if (completeSource && completeDest && !(dstLinear && !srcLinear) && isIdentityRemap)
|
||||
{
|
||||
Image.Texture target = memoryManager.Physical.TextureCache.FindTexture(
|
||||
Image.Texture target = dstPhysical.TextureCache.FindTexture(
|
||||
memoryManager,
|
||||
dstGpuVa,
|
||||
dstBpp,
|
||||
@@ -462,6 +465,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferCache bufferCache = dstPhysical.BufferCache;
|
||||
if (remap &&
|
||||
_state.State.SetRemapComponentsDstX == SetRemapComponentsDst.ConstA &&
|
||||
_state.State.SetRemapComponentsDstY == SetRemapComponentsDst.ConstA &&
|
||||
@@ -472,7 +476,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
_state.State.SetRemapComponentsComponentSize == SetRemapComponentsComponentSize.Four)
|
||||
{
|
||||
// Fast path for clears when remap is enabled.
|
||||
memoryManager.Physical.BufferCache.ClearBuffer(memoryManager, dstGpuVa, size * 4, _state.State.SetRemapConstA);
|
||||
bufferCache.ClearBuffer(memoryManager, dstGpuVa, size * 4, _state.State.SetRemapConstA);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -492,7 +496,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
}
|
||||
else
|
||||
{
|
||||
memoryManager.Physical.BufferCache.CopyBuffer(memoryManager, srcGpuVa, dstGpuVa, size);
|
||||
BufferCache.CopyBuffer(_context,memoryManager, srcGpuVa, dstGpuVa, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
||||
// Right now the copy code at the bottom assumes that it is used on both which might be incorrect.
|
||||
if (!_isLinear)
|
||||
{
|
||||
Image.Texture target = memoryManager.Physical.TextureCache.FindTexture(
|
||||
Image.Texture target = memoryManager.GetBackingMemory(_dstGpuVa).TextureCache.FindTexture(
|
||||
memoryManager,
|
||||
_dstGpuVa,
|
||||
1,
|
||||
|
||||
@@ -384,7 +384,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
||||
|
||||
ulong indirectBufferGpuVa = count.GpuVa;
|
||||
|
||||
BufferCache bufferCache = _processor.MemoryManager.Physical.BufferCache;
|
||||
BufferCache bufferCache = _processor.MemoryManager.GetBackingMemory(indirectBufferGpuVa).BufferCache;
|
||||
|
||||
bool useBuffer = bufferCache.CheckModified(_processor.MemoryManager, indirectBufferGpuVa, IndirectIndexedDataEntrySize, out ulong indirectBufferAddress);
|
||||
|
||||
@@ -394,6 +394,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
||||
|
||||
_processor.ThreedClass.DrawIndirect(
|
||||
topology,
|
||||
bufferCache,
|
||||
null,
|
||||
new MultiRange(indirectBufferAddress, IndirectIndexedDataEntrySize),
|
||||
default,
|
||||
1,
|
||||
@@ -491,22 +493,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferCache bufferCache = _processor.MemoryManager.Physical.BufferCache;
|
||||
BufferCache indirectBufferCache = _processor.MemoryManager.GetBackingMemory(indirectBufferGpuVa).BufferCache;
|
||||
BufferCache parameterBufferCache = _processor.MemoryManager.GetBackingMemory(parameterBufferGpuVa).BufferCache;
|
||||
|
||||
ulong indirectBufferSize = (ulong)maxDrawCount * (ulong)stride;
|
||||
|
||||
MultiRange indirectBufferRange = bufferCache.TranslateAndCreateMultiBuffers(_processor.MemoryManager, indirectBufferGpuVa, indirectBufferSize, BufferStage.Indirect);
|
||||
MultiRange parameterBufferRange = bufferCache.TranslateAndCreateMultiBuffers(_processor.MemoryManager, parameterBufferGpuVa, 4, BufferStage.Indirect);
|
||||
MultiRange indirectBufferRange = indirectBufferCache.TranslateAndCreateMultiBuffers(_processor.MemoryManager, indirectBufferGpuVa, indirectBufferSize, BufferStage.Indirect);
|
||||
MultiRange parameterBufferRange = parameterBufferCache.TranslateAndCreateMultiBuffers(_processor.MemoryManager, parameterBufferGpuVa, 4, BufferStage.Indirect);
|
||||
|
||||
_processor.ThreedClass.DrawIndirect(
|
||||
topology,
|
||||
indirectBufferCache,
|
||||
parameterBufferCache,
|
||||
indirectBufferRange,
|
||||
parameterBufferRange,
|
||||
maxDrawCount,
|
||||
stride,
|
||||
indexCount,
|
||||
Threed.IndirectDrawType.DrawIndexedIndirectCount);
|
||||
IndirectDrawType.DrawIndexedIndirectCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
/// </summary>
|
||||
class VtgAsComputeContext : IDisposable
|
||||
{
|
||||
private const int DummyBufferSize = 16;
|
||||
|
||||
private readonly GpuContext _context;
|
||||
|
||||
/// <summary>
|
||||
@@ -46,7 +48,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
format.GetBytesPerElement(),
|
||||
1,
|
||||
format,
|
||||
DepthStencilMode.Depth,
|
||||
Target.TextureBuffer,
|
||||
@@ -519,6 +521,21 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
return new BufferRange(_geometryIndexDataBuffer.Handle, offset, size, write);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the range for a dummy 16 bytes buffer, filled with zeros.
|
||||
/// </summary>
|
||||
/// <returns>Dummy buffer range</returns>
|
||||
public BufferRange GetDummyBufferRange()
|
||||
{
|
||||
if (_dummyBuffer == BufferHandle.Null)
|
||||
{
|
||||
_dummyBuffer = _context.Renderer.CreateBuffer(DummyBufferSize, BufferAccess.DeviceMemory);
|
||||
_context.Renderer.Pipeline.ClearBuffer(_dummyBuffer, 0, DummyBufferSize, 0);
|
||||
}
|
||||
|
||||
return new BufferRange(_dummyBuffer, 0, DummyBufferSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the range for a sequential index buffer, with ever incrementing index values.
|
||||
/// </summary>
|
||||
|
||||
@@ -147,6 +147,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
{
|
||||
_vacContext.VertexInfoBufferUpdater.SetVertexStride(index, 0, componentsCount);
|
||||
_vacContext.VertexInfoBufferUpdater.SetVertexOffset(index, 0, 0);
|
||||
SetDummyBufferTexture(_vertexAsCompute.Reservations, index, format);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -162,12 +163,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
{
|
||||
_vacContext.VertexInfoBufferUpdater.SetVertexStride(index, 0, componentsCount);
|
||||
_vacContext.VertexInfoBufferUpdater.SetVertexOffset(index, 0, 0);
|
||||
SetDummyBufferTexture(_vertexAsCompute.Reservations, index, format);
|
||||
continue;
|
||||
}
|
||||
|
||||
int vbStride = vertexBuffer.UnpackStride();
|
||||
ulong vbSize = GetVertexBufferSize(address, endAddress.Pack(), vbStride, _indexed, instanced, _firstVertex, _count);
|
||||
|
||||
ulong oldVbSize = vbSize;
|
||||
|
||||
ulong attributeOffset = (ulong)vertexAttrib.UnpackOffset();
|
||||
int componentSize = format.GetScalarSize();
|
||||
|
||||
@@ -196,11 +200,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
|
||||
int vertexInfoBinding = _vertexAsCompute.Reservations.VertexInfoConstantBufferBinding;
|
||||
BufferRange vertexInfoRange = new(_vacContext.VertexInfoBufferUpdater.Handle, 0, VertexInfoBuffer.RequiredSize);
|
||||
_context.Renderer.Pipeline.SetUniformBuffers([new BufferAssignment(vertexInfoBinding, vertexInfoRange)]);
|
||||
_context.Renderer.Pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(vertexInfoBinding, vertexInfoRange) });
|
||||
|
||||
int vertexDataBinding = _vertexAsCompute.Reservations.VertexOutputStorageBufferBinding;
|
||||
BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize, write: true);
|
||||
_context.Renderer.Pipeline.SetStorageBuffers([new BufferAssignment(vertexDataBinding, vertexDataRange)]);
|
||||
_context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexDataRange) });
|
||||
|
||||
_vacContext.VertexInfoBufferUpdater.Commit();
|
||||
|
||||
@@ -228,7 +232,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
|
||||
int vertexInfoBinding = _vertexAsCompute.Reservations.VertexInfoConstantBufferBinding;
|
||||
BufferRange vertexInfoRange = new(_vacContext.VertexInfoBufferUpdater.Handle, 0, VertexInfoBuffer.RequiredSize);
|
||||
_context.Renderer.Pipeline.SetUniformBuffers([new BufferAssignment(vertexInfoBinding, vertexInfoRange)]);
|
||||
_context.Renderer.Pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(vertexInfoBinding, vertexInfoRange) });
|
||||
|
||||
int vertexDataBinding = _vertexAsCompute.Reservations.VertexOutputStorageBufferBinding;
|
||||
|
||||
@@ -246,11 +250,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
BufferRange vertexBuffer = _vacContext.GetGeometryVertexDataBufferRange(_geometryVertexDataOffset, _geometryVertexDataSize, write: true);
|
||||
BufferRange indexBuffer = _vacContext.GetGeometryIndexDataBufferRange(_geometryIndexDataOffset, _geometryIndexDataSize, write: true);
|
||||
|
||||
_context.Renderer.Pipeline.SetStorageBuffers([
|
||||
_context.Renderer.Pipeline.SetStorageBuffers(stackalloc[]
|
||||
{
|
||||
new BufferAssignment(vertexDataBinding, vertexDataRange),
|
||||
new BufferAssignment(geometryVbBinding, vertexBuffer),
|
||||
new BufferAssignment(geometryIbBinding, indexBuffer)
|
||||
]);
|
||||
new BufferAssignment(geometryIbBinding, indexBuffer),
|
||||
});
|
||||
|
||||
_context.Renderer.Pipeline.DispatchCompute(
|
||||
BitUtils.DivRoundUp(primitivesCount, ComputeLocalSize),
|
||||
@@ -294,7 +299,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
|
||||
_context.Renderer.Pipeline.SetProgram(_vertexPassthroughProgram);
|
||||
_context.Renderer.Pipeline.SetIndexBuffer(indexBuffer, IndexType.UInt);
|
||||
_context.Renderer.Pipeline.SetStorageBuffers([new BufferAssignment(vertexDataBinding, vertexBuffer)]);
|
||||
_context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexBuffer) });
|
||||
|
||||
_context.Renderer.Pipeline.SetPrimitiveRestart(true, -1);
|
||||
_context.Renderer.Pipeline.SetPrimitiveTopology(GetGeometryOutputTopology(_geometryAsCompute.Info.GeometryVerticesPerPrimitive));
|
||||
@@ -309,7 +314,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize, write: false);
|
||||
|
||||
_context.Renderer.Pipeline.SetProgram(_vertexPassthroughProgram);
|
||||
_context.Renderer.Pipeline.SetStorageBuffers([new BufferAssignment(vertexDataBinding, vertexDataRange)]);
|
||||
_context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexDataRange) });
|
||||
_context.Renderer.Pipeline.Draw(_count, _instanceCount, 0, 0);
|
||||
}
|
||||
}
|
||||
@@ -340,6 +345,20 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
return maxOutputVertices / verticesPerPrimitive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Binds a dummy buffer as vertex buffer into a buffer texture.
|
||||
/// </summary>
|
||||
/// <param name="reservations">Shader resource binding reservations</param>
|
||||
/// <param name="index">Buffer texture index</param>
|
||||
/// <param name="format">Buffer texture format</param>
|
||||
private readonly void SetDummyBufferTexture(ResourceReservations reservations, int index, Format format)
|
||||
{
|
||||
ITexture bufferTexture = _vacContext.EnsureBufferTexture(index + 2, format);
|
||||
bufferTexture.SetStorage(_vacContext.GetDummyBufferRange());
|
||||
|
||||
_context.Renderer.Pipeline.SetTextureAndSampler(ShaderStage.Compute, reservations.GetVertexBufferTextureBinding(index), bufferTexture, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Binds a vertex buffer into a buffer texture.
|
||||
/// </summary>
|
||||
@@ -352,7 +371,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
{
|
||||
MemoryManager memoryManager = _channel.MemoryManager;
|
||||
|
||||
BufferRange range = memoryManager.Physical.BufferCache.GetBufferRange(memoryManager.GetPhysicalRegions(address, size), BufferStage.VertexBuffer);
|
||||
BufferRange range = memoryManager.GetBackingMemory(address).BufferCache.GetBufferRange(memoryManager.GetPhysicalRegions(address, size), BufferStage.VertexBuffer);
|
||||
|
||||
ITexture bufferTexture = _vacContext.EnsureBufferTexture(index + 2, format);
|
||||
bufferTexture.SetStorage(range);
|
||||
@@ -394,7 +413,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||
MemoryManager memoryManager = _channel.MemoryManager;
|
||||
|
||||
ulong misalign = address & ((ulong)_context.Capabilities.TextureBufferOffsetAlignment - 1);
|
||||
BufferRange range = memoryManager.Physical.BufferCache.GetBufferRange(
|
||||
BufferRange range = memoryManager.GetBackingMemory(address).BufferCache.GetBufferRange(
|
||||
memoryManager.GetPhysicalRegions(address + indexOffset - misalign, size + misalign),
|
||||
BufferStage.IndexBuffer);
|
||||
misalignedOffset = (int)misalign >> shift;
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
|
||||
// State associated with direct uniform buffer updates.
|
||||
// This state is used to attempt to batch together consecutive updates.
|
||||
private ulong _ubBeginGpuAddress = 0;
|
||||
private ulong _ubBeginCpuAddress = 0;
|
||||
private ulong _ubFollowUpAddress = 0;
|
||||
private ulong _ubByteCount = 0;
|
||||
@@ -113,12 +114,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
if (_ubFollowUpAddress != 0)
|
||||
{
|
||||
MemoryManager memoryManager = _channel.MemoryManager;
|
||||
PhysicalMemory physicalMemory = memoryManager.GetBackingMemory(_ubBeginGpuAddress);
|
||||
|
||||
Span<byte> data = MemoryMarshal.Cast<int, byte>(_ubData.AsSpan(0, (int)(_ubByteCount / 4)));
|
||||
|
||||
if (memoryManager.Physical.WriteWithRedundancyCheck(_ubBeginCpuAddress, data))
|
||||
if (physicalMemory.WriteWithRedundancyCheck(_ubBeginCpuAddress, data))
|
||||
{
|
||||
memoryManager.Physical.BufferCache.ForceDirty(memoryManager, _ubFollowUpAddress - _ubByteCount, _ubByteCount);
|
||||
physicalMemory.BufferCache.ForceDirty(memoryManager, _ubFollowUpAddress - _ubByteCount, _ubByteCount);
|
||||
}
|
||||
|
||||
_ubFollowUpAddress = 0;
|
||||
|
||||
@@ -641,6 +641,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
public void DrawIndirect(
|
||||
ThreedClass engine,
|
||||
PrimitiveTopology topology,
|
||||
BufferCache indirectBufferCache,
|
||||
BufferCache parameterBufferCache,
|
||||
MultiRange indirectBufferRange,
|
||||
MultiRange parameterBufferRange,
|
||||
int maxDrawCount,
|
||||
@@ -662,8 +664,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
return;
|
||||
}
|
||||
|
||||
PhysicalMemory memory = _channel.MemoryManager.Physical;
|
||||
|
||||
bool hasCount = (drawType & IndirectDrawType.Count) != 0;
|
||||
bool indexed = (drawType & IndirectDrawType.Indexed) != 0;
|
||||
|
||||
@@ -684,8 +684,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
|
||||
if (hasCount)
|
||||
{
|
||||
BufferRange indirectBuffer = memory.BufferCache.GetBufferRange(indirectBufferRange, BufferStage.Indirect);
|
||||
BufferRange parameterBuffer = memory.BufferCache.GetBufferRange(parameterBufferRange, BufferStage.Indirect);
|
||||
BufferRange indirectBuffer = indirectBufferCache.GetBufferRange(indirectBufferRange, BufferStage.Indirect);
|
||||
BufferRange parameterBuffer = parameterBufferCache.GetBufferRange(parameterBufferRange, BufferStage.Indirect);
|
||||
|
||||
if (indexed)
|
||||
{
|
||||
@@ -698,7 +698,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferRange indirectBuffer = memory.BufferCache.GetBufferRange(indirectBufferRange, BufferStage.Indirect);
|
||||
BufferRange indirectBuffer = indirectBufferCache.GetBufferRange(indirectBufferRange, BufferStage.Indirect);
|
||||
|
||||
if (indexed)
|
||||
{
|
||||
@@ -913,7 +913,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
|
||||
Span<Rectangle<int>> scissors =
|
||||
[
|
||||
new Rectangle<int>(scissorX, scissorY, scissorW, scissorH)
|
||||
new(scissorX, scissorY, scissorW, scissorH)
|
||||
];
|
||||
|
||||
_context.Renderer.Pipeline.SetScissors(scissors);
|
||||
|
||||
@@ -381,10 +381,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
{
|
||||
BufferDescriptor sb = info.SBuffers[index];
|
||||
|
||||
ulong sbDescAddress = _channel.BufferManager.GetGraphicsUniformBufferAddress(stage, sb.SbCbSlot);
|
||||
(PhysicalMemory physical, ulong sbDescAddress) = _channel.BufferManager.GetGraphicsUniformBufferAddress(stage, sb.SbCbSlot);
|
||||
sbDescAddress += (ulong)sb.SbCbOffset * 4;
|
||||
|
||||
SbDescriptor sbDescriptor = _channel.MemoryManager.Physical.Read<SbDescriptor>(sbDescAddress);
|
||||
SbDescriptor sbDescriptor = physical.Read<SbDescriptor>(sbDescAddress);
|
||||
|
||||
uint size;
|
||||
if (sb.SbCbSlot == Constants.DriverReservedUniformBuffer)
|
||||
@@ -505,7 +505,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
rtNoAlphaMask |= 1u << index;
|
||||
}
|
||||
|
||||
Image.Texture color = memoryManager.Physical.TextureCache.FindOrCreateTexture(
|
||||
TextureCache colorTextureCache = memoryManager.GetBackingMemory(colorState.Address.Pack()).TextureCache;
|
||||
|
||||
Image.Texture color = colorTextureCache.FindOrCreateTexture(
|
||||
memoryManager,
|
||||
colorState,
|
||||
_vtgWritesRtLayer || layered,
|
||||
@@ -513,7 +515,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
samplesInX,
|
||||
samplesInY,
|
||||
sizeHint);
|
||||
|
||||
|
||||
changedScale |= _channel.TextureManager.SetRenderTargetColor(index, color);
|
||||
|
||||
if (color != null)
|
||||
@@ -543,8 +545,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
{
|
||||
RtDepthStencilState dsState = _state.State.RtDepthStencilState;
|
||||
Size3D dsSize = _state.State.RtDepthStencilSize;
|
||||
|
||||
depthStencil = memoryManager.Physical.TextureCache.FindOrCreateTexture(
|
||||
TextureCache dsTextureCache = memoryManager.GetBackingMemory(dsState.Address.Pack()).TextureCache;
|
||||
|
||||
depthStencil = dsTextureCache.FindOrCreateTexture(
|
||||
memoryManager,
|
||||
dsState,
|
||||
dsSize,
|
||||
@@ -1409,8 +1412,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
private void UpdateShaderState()
|
||||
{
|
||||
ShaderCache shaderCache = _channel.MemoryManager.Physical.ShaderCache;
|
||||
|
||||
_vtgWritesRtLayer = false;
|
||||
|
||||
ShaderAddresses addresses = new();
|
||||
@@ -1433,6 +1434,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
? _state.State.TexturePoolState.MaximumId
|
||||
: _state.State.SamplerPoolState.MaximumId;
|
||||
|
||||
// Shader stages on different address spaces are not supported right now,
|
||||
// but it should never happen in practice anyway.
|
||||
ShaderCache shaderCache = _channel.MemoryManager.GetBackingMemory(addresses.VertexB).ShaderCache;
|
||||
CachedShaderProgram gs = shaderCache.GetGraphicsShader(
|
||||
ref _state.State,
|
||||
ref _pipeline,
|
||||
|
||||
@@ -5,6 +5,7 @@ using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
||||
using Ryujinx.Graphics.Gpu.Engine.InlineToMemory;
|
||||
using Ryujinx.Graphics.Gpu.Engine.Threed.Blender;
|
||||
using Ryujinx.Graphics.Gpu.Engine.Types;
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
using Ryujinx.Graphics.Gpu.Synchronization;
|
||||
using Ryujinx.Memory.Range;
|
||||
using System;
|
||||
@@ -804,6 +805,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// Performs a indirect draw, with parameters from a GPU buffer.
|
||||
/// </summary>
|
||||
/// <param name="topology">Primitive topology</param>
|
||||
/// <param name="indirectBufferCache">Buffer cache owning the buffer with the draw parameters</param>
|
||||
/// <param name="parameterBufferCache">Buffer cache owning the buffer with the draw count</param>
|
||||
/// <param name="indirectBufferRange">Memory range of the buffer with the draw parameters, such as count, first index, etc</param>
|
||||
/// <param name="parameterBufferRange">Memory range of the buffer with the draw count</param>
|
||||
/// <param name="maxDrawCount">Maximum number of draws that can be made</param>
|
||||
@@ -812,6 +815,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// <param name="drawType">Type of the indirect draw, which can be indexed or non-indexed, with or without a draw count</param>
|
||||
public void DrawIndirect(
|
||||
PrimitiveTopology topology,
|
||||
BufferCache indirectBufferCache,
|
||||
BufferCache parameterBufferCache,
|
||||
MultiRange indirectBufferRange,
|
||||
MultiRange parameterBufferRange,
|
||||
int maxDrawCount,
|
||||
@@ -819,7 +824,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
int indexCount,
|
||||
IndirectDrawType drawType)
|
||||
{
|
||||
_drawManager.DrawIndirect(this, topology, indirectBufferRange, parameterBufferRange, maxDrawCount, stride, indexCount, drawType);
|
||||
_drawManager.DrawIndirect(this, topology, indirectBufferCache, parameterBufferCache, indirectBufferRange, parameterBufferRange, maxDrawCount, stride, indexCount, drawType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -233,6 +233,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
||||
|
||||
TwodTexture dstCopyTexture = Unsafe.As<uint, TwodTexture>(ref _state.State.SetDstFormat);
|
||||
TwodTexture srcCopyTexture = Unsafe.As<uint, TwodTexture>(ref _state.State.SetSrcFormat);
|
||||
|
||||
TextureCache srcTextureCache = memoryManager.GetBackingMemory(srcCopyTexture.Address.Pack()).TextureCache;
|
||||
TextureCache dstTextureCache = memoryManager.GetBackingMemory(dstCopyTexture.Address.Pack()).TextureCache;
|
||||
|
||||
long srcX = ((long)_state.State.SetPixelsFromMemorySrcX0Int << 32) | (long)(ulong)_state.State.SetPixelsFromMemorySrcX0Frac;
|
||||
long srcY = ((long)_state.State.PixelsFromMemorySrcY0Int << 32) | (long)(ulong)_state.State.SetPixelsFromMemorySrcY0Frac;
|
||||
@@ -305,7 +308,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
||||
// are the same, as we can't blit between different depth formats.
|
||||
bool srcDepthAlias = srcCopyTexture.Format == dstCopyTexture.Format;
|
||||
|
||||
Image.Texture srcTexture = memoryManager.Physical.TextureCache.FindOrCreateTexture(
|
||||
Image.Texture srcTexture = srcTextureCache.FindOrCreateTexture(
|
||||
memoryManager,
|
||||
srcCopyTexture,
|
||||
offset,
|
||||
@@ -326,7 +329,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
||||
return;
|
||||
}
|
||||
|
||||
memoryManager.Physical.TextureCache.Lift(srcTexture);
|
||||
srcTextureCache.Lift(srcTexture);
|
||||
|
||||
// When the source texture that was found has a depth format,
|
||||
// we must enforce the target texture also has a depth format,
|
||||
@@ -342,7 +345,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
||||
dstCopyTextureFormat = dstCopyTexture.Format.Convert();
|
||||
}
|
||||
|
||||
Image.Texture dstTexture = memoryManager.Physical.TextureCache.FindOrCreateTexture(
|
||||
Image.Texture dstTexture = dstTextureCache.FindOrCreateTexture(
|
||||
memoryManager,
|
||||
dstCopyTexture,
|
||||
0,
|
||||
|
||||
@@ -58,22 +58,24 @@ namespace Ryujinx.Graphics.Gpu
|
||||
public void BindMemory(MemoryManager memoryManager)
|
||||
{
|
||||
MemoryManager oldMemoryManager = Interlocked.Exchange(ref _memoryManager, memoryManager ?? throw new ArgumentNullException(nameof(memoryManager)));
|
||||
if (oldMemoryManager == memoryManager)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memoryManager.Physical.IncrementReferenceCount();
|
||||
memoryManager.AttachToChannel(BufferManager.Rebind);
|
||||
|
||||
if (oldMemoryManager != null)
|
||||
{
|
||||
oldMemoryManager.Physical.BufferCache.NotifyBuffersModified -= BufferManager.Rebind;
|
||||
oldMemoryManager.Physical.DecrementReferenceCount();
|
||||
oldMemoryManager.DetachFromChannel(BufferManager.Rebind);
|
||||
oldMemoryManager.MemoryUnmapped -= MemoryUnmappedHandler;
|
||||
}
|
||||
|
||||
memoryManager.Physical.BufferCache.NotifyBuffersModified += BufferManager.Rebind;
|
||||
memoryManager.MemoryUnmapped += MemoryUnmappedHandler;
|
||||
|
||||
// Since the memory manager changed, make sure we will get pools from addresses of the new memory manager.
|
||||
TextureManager.ReloadPools();
|
||||
memoryManager.Physical.BufferCache.QueuePrune();
|
||||
memoryManager.QueuePrune();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -86,7 +88,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||
TextureManager.ReloadPools();
|
||||
|
||||
MemoryManager memoryManager = Volatile.Read(ref _memoryManager);
|
||||
memoryManager?.Physical.BufferCache.QueuePrune();
|
||||
memoryManager?.QueuePrune();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -141,8 +143,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||
MemoryManager oldMemoryManager = Interlocked.Exchange(ref _memoryManager, null);
|
||||
if (oldMemoryManager != null)
|
||||
{
|
||||
oldMemoryManager.Physical.BufferCache.NotifyBuffersModified -= BufferManager.Rebind;
|
||||
oldMemoryManager.Physical.DecrementReferenceCount();
|
||||
oldMemoryManager.DetachFromChannel(BufferManager.Rebind);
|
||||
oldMemoryManager.MemoryUnmapped -= MemoryUnmappedHandler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
using Ryujinx.Graphics.Gpu.Shader;
|
||||
using Ryujinx.Graphics.Gpu.Synchronization;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@@ -172,7 +173,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||
throw new ArgumentException("The PID is invalid or the process was not registered", nameof(pid));
|
||||
}
|
||||
|
||||
return new MemoryManager(physicalMemory, cpuMemorySize);
|
||||
return new MemoryManager(this, physicalMemory, cpuMemorySize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -197,7 +198,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||
/// <param name="pid">ID of the process that owns <paramref name="cpuMemory"/></param>
|
||||
/// <param name="cpuMemory">Virtual memory owned by the process</param>
|
||||
/// <exception cref="ArgumentException">Thrown if <paramref name="pid"/> was already registered</exception>
|
||||
public void RegisterProcess(ulong pid, Cpu.IVirtualMemoryManagerTracked cpuMemory)
|
||||
public void RegisterProcess(ulong pid, IVirtualMemoryManagerTracked cpuMemory)
|
||||
{
|
||||
PhysicalMemory physicalMemory = new(this, cpuMemory);
|
||||
if (!PhysicalMemoryRegistry.TryAdd(pid, physicalMemory))
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -64,7 +65,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// <param name="maximumId">Maximum ID of the texture pool</param>
|
||||
/// <param name="bindingsArrayCache">Cache of texture array bindings</param>
|
||||
/// <returns>The found or newly created texture pool</returns>
|
||||
public T FindOrCreate(GpuChannel channel, ulong address, int maximumId, TextureBindingsArrayCache bindingsArrayCache)
|
||||
public T FindOrCreate(GpuChannel channel, PhysicalMemory physicalMemory, ulong address, int maximumId, TextureBindingsArrayCache bindingsArrayCache)
|
||||
{
|
||||
// Remove old entries from the cache, if possible.
|
||||
while (_pools.Count > MaxCapacity && (_currentTimestamp - _pools.First.Value.CacheTimestamp) >= MinDeltaForRemoval)
|
||||
@@ -99,7 +100,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
}
|
||||
|
||||
// If not found, create a new one.
|
||||
pool = CreatePool(_context, channel, address, maximumId);
|
||||
pool = CreatePool(_context, channel, physicalMemory, address, maximumId);
|
||||
|
||||
pool.CacheNode = _pools.AddLast(pool);
|
||||
pool.CacheTimestamp = _currentTimestamp;
|
||||
@@ -112,9 +113,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// </summary>
|
||||
/// <param name="context">GPU context that the pool belongs to</param>
|
||||
/// <param name="channel">GPU channel that the pool belongs to</param>
|
||||
/// <param name="physicalMemory">GPU backing memory of the pool</param>
|
||||
/// <param name="address">Address of the pool in guest memory</param>
|
||||
/// <param name="maximumId">Maximum ID of the pool (equal to maximum minus one)</param>
|
||||
protected abstract T CreatePool(GpuContext context, GpuChannel channel, ulong address, int maximumId);
|
||||
protected abstract T CreatePool(GpuContext context, GpuChannel channel, PhysicalMemory physicalMemory, ulong address, int maximumId);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
/// <summary>
|
||||
@@ -20,11 +22,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// </summary>
|
||||
/// <param name="context">GPU context that the sampler pool belongs to</param>
|
||||
/// <param name="channel">GPU channel that the texture pool belongs to</param>
|
||||
/// <param name="physicalMemory">GPU backing memory of the pool</param>
|
||||
/// <param name="address">Address of the sampler pool in guest memory</param>
|
||||
/// <param name="maximumId">Maximum sampler ID of the sampler pool (equal to maximum samplers minus one)</param>
|
||||
protected override SamplerPool CreatePool(GpuContext context, GpuChannel channel, ulong address, int maximumId)
|
||||
protected override SamplerPool CreatePool(GpuContext context, GpuChannel channel, PhysicalMemory physicalMemory, ulong address, int maximumId)
|
||||
{
|
||||
return new SamplerPool(context, channel.MemoryManager.Physical, address, maximumId);
|
||||
return new SamplerPool(context, physicalMemory, address, maximumId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,6 +660,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
ISampler[] samplers = isImage ? null : new ISampler[bindingInfo.ArrayLength];
|
||||
ITexture[] textures = new ITexture[bindingInfo.ArrayLength];
|
||||
BufferCache bufferCache = null;
|
||||
|
||||
for (int index = 0; index < length; index++)
|
||||
{
|
||||
@@ -673,7 +674,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
else
|
||||
{
|
||||
ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(index, bindingInfo.FormatInfo, out texture);
|
||||
|
||||
bufferCache = _channel.MemoryManager.GetBackingMemory(descriptor.UnpackAddress()).BufferCache;
|
||||
if (texture != null)
|
||||
{
|
||||
entry.Textures[texture] = texture.InvalidatedSequence;
|
||||
@@ -702,11 +703,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
// to ensure we're not using a old buffer that was already deleted.
|
||||
if (isImage)
|
||||
{
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, entry.ImageArray, hostTexture, texture.Range, bindingInfo, index);
|
||||
}
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, entry.ImageArray, hostTexture, bufferCache, texture.Range, bindingInfo, index); }
|
||||
else
|
||||
{
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, entry.TextureArray, hostTexture, texture.Range, bindingInfo, index);
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, entry.TextureArray, hostTexture, bufferCache, texture.Range, bindingInfo, index);
|
||||
}
|
||||
}
|
||||
else if (isImage)
|
||||
@@ -797,11 +797,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
return;
|
||||
}
|
||||
|
||||
cachedTextureBuffer = MemoryMarshal.Cast<byte, int>(_channel.MemoryManager.Physical.GetSpan(textureBufferBounds.Range));
|
||||
|
||||
cachedTextureBuffer = MemoryMarshal.Cast<byte, int>(textureBufferBounds.Physical.GetSpan(textureBufferBounds.Range));
|
||||
|
||||
if (separateSamplerBuffer)
|
||||
{
|
||||
cachedSamplerBuffer = MemoryMarshal.Cast<byte, int>(_channel.MemoryManager.Physical.GetSpan(samplerBufferBounds.Range));
|
||||
cachedSamplerBuffer = MemoryMarshal.Cast<byte, int>(samplerBufferBounds.Physical.GetSpan(samplerBufferBounds.Range));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -828,11 +828,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
}
|
||||
else
|
||||
{
|
||||
cachedTextureBuffer = MemoryMarshal.Cast<byte, int>(_channel.MemoryManager.Physical.GetSpan(textureBufferBounds.Range));
|
||||
|
||||
cachedTextureBuffer = MemoryMarshal.Cast<byte, int>(textureBufferBounds.Physical.GetSpan(textureBufferBounds.Range));
|
||||
if (separateSamplerBuffer)
|
||||
{
|
||||
cachedSamplerBuffer = MemoryMarshal.Cast<byte, int>(_channel.MemoryManager.Physical.GetSpan(samplerBufferBounds.Range));
|
||||
cachedSamplerBuffer = MemoryMarshal.Cast<byte, int>(samplerBufferBounds.Physical.GetSpan(samplerBufferBounds.Range));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -901,16 +900,18 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
if (hostTexture != null && texture.Target == Target.TextureBuffer)
|
||||
{
|
||||
BufferCache bufferCache = textureBufferBounds.BufferCache;
|
||||
|
||||
// Ensure that the buffer texture is using the correct buffer as storage.
|
||||
// Buffers are frequently re-created to accommodate larger data, so we need to re-bind
|
||||
// to ensure we're not using a old buffer that was already deleted.
|
||||
if (isImage)
|
||||
{
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, entry.ImageArray, hostTexture, texture.Range, bindingInfo, index);
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, entry.ImageArray, hostTexture, bufferCache, texture.Range, bindingInfo, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, entry.TextureArray, hostTexture, texture.Range, bindingInfo, index);
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, entry.TextureArray, hostTexture, bufferCache, texture.Range, bindingInfo, index);
|
||||
}
|
||||
}
|
||||
else if (isImage)
|
||||
|
||||
@@ -396,7 +396,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
ref BufferBounds bounds = ref _channel.BufferManager.GetUniformBufferBounds(_isCompute, stageIndex, textureBufferIndex);
|
||||
|
||||
cachedTextureBuffer = MemoryMarshal.Cast<byte, int>(_channel.MemoryManager.Physical.GetSpan(bounds.Range));
|
||||
cachedTextureBuffer = MemoryMarshal.Cast<byte, int>(bounds.Physical.GetSpan(bounds.Range));
|
||||
cachedTextureBufferIndex = textureBufferIndex;
|
||||
|
||||
if (samplerBufferIndex == textureBufferIndex)
|
||||
@@ -410,7 +410,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
ref BufferBounds bounds = ref _channel.BufferManager.GetUniformBufferBounds(_isCompute, stageIndex, samplerBufferIndex);
|
||||
|
||||
cachedSamplerBuffer = MemoryMarshal.Cast<byte, int>(_channel.MemoryManager.Physical.GetSpan(bounds.Range));
|
||||
cachedSamplerBuffer = MemoryMarshal.Cast<byte, int>(bounds.Physical.GetSpan(bounds.Range));
|
||||
cachedSamplerBufferIndex = samplerBufferIndex;
|
||||
}
|
||||
}
|
||||
@@ -524,7 +524,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
// Ensure that the buffer texture is using the correct buffer as storage.
|
||||
// Buffers are frequently re-created to accommodate larger data, so we need to re-bind
|
||||
// to ensure we're not using a old buffer that was already deleted.
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, texture.Range, bindingInfo, false);
|
||||
BufferCache bufferCache = _channel.MemoryManager.GetBackingMemory(descriptor.UnpackAddress()).BufferCache;
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, bufferCache, texture.Range, bindingInfo, false);
|
||||
|
||||
// Cache is not used for buffer texture, it must always rebind.
|
||||
state.CachedTexture = null;
|
||||
@@ -659,7 +660,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
// Buffers are frequently re-created to accommodate larger data, so we need to re-bind
|
||||
// to ensure we're not using a old buffer that was already deleted.
|
||||
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, texture.Range, bindingInfo, true);
|
||||
BufferCache bufferCache = _channel.MemoryManager.GetBackingMemory(descriptor.UnpackAddress()).BufferCache;
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, bufferCache, texture.Range, bindingInfo, true);
|
||||
|
||||
// Cache is not used for buffer texture, it must always rebind.
|
||||
state.CachedTexture = null;
|
||||
@@ -715,9 +717,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
int packedId = ReadPackedId(stageIndex, handle, textureBufferIndex, samplerBufferIndex);
|
||||
int textureId = TextureHandle.UnpackTextureId(packedId);
|
||||
|
||||
PhysicalMemory physical = _channel.MemoryManager.GetBackingMemory(poolGpuVa);
|
||||
ulong poolAddress = _channel.MemoryManager.Translate(poolGpuVa);
|
||||
|
||||
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, maximumId, _bindingsArrayCache);
|
||||
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, physical, poolAddress, maximumId, _bindingsArrayCache);
|
||||
|
||||
TextureDescriptor descriptor;
|
||||
|
||||
@@ -751,12 +754,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
(int textureWordOffset, int samplerWordOffset, TextureHandleType handleType) = TextureHandle.UnpackOffsets(wordOffset);
|
||||
|
||||
ulong textureBufferAddress = _isCompute
|
||||
(PhysicalMemory texturePhysicalMemory, ulong textureBufferAddress) = _isCompute
|
||||
? _channel.BufferManager.GetComputeUniformBufferAddress(textureBufferIndex)
|
||||
: _channel.BufferManager.GetGraphicsUniformBufferAddress(stageIndex, textureBufferIndex);
|
||||
|
||||
int handle = textureBufferAddress != MemoryManager.PteUnmapped
|
||||
? _channel.MemoryManager.Physical.Read<int>(textureBufferAddress + (uint)textureWordOffset * 4)
|
||||
? texturePhysicalMemory.Read<int>(textureBufferAddress + (uint)textureWordOffset * 4)
|
||||
: 0;
|
||||
|
||||
// The "wordOffset" (which is really the immediate value used on texture instructions on the shader)
|
||||
@@ -771,12 +774,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
if (handleType != TextureHandleType.SeparateConstantSamplerHandle)
|
||||
{
|
||||
ulong samplerBufferAddress = _isCompute
|
||||
(PhysicalMemory samplerPhysicalMemory, ulong samplerBufferAddress) = _isCompute
|
||||
? _channel.BufferManager.GetComputeUniformBufferAddress(samplerBufferIndex)
|
||||
: _channel.BufferManager.GetGraphicsUniformBufferAddress(stageIndex, samplerBufferIndex);
|
||||
|
||||
samplerHandle = samplerBufferAddress != MemoryManager.PteUnmapped
|
||||
? _channel.MemoryManager.Physical.Read<int>(samplerBufferAddress + (uint)samplerWordOffset * 4)
|
||||
? samplerPhysicalMemory.Read<int>(samplerBufferAddress + (uint)samplerWordOffset * 4)
|
||||
: 0;
|
||||
}
|
||||
else
|
||||
@@ -813,7 +816,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
if (poolAddress != MemoryManager.PteUnmapped)
|
||||
{
|
||||
texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, _texturePoolMaximumId, _bindingsArrayCache);
|
||||
PhysicalMemory physical = _channel.MemoryManager.GetBackingMemory(_texturePoolGpuVa);
|
||||
texturePool = _texturePoolCache.FindOrCreate(_channel, physical, poolAddress, _texturePoolMaximumId, _bindingsArrayCache);
|
||||
_texturePool = texturePool;
|
||||
}
|
||||
}
|
||||
@@ -824,7 +828,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
if (poolAddress != MemoryManager.PteUnmapped)
|
||||
{
|
||||
samplerPool = _samplerPoolCache.FindOrCreate(_channel, poolAddress, _samplerPoolMaximumId, _bindingsArrayCache);
|
||||
PhysicalMemory physical = _channel.MemoryManager.GetBackingMemory(_samplerPoolGpuVa);
|
||||
samplerPool = _samplerPoolCache.FindOrCreate(_channel, physical, poolAddress, _samplerPoolMaximumId, _bindingsArrayCache);
|
||||
_samplerPool = samplerPool;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu.Engine.Types;
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
using Ryujinx.Graphics.Gpu.Shader;
|
||||
using System;
|
||||
|
||||
@@ -385,8 +386,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
public TexturePool GetTexturePool(ulong poolGpuVa, int maximumId)
|
||||
{
|
||||
ulong poolAddress = _channel.MemoryManager.Translate(poolGpuVa);
|
||||
PhysicalMemory physical = _channel.MemoryManager.GetBackingMemory(poolAddress);
|
||||
|
||||
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, maximumId, _bindingsArrayCache);
|
||||
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, physical, poolAddress, maximumId, _bindingsArrayCache);
|
||||
|
||||
return texturePool;
|
||||
}
|
||||
|
||||
@@ -160,9 +160,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// </summary>
|
||||
/// <param name="context">GPU context that the texture pool belongs to</param>
|
||||
/// <param name="channel">GPU channel that the texture pool belongs to</param>
|
||||
/// <param name="physicalMemory">Backing memory of the pool</param>
|
||||
/// <param name="address">Address of the texture pool in guest memory</param>
|
||||
/// <param name="maximumId">Maximum texture ID of the texture pool (equal to maximum textures minus one)</param>
|
||||
public TexturePool(GpuContext context, GpuChannel channel, ulong address, int maximumId) : base(context, channel.MemoryManager.Physical, address, maximumId)
|
||||
public TexturePool(GpuContext context, GpuChannel channel, PhysicalMemory physicalMemory, ulong address, int maximumId) : base(context, physicalMemory, address, maximumId)
|
||||
{
|
||||
_channel = channel;
|
||||
_aliasLists = new Dictionary<Texture, TextureAliasList>();
|
||||
@@ -193,7 +194,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
}
|
||||
|
||||
TextureInfo info = GetInfo(descriptor, out int layerSize);
|
||||
texture = PhysicalMemory.TextureCache.FindOrCreateTexture(_channel.MemoryManager, TextureSearchFlags.ForSampler, info, layerSize);
|
||||
MemoryManager memoryManager = _channel.MemoryManager;
|
||||
TextureCache textureCache = memoryManager.GetBackingMemory(descriptor.UnpackAddress()).TextureCache;
|
||||
texture = textureCache.FindOrCreateTexture(memoryManager, TextureSearchFlags.ForSampler, info, layerSize);
|
||||
|
||||
// If this happens, then the texture address is invalid, we can't add it to the cache.
|
||||
if (texture == null)
|
||||
@@ -421,7 +424,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
continue;
|
||||
}
|
||||
|
||||
MultiRange range = _channel.MemoryManager.Physical.TextureCache.UpdatePartiallyMapped(_channel.MemoryManager, address, texture);
|
||||
TextureCache textureCache = _channel.MemoryManager.GetBackingMemory(address).TextureCache;
|
||||
MultiRange range = textureCache.UpdatePartiallyMapped(_channel.MemoryManager, address, texture);
|
||||
|
||||
// If the texture is not mapped at all, delete its reference.
|
||||
|
||||
@@ -446,7 +450,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
if (!range.Equals(texture.Range))
|
||||
{
|
||||
// Part of the texture was mapped or unmapped. Replace the range and regenerate tracking handles.
|
||||
if (!_channel.MemoryManager.Physical.TextureCache.UpdateMapping(texture, range))
|
||||
if (!textureCache.UpdateMapping(texture, range))
|
||||
{
|
||||
// Texture could not be remapped due to a collision, just delete it.
|
||||
if (Interlocked.Exchange(ref Items[request.ID], null) != null)
|
||||
@@ -481,6 +485,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// <param name="size">Size of the range being invalidated</param>
|
||||
protected override void InvalidateRangeImpl(ulong address, ulong size)
|
||||
{
|
||||
MemoryManager memoryManager = _channel.MemoryManager;
|
||||
ProcessDereferenceQueue();
|
||||
|
||||
ulong endAddress = address + size;
|
||||
@@ -505,7 +510,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
if (texture.HasOneReference())
|
||||
{
|
||||
_channel.MemoryManager.Physical.TextureCache.AddShortCache(texture, ref cachedDescriptor);
|
||||
TextureCache textureCache = memoryManager.GetBackingMemory(descriptor.UnpackAddress()).TextureCache;
|
||||
textureCache.AddShortCache(texture, ref cachedDescriptor);
|
||||
}
|
||||
|
||||
if (Interlocked.Exchange(ref Items[id], null) != null)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
/// <summary>
|
||||
@@ -20,11 +22,17 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// </summary>
|
||||
/// <param name="context">GPU context that the texture pool belongs to</param>
|
||||
/// <param name="channel">GPU channel that the texture pool belongs to</param>
|
||||
/// <param name="physicalMemory">Backing memory of the pool</param>
|
||||
/// <param name="address">Address of the texture pool in guest memory</param>
|
||||
/// <param name="maximumId">Maximum texture ID of the texture pool (equal to maximum textures minus one)</param>
|
||||
protected override TexturePool CreatePool(GpuContext context, GpuChannel channel, ulong address, int maximumId)
|
||||
protected override TexturePool CreatePool(
|
||||
GpuContext context,
|
||||
GpuChannel channel,
|
||||
PhysicalMemory physicalMemory,
|
||||
ulong address,
|
||||
int maximumId)
|
||||
{
|
||||
return new TexturePool(context, channel, address, maximumId);
|
||||
return new TexturePool(context, channel, physicalMemory, address, maximumId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,16 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// </summary>
|
||||
readonly struct BufferBounds : IEquatable<BufferBounds>
|
||||
{
|
||||
/// <summary>
|
||||
/// Physical memory backing the buffer.
|
||||
/// </summary>
|
||||
public PhysicalMemory Physical { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Buffer cache that owns the buffer.
|
||||
/// </summary>
|
||||
public BufferCache BufferCache => Physical.BufferCache;
|
||||
|
||||
/// <summary>
|
||||
/// Physical memory ranges where the buffer is mapped.
|
||||
/// </summary>
|
||||
@@ -29,8 +39,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// </summary>
|
||||
/// <param name="range">Physical memory ranges where the buffer is mapped</param>
|
||||
/// <param name="flags">Buffer usage flags</param>
|
||||
public BufferBounds(MultiRange range, BufferUsageFlags flags = BufferUsageFlags.None)
|
||||
public BufferBounds(PhysicalMemory physical, MultiRange range, BufferUsageFlags flags = BufferUsageFlags.None)
|
||||
{
|
||||
Physical = physical;
|
||||
Range = range;
|
||||
Flags = flags;
|
||||
}
|
||||
|
||||
@@ -735,18 +735,22 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <remarks>
|
||||
/// This does a GPU side copy.
|
||||
/// </remarks>
|
||||
/// <param name="context">GPU context</param>
|
||||
/// <param name="memoryManager">GPU memory manager where the buffer is mapped</param>
|
||||
/// <param name="srcVa">GPU virtual address of the copy source</param>
|
||||
/// <param name="dstVa">GPU virtual address of the copy destination</param>
|
||||
/// <param name="size">Size in bytes of the copy</param>
|
||||
public void CopyBuffer(MemoryManager memoryManager, ulong srcVa, ulong dstVa, ulong size)
|
||||
public static void CopyBuffer(GpuContext context, MemoryManager memoryManager, ulong srcVa, ulong dstVa, ulong size)
|
||||
{
|
||||
MultiRange srcRange = TranslateAndCreateMultiBuffersPhysicalOnly(memoryManager, srcVa, size, BufferStage.Copy);
|
||||
MultiRange dstRange = TranslateAndCreateMultiBuffersPhysicalOnly(memoryManager, dstVa, size, BufferStage.Copy);
|
||||
PhysicalMemory srcPhysical = memoryManager.GetBackingMemory(srcVa);
|
||||
PhysicalMemory dstPhysical = memoryManager.GetBackingMemory(dstVa);
|
||||
|
||||
MultiRange srcRange = srcPhysical.BufferCache.TranslateAndCreateBuffer(memoryManager, srcVa, size, BufferStage.Copy);
|
||||
MultiRange dstRange = dstPhysical.BufferCache.TranslateAndCreateBuffer(memoryManager, dstVa, size, BufferStage.Copy);
|
||||
|
||||
if (srcRange.Count == 1 && dstRange.Count == 1)
|
||||
{
|
||||
CopyBufferSingleRange(memoryManager, srcRange.GetSubRange(0).Address, dstRange.GetSubRange(0).Address, size);
|
||||
CopyBufferSingleRange(context, srcPhysical, dstPhysical, srcRange.GetSubRange(0).Address, dstRange.GetSubRange(0).Address, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -777,7 +781,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
ulong dstSize = dstSubRange.Size - dstOffset;
|
||||
ulong copySize = Math.Min(srcSize, dstSize);
|
||||
|
||||
CopyBufferSingleRange(memoryManager, srcSubRange.Address + srcOffset, dstSubRange.Address + dstOffset, copySize);
|
||||
CopyBufferSingleRange(context, srcPhysical, dstPhysical, srcSubRange.Address + srcOffset, dstSubRange.Address + dstOffset, copySize);
|
||||
|
||||
srcOffset += copySize;
|
||||
dstOffset += copySize;
|
||||
@@ -793,18 +797,26 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// This does a GPU side copy.
|
||||
/// </remarks>
|
||||
/// <param name="memoryManager">GPU memory manager where the buffer is mapped</param>
|
||||
/// <param name="srcPhysical">Physical memory backing the source buffer.</param>
|
||||
/// <param name="dstPhysical">Physical memory backing the destination buffer.</param>
|
||||
/// <param name="srcAddress">Physical address of the copy source</param>
|
||||
/// <param name="dstAddress">Physical address of the copy destination</param>
|
||||
/// <param name="size">Size in bytes of the copy</param>
|
||||
private void CopyBufferSingleRange(MemoryManager memoryManager, ulong srcAddress, ulong dstAddress, ulong size)
|
||||
private static void CopyBufferSingleRange(
|
||||
GpuContext context,
|
||||
PhysicalMemory srcPhysical,
|
||||
PhysicalMemory dstPhysical,
|
||||
ulong srcAddress,
|
||||
ulong dstAddress,
|
||||
ulong size)
|
||||
{
|
||||
Buffer srcBuffer = GetBuffer(srcAddress, size, BufferStage.Copy);
|
||||
Buffer dstBuffer = GetBuffer(dstAddress, size, BufferStage.Copy);
|
||||
Buffer srcBuffer = srcPhysical.BufferCache.GetBuffer(srcAddress, size, BufferStage.Copy);
|
||||
Buffer dstBuffer = dstPhysical.BufferCache.GetBuffer(dstAddress, size, BufferStage.Copy);
|
||||
|
||||
int srcOffset = (int)(srcAddress - srcBuffer.Address);
|
||||
int dstOffset = (int)(dstAddress - dstBuffer.Address);
|
||||
|
||||
_context.Renderer.Pipeline.CopyBuffer(
|
||||
context.Renderer.Pipeline.CopyBuffer(
|
||||
srcBuffer.Handle,
|
||||
dstBuffer.Handle,
|
||||
srcOffset,
|
||||
@@ -820,7 +832,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
// Optimization: If the data being copied is already in memory, then copy it directly instead of flushing from GPU.
|
||||
|
||||
dstBuffer.ClearModified(dstAddress, size);
|
||||
memoryManager.Physical.WriteTrackedResource(dstAddress, memoryManager.Physical.GetSpan(srcAddress, (int)size), ResourceKind.Buffer);
|
||||
dstPhysical.WriteTrackedResource(dstAddress, srcPhysical.GetSpan(srcAddress, (int)size), ResourceKind.Buffer);
|
||||
}
|
||||
|
||||
dstBuffer.CopyToDependantVirtualBuffers(dstAddress, size);
|
||||
@@ -849,7 +861,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
_context.Renderer.Pipeline.ClearBuffer(buffer.Handle, offset, (int)subRange.Size, value);
|
||||
|
||||
memoryManager.Physical.FillTrackedResource(subRange.Address, subRange.Size, value, ResourceKind.Buffer);
|
||||
memoryManager.GetBackingMemory(gpuVa).FillTrackedResource(subRange.Address, subRange.Size, value, ResourceKind.Buffer);
|
||||
|
||||
buffer.CopyToDependantVirtualBuffers(subRange.Address, subRange.Size);
|
||||
}
|
||||
|
||||
@@ -66,18 +66,19 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
Buffers = new BufferBounds[count];
|
||||
Unaligned = new bool[count];
|
||||
|
||||
Buffers.AsSpan().Fill(new BufferBounds(new MultiRange(MemoryManager.PteUnmapped, 0UL)));
|
||||
Buffers.AsSpan().Fill(new BufferBounds(null, new MultiRange(MemoryManager.PteUnmapped, 0UL)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the region of a buffer at a given slot.
|
||||
/// </summary>
|
||||
/// <param name="index">Buffer slot</param>
|
||||
/// <param name="physical">Physical memory backing the buffer</param>
|
||||
/// <param name="range">Physical memory regions where the buffer is mapped</param>
|
||||
/// <param name="flags">Buffer usage flags</param>
|
||||
public void SetBounds(int index, MultiRange range, BufferUsageFlags flags = BufferUsageFlags.None)
|
||||
public void SetBounds(int index, PhysicalMemory physical, MultiRange range, BufferUsageFlags flags = BufferUsageFlags.None)
|
||||
{
|
||||
Buffers[index] = new BufferBounds(range, flags);
|
||||
Buffers[index] = new BufferBounds(physical, range, flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -156,8 +157,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="type">Type of each index buffer element</param>
|
||||
public void SetIndexBuffer(ulong gpuVa, ulong size, IndexType type)
|
||||
{
|
||||
MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size, BufferStage.IndexBuffer);
|
||||
BufferCache bufferCache = _channel.MemoryManager.GetBackingMemory(gpuVa).BufferCache;
|
||||
MultiRange range = bufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size, BufferStage.IndexBuffer);
|
||||
|
||||
_indexBuffer.BufferCache = bufferCache;
|
||||
_indexBuffer.Range = range;
|
||||
_indexBuffer.Type = type;
|
||||
|
||||
@@ -186,11 +189,15 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="divisor">Vertex divisor of the buffer, for instanced draws</param>
|
||||
public void SetVertexBuffer(int index, ulong gpuVa, ulong size, int stride, int divisor)
|
||||
{
|
||||
MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size, BufferStage.VertexBuffer);
|
||||
BufferCache bufferCache = _channel.MemoryManager.GetBackingMemory(gpuVa).BufferCache;
|
||||
MultiRange range = bufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size, BufferStage.VertexBuffer);
|
||||
|
||||
_vertexBuffers[index].Range = range;
|
||||
_vertexBuffers[index].Stride = stride;
|
||||
_vertexBuffers[index].Divisor = divisor;
|
||||
ref VertexBuffer vb = ref _vertexBuffers[index];
|
||||
|
||||
vb.BufferCache = bufferCache;
|
||||
vb.Range = range;
|
||||
vb.Stride = stride;
|
||||
vb.Divisor = divisor;
|
||||
|
||||
_vertexBuffersDirty = true;
|
||||
|
||||
@@ -213,9 +220,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="size">Size in bytes of the transform feedback buffer</param>
|
||||
public void SetTransformFeedbackBuffer(int index, ulong gpuVa, ulong size)
|
||||
{
|
||||
MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateMultiBuffers(_channel.MemoryManager, gpuVa, size, BufferStage.TransformFeedback);
|
||||
PhysicalMemory physical = _channel.MemoryManager.GetBackingMemory(gpuVa);
|
||||
MultiRange range = physical.BufferCache.TranslateAndCreateMultiBuffers(_channel.MemoryManager, gpuVa, size, BufferStage.TransformFeedback);
|
||||
|
||||
_transformFeedbackBuffers[index] = new BufferBounds(range);
|
||||
_transformFeedbackBuffers[index] = new BufferBounds(physical, range);
|
||||
_transformFeedbackBuffersDirty = true;
|
||||
}
|
||||
|
||||
@@ -258,11 +266,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
RecordStorageAlignment(_cpStorageBuffers, index, gpuVa);
|
||||
|
||||
gpuVa = BitUtils.AlignDown<ulong>(gpuVa, (ulong)_context.Capabilities.StorageBufferOffsetAlignment);
|
||||
gpuVa = BitUtils.AlignDown(gpuVa, (ulong)_context.Capabilities.StorageBufferOffsetAlignment);
|
||||
|
||||
MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateMultiBuffers(_channel.MemoryManager, gpuVa, size, BufferStageUtils.ComputeStorage(flags));
|
||||
PhysicalMemory physical = _channel.MemoryManager.GetBackingMemory(gpuVa);
|
||||
MultiRange range = physical.BufferCache.TranslateAndCreateMultiBuffers(_channel.MemoryManager, gpuVa, size, BufferStageUtils.ComputeStorage(flags));
|
||||
|
||||
_cpStorageBuffers.SetBounds(index, range, flags);
|
||||
_cpStorageBuffers.SetBounds(index, physical, range, flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -282,16 +291,17 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
RecordStorageAlignment(buffers, index, gpuVa);
|
||||
|
||||
gpuVa = BitUtils.AlignDown<ulong>(gpuVa, (ulong)_context.Capabilities.StorageBufferOffsetAlignment);
|
||||
gpuVa = BitUtils.AlignDown(gpuVa, (ulong)_context.Capabilities.StorageBufferOffsetAlignment);
|
||||
|
||||
MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateMultiBuffers(_channel.MemoryManager, gpuVa, size, BufferStageUtils.GraphicsStorage(stage, flags));
|
||||
PhysicalMemory physical = _channel.MemoryManager.GetBackingMemory(gpuVa);
|
||||
MultiRange range = physical.BufferCache.TranslateAndCreateMultiBuffers(_channel.MemoryManager, gpuVa, size, BufferStageUtils.GraphicsStorage(stage, flags));
|
||||
|
||||
if (!buffers.Buffers[index].Range.Equals(range))
|
||||
{
|
||||
_gpStorageBuffersDirty = true;
|
||||
}
|
||||
|
||||
buffers.SetBounds(index, range, flags);
|
||||
buffers.SetBounds(index, physical, range, flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -303,9 +313,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="size">Size in bytes of the storage buffer</param>
|
||||
public void SetComputeUniformBuffer(int index, ulong gpuVa, ulong size)
|
||||
{
|
||||
MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size, BufferStage.Compute);
|
||||
PhysicalMemory physical = _channel.MemoryManager.GetBackingMemory(gpuVa);
|
||||
MultiRange range = physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size, BufferStage.Compute);
|
||||
|
||||
_cpUniformBuffers.SetBounds(index, range);
|
||||
_cpUniformBuffers.SetBounds(index, physical, range);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -318,9 +329,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="size">Size in bytes of the storage buffer</param>
|
||||
public void SetGraphicsUniformBuffer(int stage, int index, ulong gpuVa, ulong size)
|
||||
{
|
||||
MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size, BufferStageUtils.FromShaderStage(stage));
|
||||
PhysicalMemory physical = _channel.MemoryManager.GetBackingMemory(gpuVa);
|
||||
MultiRange range = _channel.MemoryManager.GetBackingMemory(gpuVa).BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size, BufferStageUtils.FromShaderStage(stage));
|
||||
|
||||
_gpUniformBuffers[stage].SetBounds(index, range);
|
||||
_gpUniformBuffers[stage].SetBounds(index, physical, range);
|
||||
_gpUniformBuffersDirty = true;
|
||||
}
|
||||
|
||||
@@ -416,9 +428,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// </summary>
|
||||
/// <param name="index">Index of the uniform buffer binding</param>
|
||||
/// <returns>The uniform buffer address, or an undefined value if the buffer is not currently bound</returns>
|
||||
public ulong GetComputeUniformBufferAddress(int index)
|
||||
public (PhysicalMemory, ulong) GetComputeUniformBufferAddress(int index)
|
||||
{
|
||||
return _cpUniformBuffers.Buffers[index].Range.GetSubRange(0).Address;
|
||||
ref BufferBounds buffer = ref _cpUniformBuffers.Buffers[index];
|
||||
return (buffer.Physical, buffer.Range.GetSubRange(0).Address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -437,9 +450,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="stage">Index of the shader stage</param>
|
||||
/// <param name="index">Index of the uniform buffer binding</param>
|
||||
/// <returns>The uniform buffer address, or an undefined value if the buffer is not currently bound</returns>
|
||||
public ulong GetGraphicsUniformBufferAddress(int stage, int index)
|
||||
public (PhysicalMemory, ulong) GetGraphicsUniformBufferAddress(int stage, int index)
|
||||
{
|
||||
return _gpUniformBuffers[stage].Buffers[index].Range.GetSubRange(0).Address;
|
||||
ref BufferBounds buffer = ref _gpUniformBuffers[stage].Buffers[index];
|
||||
return (buffer.Physical, buffer.Range.GetSubRange(0).Address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -478,12 +492,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// </summary>
|
||||
public void CommitComputeBindings()
|
||||
{
|
||||
BufferCache bufferCache = _channel.MemoryManager.Physical.BufferCache;
|
||||
BindBuffers(_cpStorageBuffers, isStorage: true);
|
||||
BindBuffers(_cpUniformBuffers, isStorage: false);
|
||||
|
||||
BindBuffers(bufferCache, _cpStorageBuffers, isStorage: true);
|
||||
BindBuffers(bufferCache, _cpUniformBuffers, isStorage: false);
|
||||
|
||||
CommitBufferTextureBindings(bufferCache);
|
||||
CommitBufferTextureBindings();
|
||||
|
||||
// Force rebind after doing compute work.
|
||||
Rebind();
|
||||
@@ -495,14 +507,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// Commit any queued buffer texture bindings.
|
||||
/// </summary>
|
||||
/// <param name="bufferCache">Buffer cache</param>
|
||||
private void CommitBufferTextureBindings(BufferCache bufferCache)
|
||||
private void CommitBufferTextureBindings()
|
||||
{
|
||||
if (_bufferTextures.Count > 0)
|
||||
{
|
||||
foreach (BufferTextureBinding binding in _bufferTextures)
|
||||
{
|
||||
bool isStore = binding.BindingInfo.Flags.HasFlag(TextureUsageFlags.ImageStore);
|
||||
BufferRange range = bufferCache.GetBufferRange(binding.Range, BufferStageUtils.TextureBuffer(binding.Stage, binding.BindingInfo.Flags), isStore);
|
||||
BufferRange range = binding.BufferCache.GetBufferRange(binding.Range, BufferStageUtils.TextureBuffer(binding.Stage, binding.BindingInfo.Flags), isStore);
|
||||
binding.Texture.SetStorage(range);
|
||||
|
||||
// The texture must be rebound to use the new storage if it was updated.
|
||||
@@ -526,7 +538,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
foreach (BufferTextureArrayBinding<ITextureArray> binding in _bufferTextureArrays)
|
||||
{
|
||||
BufferRange range = bufferCache.GetBufferRange(binding.Range, BufferStage.None);
|
||||
BufferRange range = binding.BufferCache.GetBufferRange(binding.Range, BufferStage.None);
|
||||
binding.Texture.SetStorage(range);
|
||||
|
||||
textureArray[0] = binding.Texture;
|
||||
@@ -536,7 +548,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
foreach (BufferTextureArrayBinding<IImageArray> binding in _bufferImageArrays)
|
||||
{
|
||||
bool isStore = binding.BindingInfo.Flags.HasFlag(TextureUsageFlags.ImageStore);
|
||||
BufferRange range = bufferCache.GetBufferRange(binding.Range, BufferStage.None, isStore);
|
||||
BufferRange range = binding.BufferCache.GetBufferRange(binding.Range, BufferStage.None, isStore);
|
||||
binding.Texture.SetStorage(range);
|
||||
|
||||
textureArray[0] = binding.Texture;
|
||||
@@ -555,8 +567,6 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="indexed">True if the index buffer is in use</param>
|
||||
public void CommitGraphicsBindings(bool indexed)
|
||||
{
|
||||
BufferCache bufferCache = _channel.MemoryManager.Physical.BufferCache;
|
||||
|
||||
if (indexed)
|
||||
{
|
||||
if (_indexBufferDirty || _rebind)
|
||||
@@ -565,14 +575,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
if (!_indexBuffer.Range.IsUnmapped)
|
||||
{
|
||||
BufferRange buffer = bufferCache.GetBufferRange(_indexBuffer.Range, BufferStage.IndexBuffer);
|
||||
BufferRange buffer = _indexBuffer.BufferCache.GetBufferRange(_indexBuffer.Range, BufferStage.IndexBuffer);
|
||||
|
||||
_context.Renderer.Pipeline.SetIndexBuffer(buffer, _indexBuffer.Type);
|
||||
}
|
||||
}
|
||||
else if (!_indexBuffer.Range.IsUnmapped)
|
||||
{
|
||||
bufferCache.SynchronizeBufferRange(_indexBuffer.Range);
|
||||
_indexBuffer.BufferCache.SynchronizeBufferRange(_indexBuffer.Range);
|
||||
}
|
||||
}
|
||||
else if (_rebind)
|
||||
@@ -597,7 +607,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
continue;
|
||||
}
|
||||
|
||||
BufferRange buffer = bufferCache.GetBufferRange(vb.Range, BufferStage.VertexBuffer);
|
||||
BufferRange buffer = vb.BufferCache.GetBufferRange(vb.Range, BufferStage.VertexBuffer);
|
||||
|
||||
vertexBuffers[index] = new VertexBufferDescriptor(buffer, vb.Stride, vb.Divisor);
|
||||
}
|
||||
@@ -615,7 +625,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
continue;
|
||||
}
|
||||
|
||||
bufferCache.SynchronizeBufferRange(vb.Range);
|
||||
vb.BufferCache.SynchronizeBufferRange(vb.Range);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,7 +647,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
continue;
|
||||
}
|
||||
|
||||
tfbs[index] = bufferCache.GetBufferRange(tfb.Range, BufferStage.TransformFeedback, write: true);
|
||||
tfbs[index] = tfb.BufferCache.GetBufferRange(tfb.Range, BufferStage.TransformFeedback, write: true);
|
||||
}
|
||||
|
||||
_context.Renderer.Pipeline.SetTransformFeedbackBuffers(tfbs);
|
||||
@@ -684,7 +694,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
_context.SupportBufferUpdater.SetTfeOffset(index, tfeOffset);
|
||||
|
||||
buffers[index] = new BufferAssignment(index, bufferCache.GetBufferRange(range, BufferStage.TransformFeedback, write: true));
|
||||
buffers[index] = new BufferAssignment(index, tfb.BufferCache.GetBufferRange(range, BufferStage.TransformFeedback, write: true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -702,7 +712,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
continue;
|
||||
}
|
||||
|
||||
bufferCache.SynchronizeBufferRange(tfb.Range);
|
||||
tfb.BufferCache.SynchronizeBufferRange(tfb.Range);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,7 +720,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
_gpStorageBuffersDirty = false;
|
||||
|
||||
BindBuffers(bufferCache, _gpStorageBuffers, isStorage: true);
|
||||
BindBuffers(_gpStorageBuffers, isStorage: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -721,14 +731,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
_gpUniformBuffersDirty = false;
|
||||
|
||||
BindBuffers(bufferCache, _gpUniformBuffers, isStorage: false);
|
||||
BindBuffers(_gpUniformBuffers, isStorage: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateBuffers(_gpUniformBuffers);
|
||||
}
|
||||
|
||||
CommitBufferTextureBindings(bufferCache);
|
||||
CommitBufferTextureBindings();
|
||||
|
||||
_rebind = false;
|
||||
|
||||
@@ -742,7 +752,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="bindings">Buffer memory ranges to bind</param>
|
||||
/// <param name="isStorage">True to bind as storage buffer, false to bind as uniform buffer</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void BindBuffers(BufferCache bufferCache, BuffersPerStage[] bindings, bool isStorage)
|
||||
private void BindBuffers(BuffersPerStage[] bindings, bool isStorage)
|
||||
{
|
||||
int rangesCount = 0;
|
||||
|
||||
@@ -763,8 +773,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
bool isWrite = bounds.Flags.HasFlag(BufferUsageFlags.Write);
|
||||
BufferRange range = isStorage
|
||||
? bufferCache.GetBufferRangeAligned(bounds.Range, bufferStage | BufferStageUtils.FromUsage(bounds.Flags), isWrite)
|
||||
: bufferCache.GetBufferRange(bounds.Range, bufferStage);
|
||||
? bounds.BufferCache.GetBufferRangeAligned(bounds.Range, bufferStage | BufferStageUtils.FromUsage(bounds.Flags), isWrite)
|
||||
: bounds.BufferCache.GetBufferRange(bounds.Range, bufferStage);
|
||||
|
||||
ranges[rangesCount++] = new BufferAssignment(bindingInfo.Binding, range);
|
||||
}
|
||||
@@ -780,11 +790,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <summary>
|
||||
/// Bind respective buffer bindings on the host API.
|
||||
/// </summary>
|
||||
/// <param name="bufferCache">Buffer cache holding the buffers for the specified ranges</param>
|
||||
/// <param name="buffers">Buffer memory ranges to bind</param>
|
||||
/// <param name="isStorage">True to bind as storage buffer, false to bind as uniform buffer</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void BindBuffers(BufferCache bufferCache, BuffersPerStage buffers, bool isStorage)
|
||||
private void BindBuffers(BuffersPerStage buffers, bool isStorage)
|
||||
{
|
||||
int rangesCount = 0;
|
||||
|
||||
@@ -800,8 +809,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
bool isWrite = bounds.Flags.HasFlag(BufferUsageFlags.Write);
|
||||
BufferRange range = isStorage
|
||||
? bufferCache.GetBufferRangeAligned(bounds.Range, BufferStageUtils.ComputeStorage(bounds.Flags), isWrite)
|
||||
: bufferCache.GetBufferRange(bounds.Range, BufferStage.Compute);
|
||||
? bounds.BufferCache.GetBufferRangeAligned(bounds.Range, BufferStageUtils.ComputeStorage(bounds.Flags), isWrite)
|
||||
: bounds.BufferCache.GetBufferRange(bounds.Range, BufferStage.Compute);
|
||||
|
||||
ranges[rangesCount++] = new BufferAssignment(bindingInfo.Binding, range);
|
||||
}
|
||||
@@ -854,7 +863,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
continue;
|
||||
}
|
||||
|
||||
_channel.MemoryManager.Physical.BufferCache.SynchronizeBufferRange(bounds.Range);
|
||||
bounds.BufferCache.SynchronizeBufferRange(bounds.Range);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -871,13 +880,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
public void SetBufferTextureStorage(
|
||||
ShaderStage stage,
|
||||
ITexture texture,
|
||||
BufferCache bufferCache,
|
||||
MultiRange range,
|
||||
TextureBindingInfo bindingInfo,
|
||||
bool isImage)
|
||||
{
|
||||
_channel.MemoryManager.Physical.BufferCache.CreateBuffer(range, BufferStageUtils.TextureBuffer(stage, bindingInfo.Flags));
|
||||
bufferCache.CreateBuffer(range, BufferStageUtils.TextureBuffer(stage, bindingInfo.Flags));
|
||||
|
||||
_bufferTextures.Add(new BufferTextureBinding(stage, texture, range, bindingInfo, isImage));
|
||||
_bufferTextures.Add(new BufferTextureBinding(stage, texture, bufferCache, range, bindingInfo, isImage));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -894,13 +904,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
ShaderStage stage,
|
||||
ITextureArray array,
|
||||
ITexture texture,
|
||||
BufferCache bufferCache,
|
||||
MultiRange range,
|
||||
TextureBindingInfo bindingInfo,
|
||||
int index)
|
||||
{
|
||||
_channel.MemoryManager.Physical.BufferCache.CreateBuffer(range, BufferStageUtils.TextureBuffer(stage, bindingInfo.Flags));
|
||||
bufferCache.CreateBuffer(range, BufferStageUtils.TextureBuffer(stage, bindingInfo.Flags));
|
||||
|
||||
_bufferTextureArrays.Add(new BufferTextureArrayBinding<ITextureArray>(array, texture, range, bindingInfo, index));
|
||||
_bufferTextureArrays.Add(new BufferTextureArrayBinding<ITextureArray>(array, texture, bufferCache, range, bindingInfo, index));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -917,13 +928,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
ShaderStage stage,
|
||||
IImageArray array,
|
||||
ITexture texture,
|
||||
BufferCache bufferCache,
|
||||
MultiRange range,
|
||||
TextureBindingInfo bindingInfo,
|
||||
int index)
|
||||
{
|
||||
_channel.MemoryManager.Physical.BufferCache.CreateBuffer(range, BufferStageUtils.TextureBuffer(stage, bindingInfo.Flags));
|
||||
bufferCache.CreateBuffer(range, BufferStageUtils.TextureBuffer(stage, bindingInfo.Flags));
|
||||
|
||||
_bufferImageArrays.Add(new BufferTextureArrayBinding<IImageArray>(array, texture, range, bindingInfo, index));
|
||||
_bufferImageArrays.Add(new BufferTextureArrayBinding<IImageArray>(array, texture, bufferCache, range, bindingInfo, index));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -19,6 +19,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// </summary>
|
||||
public ITexture Texture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Buffer cache that owns the buffer.
|
||||
/// </summary>
|
||||
public BufferCache BufferCache { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Physical ranges of memory where the buffer texture data is located.
|
||||
/// </summary>
|
||||
@@ -39,18 +44,21 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// </summary>
|
||||
/// <param name="array">Array</param>
|
||||
/// <param name="texture">Buffer texture</param>
|
||||
/// <param name="bufferCache">Buffer cache that owns the buffer</param>
|
||||
/// <param name="range">Physical ranges of memory where the buffer texture data is located</param>
|
||||
/// <param name="bindingInfo">Binding info</param>
|
||||
/// <param name="index">Index of the binding on the array</param>
|
||||
public BufferTextureArrayBinding(
|
||||
T array,
|
||||
ITexture texture,
|
||||
BufferCache bufferCache,
|
||||
MultiRange range,
|
||||
TextureBindingInfo bindingInfo,
|
||||
int index)
|
||||
{
|
||||
Array = array;
|
||||
Texture = texture;
|
||||
BufferCache = bufferCache;
|
||||
Range = range;
|
||||
BindingInfo = bindingInfo;
|
||||
Index = index;
|
||||
|
||||
@@ -20,6 +20,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// </summary>
|
||||
public ITexture Texture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Buffer cache that owns the buffer.
|
||||
/// </summary>
|
||||
public BufferCache BufferCache { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Physical ranges of memory where the buffer texture data is located.
|
||||
/// </summary>
|
||||
@@ -40,18 +45,21 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// </summary>
|
||||
/// <param name="stage">Shader stage accessing the texture</param>
|
||||
/// <param name="texture">Buffer texture</param>
|
||||
/// <param name="bufferCache">Buffer cache that owns the buffer</param>
|
||||
/// <param name="range">Physical ranges of memory where the buffer texture data is located</param>
|
||||
/// <param name="bindingInfo">Binding info</param>
|
||||
/// <param name="isImage">Whether the binding is for an image or a sampler</param>
|
||||
public BufferTextureBinding(
|
||||
ShaderStage stage,
|
||||
ITexture texture,
|
||||
BufferCache bufferCache,
|
||||
MultiRange range,
|
||||
TextureBindingInfo bindingInfo,
|
||||
bool isImage)
|
||||
{
|
||||
Stage = stage;
|
||||
Texture = texture;
|
||||
BufferCache = bufferCache;
|
||||
Range = range;
|
||||
BindingInfo = bindingInfo;
|
||||
IsImage = isImage;
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// </summary>
|
||||
struct IndexBuffer
|
||||
{
|
||||
public BufferCache BufferCache;
|
||||
public MultiRange Range;
|
||||
public IndexType Type;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using Ryujinx.Memory;
|
||||
using Ryujinx.Memory.Range;
|
||||
using System;
|
||||
@@ -35,10 +36,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
public event EventHandler<UnmapEventArgs> MemoryUnmapped;
|
||||
|
||||
/// <summary>
|
||||
/// Physical memory where the virtual memory is mapped into.
|
||||
/// </summary>
|
||||
internal PhysicalMemory Physical { get; }
|
||||
private readonly GpuContext _context;
|
||||
private readonly List<PhysicalMemory> _physicalMemoryList;
|
||||
private readonly Dictionary<PhysicalMemory, byte> _physicalMemoryMap;
|
||||
|
||||
/// <summary>
|
||||
/// Virtual range cache.
|
||||
@@ -53,19 +53,65 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <summary>
|
||||
/// Creates a new instance of the GPU memory manager.
|
||||
/// </summary>
|
||||
/// <param name="context">GPU context</param>
|
||||
/// <param name="physicalMemory">Physical memory that this memory manager will map into</param>
|
||||
/// <param name="cpuMemorySize">The amount of physical CPU Memory Avaiable on the device.</param>
|
||||
internal MemoryManager(PhysicalMemory physicalMemory, ulong cpuMemorySize)
|
||||
|
||||
internal MemoryManager(GpuContext context, PhysicalMemory physicalMemory, ulong cpuMemorySize)
|
||||
{
|
||||
Physical = physicalMemory;
|
||||
_context = context;
|
||||
|
||||
_physicalMemoryList = new List<PhysicalMemory>()
|
||||
{
|
||||
physicalMemory
|
||||
};
|
||||
|
||||
_physicalMemoryMap = new Dictionary<PhysicalMemory, byte>
|
||||
{
|
||||
{ physicalMemory, 0 }
|
||||
};
|
||||
|
||||
VirtualRangeCache = new VirtualRangeCache(this);
|
||||
CounterCache = new CounterCache();
|
||||
_pageTable = new ulong[PtLvl0Size][];
|
||||
MemoryUnmapped += Physical.TextureCache.MemoryUnmappedHandler;
|
||||
MemoryUnmapped += Physical.BufferCache.MemoryUnmappedHandler;
|
||||
MemoryUnmapped += physicalMemory.TextureCache.MemoryUnmappedHandler;
|
||||
MemoryUnmapped += physicalMemory.BufferCache.MemoryUnmappedHandler;
|
||||
MemoryUnmapped += VirtualRangeCache.MemoryUnmappedHandler;
|
||||
MemoryUnmapped += CounterCache.MemoryUnmappedHandler;
|
||||
Physical.TextureCache.Initialize(cpuMemorySize);
|
||||
physicalMemory.TextureCache.Initialize(cpuMemorySize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the memory manager to a new GPU channel.
|
||||
/// </summary>
|
||||
/// <param name="rebind">Action to be performed when the buffer cache changes</param>
|
||||
internal void AttachToChannel(Action rebind)
|
||||
{
|
||||
PhysicalMemory physicalMemory = GetOwnPhysicalMemory();
|
||||
|
||||
physicalMemory.IncrementReferenceCount();
|
||||
physicalMemory.BufferCache.NotifyBuffersModified += rebind;
|
||||
physicalMemory.BufferCache.QueuePrune();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the memory manager to a new GPU channel.
|
||||
/// </summary>
|
||||
/// <param name="rebind">Action that was performed when the buffer cache changed</param>
|
||||
internal void DetachFromChannel(Action rebind)
|
||||
{
|
||||
PhysicalMemory physicalMemory = GetOwnPhysicalMemory();
|
||||
|
||||
physicalMemory.BufferCache.NotifyBuffersModified -= rebind;
|
||||
physicalMemory.DecrementReferenceCount();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues a prune of invalid entries on the buffer cache.
|
||||
/// </summary>
|
||||
internal void QueuePrune()
|
||||
{
|
||||
GetOwnPhysicalMemory().BufferCache.QueuePrune();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -81,15 +127,15 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
if (IsContiguous(va, size))
|
||||
{
|
||||
ulong address = Translate(va);
|
||||
(PhysicalMemory physicalMemory, ulong address) = TranslateWithPhysicalMemory(va);
|
||||
|
||||
if (tracked)
|
||||
{
|
||||
return Physical.ReadTracked<T>(address);
|
||||
return physicalMemory.ReadTracked<T>(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Physical.Read<T>(address);
|
||||
return physicalMemory.Read<T>(address);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -113,7 +159,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
if (IsContiguous(va, size))
|
||||
{
|
||||
return Physical.GetSpan(Translate(va), size, tracked);
|
||||
(PhysicalMemory physicalMemory, ulong address) = TranslateWithPhysicalMemory(va);
|
||||
|
||||
return physicalMemory.GetSpan(address, size, tracked);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -138,7 +186,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
bool isContiguous = true;
|
||||
int mappedSize;
|
||||
|
||||
if (ValidateAddress(va) && GetPte(va) != PteUnmapped && Physical.IsMapped(Translate(va)))
|
||||
if (ValidateAddress(va) && IsMappedOnGpuAndPhysical(va))
|
||||
{
|
||||
ulong endVa = va + (ulong)size;
|
||||
ulong endVaAligned = (endVa + PageMask) & ~PageMask;
|
||||
@@ -151,7 +199,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
ulong nextVa = currentVa + PageSize;
|
||||
ulong nextPa = Translate(nextVa);
|
||||
|
||||
if (!ValidateAddress(nextVa) || GetPte(nextVa) == PteUnmapped || !Physical.IsMapped(nextPa))
|
||||
if (!ValidateAddress(nextVa) || !IsMappedOnGpuAndPhysical(nextVa))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -180,7 +228,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
if (isContiguous)
|
||||
{
|
||||
return Physical.GetSpan(Translate(va), mappedSize, tracked);
|
||||
(PhysicalMemory physicalMemory, ulong address) = TranslateWithPhysicalMemory(va);
|
||||
|
||||
return physicalMemory.GetSpan(address, mappedSize, tracked);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -192,6 +242,23 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a page of memory is mapped on the GPU and its backing memory.
|
||||
/// </summary>
|
||||
/// <param name="va">GPU virtual address of the page</param>
|
||||
/// <returns>True if mapped, false otherwise</returns>
|
||||
private bool IsMappedOnGpuAndPhysical(ulong va)
|
||||
{
|
||||
(PhysicalMemory physicalMemory, ulong address) = TranslateWithPhysicalMemory(va);
|
||||
|
||||
if (address == PteUnmapped)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return physicalMemory.IsMapped(address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads data from a possibly non-contiguous region of GPU mapped memory.
|
||||
/// </summary>
|
||||
@@ -209,22 +276,22 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
if ((va & PageMask) != 0)
|
||||
{
|
||||
ulong pa = Translate(va);
|
||||
(PhysicalMemory physicalMemory, ulong pa) = TranslateWithPhysicalMemory(va);
|
||||
|
||||
size = Math.Min(data.Length, (int)PageSize - (int)(va & PageMask));
|
||||
|
||||
Physical.GetSpan(pa, size, tracked).CopyTo(data[..size]);
|
||||
physicalMemory.GetSpan(pa, size, tracked).CopyTo(data[..size]);
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
for (; offset < data.Length; offset += size)
|
||||
{
|
||||
ulong pa = Translate(va + (ulong)offset);
|
||||
(PhysicalMemory physicalMemory, ulong pa) = TranslateWithPhysicalMemory(va + (ulong)offset);
|
||||
|
||||
size = Math.Min(data.Length - offset, (int)PageSize);
|
||||
|
||||
Physical.GetSpan(pa, size, tracked).CopyTo(data.Slice(offset, size));
|
||||
physicalMemory.GetSpan(pa, size, tracked).CopyTo(data.Slice(offset, size));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,15 +306,17 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
if (IsContiguous(va, size))
|
||||
{
|
||||
return Physical.GetWritableRegion(Translate(va), size, tracked);
|
||||
(PhysicalMemory physicalMemory, ulong address) = TranslateWithPhysicalMemory(va);
|
||||
|
||||
return physicalMemory.GetWritableRegion(address, size, tracked);
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryOwner<byte> memoryOwner = MemoryOwner<byte>.Rent(size);
|
||||
Memory<byte> memory = new byte[size];
|
||||
|
||||
ReadImpl(va, memoryOwner.Span, tracked);
|
||||
GetSpan(va, size).CopyTo(memory.Span);
|
||||
|
||||
return new WritableRegion(this, va, memoryOwner, tracked);
|
||||
return new WritableRegion(this, va, memory, tracked);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +338,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="data">The data to be written</param>
|
||||
public void Write(ulong va, ReadOnlySpan<byte> data)
|
||||
{
|
||||
WriteImpl(va, data, Physical.Write);
|
||||
WriteImpl(va, data, (physical, va, data) => physical.Write(va, data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -279,7 +348,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="data">The data to be written</param>
|
||||
public void WriteTrackedResource(ulong va, ReadOnlySpan<byte> data)
|
||||
{
|
||||
WriteImpl(va, data, Physical.WriteTrackedResource);
|
||||
WriteImpl(va, data, (physical, va, data) => physical.WriteTrackedResource(va, data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -289,10 +358,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="data">The data to be written</param>
|
||||
public void WriteUntracked(ulong va, ReadOnlySpan<byte> data)
|
||||
{
|
||||
WriteImpl(va, data, Physical.WriteUntracked);
|
||||
WriteImpl(va, data, (physical, va, data) => physical.WriteUntracked(va, data));
|
||||
}
|
||||
|
||||
private delegate void WriteCallback(ulong address, ReadOnlySpan<byte> data);
|
||||
private delegate void WriteCallback(PhysicalMemory physicalMemory, ulong address, ReadOnlySpan<byte> data);
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to possibly non-contiguous GPU mapped memory.
|
||||
@@ -304,7 +373,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
if (IsContiguous(va, data.Length))
|
||||
{
|
||||
writeCallback(Translate(va), data);
|
||||
(PhysicalMemory physicalMemory, ulong address) = TranslateWithPhysicalMemory(va);
|
||||
|
||||
writeCallback(physicalMemory, address, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -312,22 +383,67 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
if ((va & PageMask) != 0)
|
||||
{
|
||||
ulong pa = Translate(va);
|
||||
(PhysicalMemory physicalMemory, ulong pa) = TranslateWithPhysicalMemory(va);
|
||||
|
||||
size = Math.Min(data.Length, (int)PageSize - (int)(va & PageMask));
|
||||
|
||||
writeCallback(pa, data[..size]);
|
||||
writeCallback(physicalMemory, pa, data[..size]);
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
for (; offset < data.Length; offset += size)
|
||||
{
|
||||
ulong pa = Translate(va + (ulong)offset);
|
||||
(PhysicalMemory physicalMemory, ulong pa) = TranslateWithPhysicalMemory(va + (ulong)offset);
|
||||
|
||||
size = Math.Min(data.Length - offset, (int)PageSize);
|
||||
|
||||
writeCallback(pa, data.Slice(offset, size));
|
||||
writeCallback(physicalMemory, pa, data.Slice(offset, size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to GPU mapped memory, stopping at the first unmapped page at the memory region, if any.
|
||||
/// </summary>
|
||||
/// <param name="va">GPU virtual address to write the data into</param>
|
||||
/// <param name="data">The data to be written</param>
|
||||
public void WriteMapped(ulong va, ReadOnlySpan<byte> data)
|
||||
{
|
||||
if (IsContiguous(va, data.Length))
|
||||
{
|
||||
(PhysicalMemory physicalMemory, ulong address) = TranslateWithPhysicalMemory(va);
|
||||
|
||||
physicalMemory.Write(address, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = 0, size;
|
||||
|
||||
if ((va & PageMask) != 0)
|
||||
{
|
||||
(PhysicalMemory physicalMemory, ulong pa) = TranslateWithPhysicalMemory(va);
|
||||
|
||||
size = Math.Min(data.Length, (int)PageSize - (int)(va & PageMask));
|
||||
|
||||
if (pa != PteUnmapped && physicalMemory.IsMapped(pa))
|
||||
{
|
||||
physicalMemory.Write(pa, data[..size]);
|
||||
}
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
for (; offset < data.Length; offset += size)
|
||||
{
|
||||
(PhysicalMemory physicalMemory, ulong pa) = TranslateWithPhysicalMemory(va + (ulong)offset);
|
||||
|
||||
size = Math.Min(data.Length - offset, (int)PageSize);
|
||||
|
||||
if (pa != PteUnmapped && physicalMemory.IsMapped(pa))
|
||||
{
|
||||
physicalMemory.Write(pa, data.Slice(offset, size));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -359,15 +475,51 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="size">Size in bytes of the mapping</param>
|
||||
/// <param name="kind">Kind of the resource located at the mapping</param>
|
||||
public void Map(ulong pa, ulong va, ulong size, PteKind kind)
|
||||
{
|
||||
MapImpl(pa, va, size, kind);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a given range of pages to the specified CPU virtual address from a different process.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// All addresses and sizes must be page aligned.
|
||||
/// </remarks>
|
||||
/// <param name="pa">CPU virtual address to map into</param>
|
||||
/// <param name="va">GPU virtual address to be mapped</param>
|
||||
/// <param name="size">Size in bytes of the mapping</param>
|
||||
/// <param name="kind">Kind of the resource located at the mapping</param>
|
||||
/// <param name="ownedPid">PID of the process that owns the mapping</param>
|
||||
public void MapForeign(ulong pa, ulong va, ulong size, PteKind kind, ulong ownedPid)
|
||||
{
|
||||
if (_context.PhysicalMemoryRegistry.TryGetValue(ownedPid, out PhysicalMemory physicalMemory))
|
||||
{
|
||||
MapImpl(pa, va, size, kind, physicalMemory);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a given range of pages to the specified CPU virtual address.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// All addresses and sizes must be page aligned.
|
||||
/// </remarks>
|
||||
/// <param name="pa">CPU virtual address to map into</param>
|
||||
/// <param name="va">GPU virtual address to be mapped</param>
|
||||
/// <param name="size">Size in bytes of the mapping</param>
|
||||
/// <param name="kind">Kind of the resource located at the mapping</param>
|
||||
/// <param name="physicalMemory">Optional physical memory to import for the mapping</param>
|
||||
private void MapImpl(ulong pa, ulong va, ulong size, PteKind kind, PhysicalMemory physicalMemory = null)
|
||||
{
|
||||
lock (_pageTable)
|
||||
{
|
||||
UnmapEventArgs e = new(va, size);
|
||||
MemoryUnmapped?.Invoke(this, e);
|
||||
byte pIndex = physicalMemory != null ? GetOrAddPhysicalMemory(physicalMemory) : (byte)0;
|
||||
|
||||
for (ulong offset = 0; offset < size; offset += PageSize)
|
||||
{
|
||||
SetPte(va + offset, PackPte(pa + offset, kind));
|
||||
SetPte(va + offset, PackPte(pa + offset, pIndex, kind));
|
||||
}
|
||||
|
||||
RunRemapActions(e);
|
||||
@@ -418,12 +570,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
for (int page = 0; page < pages - 1; page++)
|
||||
{
|
||||
if (!ValidateAddress(va + PageSize) || GetPte(va + PageSize) == PteUnmapped)
|
||||
ulong nextPte = GetPte(va + PageSize);
|
||||
|
||||
if (!ValidateAddress(va + PageSize) || nextPte == PteUnmapped)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Translate(va) + PageSize != Translate(va + PageSize))
|
||||
if (GetPte(va) + PageSize != nextPte)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -457,7 +611,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
int pages = (int)((endVaRounded - va) / PageSize);
|
||||
|
||||
List<MemoryRange> regions = [];
|
||||
List<MemoryRange> regions = new();
|
||||
|
||||
for (int page = 0; page < pages - 1; page++)
|
||||
{
|
||||
@@ -535,6 +689,49 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the backing memory for a given GPU virtual address.
|
||||
/// </summary>
|
||||
/// <param name="va">GPU virtual address to get the backing memory from</param>
|
||||
/// <returns>The backing memory for the specified GPU virtual address</returns>
|
||||
internal PhysicalMemory GetBackingMemory(ulong va)
|
||||
{
|
||||
ulong pte = GetPte(va);
|
||||
|
||||
if (pte == PteUnmapped)
|
||||
{
|
||||
return GetOwnPhysicalMemory();
|
||||
}
|
||||
|
||||
return _physicalMemoryList[UnpackPIndexFromPte(pte)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the backing memory that is owned by this GPU memory manager.
|
||||
/// </summary>
|
||||
/// <returns>The backing memory owned by this memory manager</returns>
|
||||
private PhysicalMemory GetOwnPhysicalMemory()
|
||||
{
|
||||
return _physicalMemoryList[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index for a given physical memory on the list, adding it to the list if needed.
|
||||
/// </summary>
|
||||
/// <param name="physicalMemory">Physical memory to get the index from</param>
|
||||
/// <returns>The index of the physical memory on the list</returns>
|
||||
private byte GetOrAddPhysicalMemory(PhysicalMemory physicalMemory)
|
||||
{
|
||||
if (!_physicalMemoryMap.TryGetValue(physicalMemory, out byte pIndex))
|
||||
{
|
||||
pIndex = checked((byte)_physicalMemoryList.Count);
|
||||
_physicalMemoryList.Add(physicalMemory);
|
||||
_physicalMemoryMap.Add(physicalMemory, pIndex);
|
||||
}
|
||||
|
||||
return pIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates a GPU virtual address.
|
||||
/// </summary>
|
||||
@@ -636,6 +833,28 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
return Math.Min(maxSize, va - startVa);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translates a GPU virtual address to a CPU virtual address and the associated physical memory.
|
||||
/// </summary>
|
||||
/// <param name="va">GPU virtual address to be translated</param>
|
||||
/// <returns>CPU virtual address with the physical memory, or <see cref="PteUnmapped"/> if unmapped</returns>
|
||||
private (PhysicalMemory, ulong) TranslateWithPhysicalMemory(ulong va)
|
||||
{
|
||||
if (!ValidateAddress(va))
|
||||
{
|
||||
return (GetOwnPhysicalMemory(), PteUnmapped);
|
||||
}
|
||||
|
||||
ulong pte = GetPte(va);
|
||||
|
||||
if (pte == PteUnmapped)
|
||||
{
|
||||
return (GetOwnPhysicalMemory(), PteUnmapped);
|
||||
}
|
||||
|
||||
return (_physicalMemoryList[UnpackPIndexFromPte(pte)], UnpackPaFromPte(pte) + (va & PageMask));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the kind of a given memory page.
|
||||
/// This might indicate the type of resource that can be allocated on the page, and also texture tiling.
|
||||
@@ -659,6 +878,18 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
return UnpackKindFromPte(pte);
|
||||
}
|
||||
|
||||
public bool IsForeignMapping(ulong va)
|
||||
{
|
||||
ulong pte = GetPte(va);
|
||||
|
||||
if (pte == PteUnmapped)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return UnpackPIndexFromPte(pte) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Page Table entry for a given GPU virtual address.
|
||||
/// </summary>
|
||||
@@ -704,11 +935,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// Creates a page table entry from a physical address and kind.
|
||||
/// </summary>
|
||||
/// <param name="pa">Physical address</param>
|
||||
/// <param name="pIndex">Index of the physical memory on the list</param>
|
||||
/// <param name="kind">Kind</param>
|
||||
/// <returns>Page table entry</returns>
|
||||
private static ulong PackPte(ulong pa, PteKind kind)
|
||||
private static ulong PackPte(ulong pa, byte pIndex, PteKind kind)
|
||||
{
|
||||
return pa | ((ulong)kind << 56);
|
||||
return pa | ((ulong)pIndex << 48) | ((ulong)kind << 56);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -721,6 +953,16 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
return (PteKind)(pte >> 56);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the physical memory index in the list from a page table entry.
|
||||
/// </summary>
|
||||
/// <param name="pte">Page table entry</param>
|
||||
/// <returns>Physical memory index</returns>
|
||||
private static byte UnpackPIndexFromPte(ulong pte)
|
||||
{
|
||||
return (byte)(pte >> 48);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks physical address from a page table entry.
|
||||
/// </summary>
|
||||
@@ -728,7 +970,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <returns>Physical address</returns>
|
||||
private static ulong UnpackPaFromPte(ulong pte)
|
||||
{
|
||||
return pte & 0xffffffffffffffUL;
|
||||
return pte & 0xffffffffffffUL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// </summary>
|
||||
struct VertexBuffer
|
||||
{
|
||||
public BufferCache BufferCache;
|
||||
public MultiRange Range;
|
||||
public int Stride;
|
||||
public int Divisor;
|
||||
|
||||
@@ -729,7 +729,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||
|
||||
ShaderProgram program = translatorContext.Translate();
|
||||
|
||||
CachedShaderStage[] shaders = [new CachedShaderStage(program.Info, shader.Code, shader.Cb1Data)];
|
||||
CachedShaderStage[] shaders = [new(program.Info, shader.Code, shader.Cb1Data)];
|
||||
|
||||
_compilationQueue.Enqueue(new ProgramCompilation([program], shaders, newSpecState, programIndex, isCompute: true));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
@@ -66,11 +67,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
/// <inheritdoc/>
|
||||
public uint ConstantBuffer1Read(int offset)
|
||||
{
|
||||
ulong baseAddress = _compute
|
||||
(PhysicalMemory physical, ulong baseAddress) = _compute
|
||||
? _channel.BufferManager.GetComputeUniformBufferAddress(1)
|
||||
: _channel.BufferManager.GetGraphicsUniformBufferAddress(_stageIndex, 1);
|
||||
|
||||
return _channel.MemoryManager.Physical.Read<uint>(baseAddress + (ulong)offset);
|
||||
return physical.Read<uint>(baseAddress + (ulong)offset);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -733,15 +733,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
byte[] codeB,
|
||||
bool asCompute)
|
||||
{
|
||||
ulong cb1DataAddress = channel.BufferManager.GetGraphicsUniformBufferAddress(0, 1);
|
||||
|
||||
(PhysicalMemory physical, ulong cb1DataAddress) = channel.BufferManager.GetGraphicsUniformBufferAddress(0, 1);
|
||||
|
||||
MemoryManager memoryManager = channel.MemoryManager;
|
||||
|
||||
codeA ??= memoryManager.GetSpan(vertexA.Address, vertexA.Size).ToArray();
|
||||
codeB ??= memoryManager.GetSpan(currentStage.Address, currentStage.Size).ToArray();
|
||||
byte[] cb1DataA = ReadArray(memoryManager, cb1DataAddress, vertexA.Cb1DataSize);
|
||||
byte[] cb1DataB = ReadArray(memoryManager, cb1DataAddress, currentStage.Cb1DataSize);
|
||||
|
||||
byte[] cb1DataA = ReadArray(physical, cb1DataAddress, vertexA.Cb1DataSize);
|
||||
byte[] cb1DataB = ReadArray(physical, cb1DataAddress, currentStage.Cb1DataSize);
|
||||
|
||||
ShaderDumpPaths pathsA = default;
|
||||
ShaderDumpPaths pathsB = default;
|
||||
|
||||
@@ -775,11 +775,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
{
|
||||
MemoryManager memoryManager = channel.MemoryManager;
|
||||
|
||||
ulong cb1DataAddress = context.Stage == ShaderStage.Compute
|
||||
(PhysicalMemory physical, ulong cb1DataAddress) = context.Stage == ShaderStage.Compute
|
||||
? channel.BufferManager.GetComputeUniformBufferAddress(1)
|
||||
: channel.BufferManager.GetGraphicsUniformBufferAddress(StageToStageIndex(context.Stage), 1);
|
||||
|
||||
byte[] cb1Data = ReadArray(memoryManager, cb1DataAddress, context.Cb1DataSize);
|
||||
byte[] cb1Data = ReadArray(physical, cb1DataAddress, context.Cb1DataSize);
|
||||
code ??= memoryManager.GetSpan(context.Address, context.Size).ToArray();
|
||||
|
||||
ShaderDumpPaths paths = dumper?.Dump(code, context.Stage == ShaderStage.Compute) ?? default;
|
||||
@@ -793,18 +793,18 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
/// <summary>
|
||||
/// Reads data from physical memory, returns an empty array if the memory is unmapped or size is 0.
|
||||
/// </summary>
|
||||
/// <param name="memoryManager">Memory manager with the physical memory to read from</param>
|
||||
/// <param name="physicalMemory">Physical memory to read the data from, might be null</param>
|
||||
/// <param name="address">Physical address of the region to read</param>
|
||||
/// <param name="size">Size in bytes of the data</param>
|
||||
/// <returns>An array with the data at the specified memory location</returns>
|
||||
private static byte[] ReadArray(MemoryManager memoryManager, ulong address, int size)
|
||||
private static byte[] ReadArray(PhysicalMemory physicalMemory, ulong address, int size)
|
||||
{
|
||||
if (address == MemoryManager.PteUnmapped || size == 0)
|
||||
if (address == MemoryManager.PteUnmapped || size == 0 || physicalMemory == null)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return memoryManager.Physical.GetSpan(address, size).ToArray();
|
||||
return physicalMemory.GetSpan(address, size).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -696,7 +696,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
{
|
||||
ref BufferBounds bounds = ref channel.BufferManager.GetUniformBufferBounds(isCompute, stageIndex, textureBufferIndex);
|
||||
|
||||
cachedTextureBuffer = MemoryMarshal.Cast<byte, int>(channel.MemoryManager.Physical.GetSpan(bounds.Range));
|
||||
cachedTextureBuffer = MemoryMarshal.Cast<byte, int>(bounds.Physical.GetSpan(bounds.Range));
|
||||
cachedTextureBufferIndex = textureBufferIndex;
|
||||
|
||||
if (samplerBufferIndex == textureBufferIndex)
|
||||
@@ -710,7 +710,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
{
|
||||
ref BufferBounds bounds = ref channel.BufferManager.GetUniformBufferBounds(isCompute, stageIndex, samplerBufferIndex);
|
||||
|
||||
cachedSamplerBuffer = MemoryMarshal.Cast<byte, int>(channel.MemoryManager.Physical.GetSpan(bounds.Range));
|
||||
cachedSamplerBuffer = MemoryMarshal.Cast<byte, int>(bounds.Physical.GetSpan(bounds.Range));
|
||||
cachedSamplerBufferIndex = samplerBufferIndex;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,18 @@ using System.Threading;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu
|
||||
{
|
||||
using Texture = Image.Texture;
|
||||
|
||||
public record TextureData(int Width, int Height, byte[] Data);
|
||||
|
||||
/// <summary>
|
||||
/// GPU image presentation window.
|
||||
/// </summary>
|
||||
public class Window
|
||||
{
|
||||
private const int CaptureTextureWidth = 1280;
|
||||
private const int CaptureTextureHeight = 720;
|
||||
|
||||
private readonly GpuContext _context;
|
||||
|
||||
/// <summary>
|
||||
@@ -85,7 +92,21 @@ namespace Ryujinx.Graphics.Gpu
|
||||
}
|
||||
}
|
||||
|
||||
private class PresentedTexture
|
||||
{
|
||||
public readonly Texture Texture;
|
||||
public readonly ImageCrop Crop;
|
||||
|
||||
public PresentedTexture(Texture texture, ImageCrop crop)
|
||||
{
|
||||
Texture = texture;
|
||||
Crop = crop;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly ConcurrentQueue<PresentationTexture> _frameQueue;
|
||||
private PresentedTexture _lastPresentedTexture;
|
||||
private ITexture _captureTexture;
|
||||
|
||||
private int _framesAvailable;
|
||||
|
||||
@@ -188,6 +209,51 @@ namespace Ryujinx.Graphics.Gpu
|
||||
return true;
|
||||
}
|
||||
|
||||
public TextureData GetLastPresentedData()
|
||||
{
|
||||
PresentedTexture pt = Volatile.Read(ref _lastPresentedTexture);
|
||||
|
||||
if (pt != null)
|
||||
{
|
||||
byte[] inputData = CaptureLastFrame(pt.Texture.HostTexture, pt.Crop);
|
||||
|
||||
int size = SizeCalculator.GetBlockLinearTextureSize(
|
||||
CaptureTextureWidth,
|
||||
CaptureTextureHeight,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
4,
|
||||
16,
|
||||
1,
|
||||
1).TotalSize;
|
||||
|
||||
byte[] data = new byte[size];
|
||||
|
||||
LayoutConverter.ConvertLinearToBlockLinear(data, CaptureTextureWidth, CaptureTextureHeight, CaptureTextureWidth * 4, 4, 16, inputData);
|
||||
|
||||
return new TextureData(CaptureTextureWidth, CaptureTextureHeight, data);
|
||||
}
|
||||
|
||||
return new TextureData(0, 0, Array.Empty<byte>());
|
||||
}
|
||||
|
||||
public TextureData GetLastPresentedDataLinear()
|
||||
{
|
||||
PresentedTexture pt = Volatile.Read(ref _lastPresentedTexture);
|
||||
|
||||
if (pt != null)
|
||||
{
|
||||
byte[] inputData = CaptureLastFrame(pt.Texture.HostTexture, new ImageCrop());
|
||||
|
||||
return new TextureData(pt.Texture.Info.Width, pt.Texture.Info.Height, inputData);
|
||||
}
|
||||
|
||||
return new TextureData(0, 0, Array.Empty<byte>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Presents a texture on the queue.
|
||||
/// If the queue is empty, then no texture is presented.
|
||||
@@ -205,6 +271,10 @@ namespace Ryujinx.Graphics.Gpu
|
||||
|
||||
pt.Cache.Tick();
|
||||
|
||||
EnsureCaptureTexture();
|
||||
|
||||
Volatile.Write(ref _lastPresentedTexture, new PresentedTexture(texture, pt.Crop));
|
||||
|
||||
texture.SynchronizeMemory();
|
||||
|
||||
ImageCrop crop = new(
|
||||
@@ -244,6 +314,96 @@ namespace Ryujinx.Graphics.Gpu
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureCaptureTexture()
|
||||
{
|
||||
if (_captureTexture == null)
|
||||
{
|
||||
_captureTexture = _context.Renderer.CreateTexture(new TextureCreateInfo(
|
||||
1280,
|
||||
720,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
4,
|
||||
Format.R8G8B8A8Unorm,
|
||||
DepthStencilMode.Depth,
|
||||
Target.Texture2D,
|
||||
SwizzleComponent.Red,
|
||||
SwizzleComponent.Green,
|
||||
SwizzleComponent.Blue,
|
||||
SwizzleComponent.Alpha));
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] CaptureLastFrame(ITexture lastFrame, ImageCrop crop)
|
||||
{
|
||||
int cropLeft, cropRight, cropTop, cropBottom;
|
||||
|
||||
if (crop.Left == 0 && crop.Right == 0)
|
||||
{
|
||||
cropLeft = 0;
|
||||
cropRight = lastFrame.Width;
|
||||
}
|
||||
else
|
||||
{
|
||||
cropLeft = crop.Left;
|
||||
cropRight = crop.Right;
|
||||
}
|
||||
|
||||
if (crop.Top == 0 && crop.Bottom == 0)
|
||||
{
|
||||
cropTop = 0;
|
||||
cropBottom = lastFrame.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
cropTop = crop.Top;
|
||||
cropBottom = crop.Bottom;
|
||||
}
|
||||
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
if (crop.FlipX)
|
||||
{
|
||||
x1 = cropRight;
|
||||
x2 = cropLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = cropLeft;
|
||||
x2 = cropRight;
|
||||
}
|
||||
|
||||
if (crop.FlipY)
|
||||
{
|
||||
y1 = cropBottom;
|
||||
y2 = cropTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
y1 = cropTop;
|
||||
y2 = cropBottom;
|
||||
}
|
||||
|
||||
Extents2D srcRegion = new(x1, y1, x2, y2);
|
||||
Extents2D dstRegion = new(0, 0, CaptureTextureWidth, CaptureTextureHeight);
|
||||
|
||||
byte[] outputData = null;
|
||||
|
||||
_context.Renderer.BackgroundContextAction(() =>
|
||||
{
|
||||
lastFrame.CopyTo(_captureTexture, srcRegion, dstRegion, true);
|
||||
|
||||
using var data = _captureTexture.GetData();
|
||||
|
||||
outputData = data.Get().ToArray();
|
||||
});
|
||||
|
||||
return outputData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicate that a frame on the queue is ready to be acquired.
|
||||
/// </summary>
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
||||
}
|
||||
}
|
||||
|
||||
ArrayPtr<T> allocation = new ArrayPtr<T>(ptr, length);
|
||||
ArrayPtr<T> allocation = new(ptr, length);
|
||||
|
||||
allocation.AsSpan().Fill(default);
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return (v & 1) != 0 ? m - ((v + 1) >> 1) : m + (v >> 1);
|
||||
}
|
||||
|
||||
private static readonly byte[] InvMapTable =
|
||||
{
|
||||
private static readonly byte[] _invMapTable =
|
||||
[
|
||||
7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176, 189, 202, 215, 228, 241, 254, 1, 2, 3, 4,
|
||||
5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34,
|
||||
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62,
|
||||
@@ -28,13 +28,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
206, 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
|
||||
229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250,
|
||||
251, 252, 253, 253
|
||||
};
|
||||
];
|
||||
|
||||
public static int InvRemapProb(int v, int m)
|
||||
{
|
||||
Debug.Assert(v < InvMapTable.Length / sizeof(byte));
|
||||
Debug.Assert(v < _invMapTable.Length / sizeof(byte));
|
||||
|
||||
v = InvMapTable[v];
|
||||
v = _invMapTable[v];
|
||||
m--;
|
||||
if (m << 1 <= Prob.MaxProb)
|
||||
{
|
||||
|
||||
@@ -111,23 +111,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
Span<ushort> dst16 = MemoryMarshal.Cast<byte, ushort>(dst);
|
||||
if (xd.Lossless)
|
||||
{
|
||||
Idct.HighbdIwht4x4Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
Idct.HighbdIwht4X4Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (txSize)
|
||||
{
|
||||
case TxSize.Tx4x4:
|
||||
Idct.HighbdIdct4x4Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
case TxSize.Tx4X4:
|
||||
Idct.HighbdIdct4X4Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
break;
|
||||
case TxSize.Tx8x8:
|
||||
Idct.HighbdIdct8x8Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
case TxSize.Tx8X8:
|
||||
Idct.HighbdIdct8X8Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
break;
|
||||
case TxSize.Tx16x16:
|
||||
Idct.HighbdIdct16x16Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
case TxSize.Tx16X16:
|
||||
Idct.HighbdIdct16X16Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
break;
|
||||
case TxSize.Tx32x32:
|
||||
Idct.HighbdIdct32x32Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
case TxSize.Tx32X32:
|
||||
Idct.HighbdIdct32X32Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid transform size");
|
||||
@@ -139,23 +139,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
if (xd.Lossless)
|
||||
{
|
||||
Idct.Iwht4x4Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
Idct.Iwht4X4Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (txSize)
|
||||
{
|
||||
case TxSize.Tx4x4:
|
||||
Idct.Idct4x4Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
case TxSize.Tx4X4:
|
||||
Idct.Idct4X4Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx8x8:
|
||||
Idct.Idct8x8Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
case TxSize.Tx8X8:
|
||||
Idct.Idct8X8Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx16x16:
|
||||
Idct.Idct16x16Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
case TxSize.Tx16X16:
|
||||
Idct.Idct16X16Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx32x32:
|
||||
Idct.Idct32x32Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
case TxSize.Tx32X32:
|
||||
Idct.Idct32X32Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid transform size");
|
||||
@@ -170,11 +170,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
else
|
||||
{
|
||||
if (txSize <= TxSize.Tx16x16 && eob <= 10)
|
||||
if (txSize <= TxSize.Tx16X16 && eob <= 10)
|
||||
{
|
||||
dqcoeff.AsSpan().Slice(0, 4 * (4 << (int)txSize)).Clear();
|
||||
}
|
||||
else if (txSize == TxSize.Tx32x32 && eob <= 34)
|
||||
else if (txSize == TxSize.Tx32X32 && eob <= 34)
|
||||
{
|
||||
dqcoeff.AsSpan().Slice(0, 256).Clear();
|
||||
}
|
||||
@@ -202,23 +202,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
Span<ushort> dst16 = MemoryMarshal.Cast<byte, ushort>(dst);
|
||||
if (xd.Lossless)
|
||||
{
|
||||
Idct.HighbdIwht4x4Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
Idct.HighbdIwht4X4Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (txSize)
|
||||
{
|
||||
case TxSize.Tx4x4:
|
||||
Idct.HighbdIht4x4Add(txType, dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
case TxSize.Tx4X4:
|
||||
Idct.HighbdIht4X4Add(txType, dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
break;
|
||||
case TxSize.Tx8x8:
|
||||
Idct.HighbdIht8x8Add(txType, dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
case TxSize.Tx8X8:
|
||||
Idct.HighbdIht8X8Add(txType, dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
break;
|
||||
case TxSize.Tx16x16:
|
||||
Idct.HighbdIht16x16Add(txType, dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
case TxSize.Tx16X16:
|
||||
Idct.HighbdIht16X16Add(txType, dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
break;
|
||||
case TxSize.Tx32x32:
|
||||
Idct.HighbdIdct32x32Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
case TxSize.Tx32X32:
|
||||
Idct.HighbdIdct32X32Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid transform size");
|
||||
@@ -230,23 +230,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
if (xd.Lossless)
|
||||
{
|
||||
Idct.Iwht4x4Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
Idct.Iwht4X4Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (txSize)
|
||||
{
|
||||
case TxSize.Tx4x4:
|
||||
Idct.Iht4x4Add(txType, dqcoeff.AsSpan(), dst, stride, eob);
|
||||
case TxSize.Tx4X4:
|
||||
Idct.Iht4X4Add(txType, dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx8x8:
|
||||
Idct.Iht8x8Add(txType, dqcoeff.AsSpan(), dst, stride, eob);
|
||||
case TxSize.Tx8X8:
|
||||
Idct.Iht8X8Add(txType, dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx16x16:
|
||||
Idct.Iht16x16Add(txType, dqcoeff.AsSpan(), dst, stride, eob);
|
||||
case TxSize.Tx16X16:
|
||||
Idct.Iht16X16Add(txType, dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
case TxSize.Tx32x32:
|
||||
Idct.Idct32x32Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
case TxSize.Tx32X32:
|
||||
Idct.Idct32X32Add(dqcoeff.AsSpan(), dst, stride, eob);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid transform size");
|
||||
@@ -261,11 +261,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
else
|
||||
{
|
||||
if (txType == TxType.DctDct && txSize <= TxSize.Tx16x16 && eob <= 10)
|
||||
if (txType == TxType.DctDct && txSize <= TxSize.Tx16X16 && eob <= 10)
|
||||
{
|
||||
dqcoeff.AsSpan().Slice(0, 4 * (4 << (int)txSize)).Clear();
|
||||
}
|
||||
else if (txSize == TxSize.Tx32x32 && eob <= 34)
|
||||
else if (txSize == TxSize.Tx32X32 && eob <= 34)
|
||||
{
|
||||
dqcoeff.AsSpan().Slice(0, 256).Clear();
|
||||
}
|
||||
@@ -291,7 +291,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
byte* dst = &pd.Dst.Buf.ToPointer()[dstOffset];
|
||||
Span<byte> dstSpan = pd.Dst.Buf.AsSpan().Slice(dstOffset);
|
||||
|
||||
if (mi.SbType < BlockSize.Block8x8)
|
||||
if (mi.SbType < BlockSize.Block8X8)
|
||||
{
|
||||
if (plane == 0)
|
||||
{
|
||||
@@ -769,21 +769,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
isScaled ? new Ptr<ScaleFactors>(ref sf) : Ptr<ScaleFactors>.Null);
|
||||
xd.BlockRefs[refr] = new Ptr<RefBuffer>(ref refBuf);
|
||||
|
||||
if (sbType < BlockSize.Block8x8)
|
||||
if (sbType < BlockSize.Block8X8)
|
||||
{
|
||||
for (plane = 0; plane < Constants.MaxMbPlane; ++plane)
|
||||
{
|
||||
ref MacroBlockDPlane pd = ref xd.Plane[plane];
|
||||
ref Buf2D dstBuf = ref pd.Dst;
|
||||
int num4x4W = pd.N4W;
|
||||
int num4x4H = pd.N4H;
|
||||
int n4Wx4 = 4 * num4x4W;
|
||||
int n4Hx4 = 4 * num4x4H;
|
||||
int num4X4W = pd.N4W;
|
||||
int num4X4H = pd.N4H;
|
||||
int n4Wx4 = 4 * num4X4W;
|
||||
int n4Hx4 = 4 * num4X4H;
|
||||
ref Buf2D preBuf = ref pd.Pre[refr];
|
||||
int i = 0;
|
||||
for (int y = 0; y < num4x4H; ++y)
|
||||
for (int y = 0; y < num4X4H; ++y)
|
||||
{
|
||||
for (int x = 0; x < num4x4W; ++x)
|
||||
for (int x = 0; x < num4X4W; ++x)
|
||||
{
|
||||
Mv mv = ReconInter.AverageSplitMvs(ref pd, ref mi, refr, i++);
|
||||
DecBuildInterPredictors(
|
||||
@@ -816,10 +816,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
ref MacroBlockDPlane pd = ref xd.Plane[plane];
|
||||
ref Buf2D dstBuf = ref pd.Dst;
|
||||
int num4x4W = pd.N4W;
|
||||
int num4x4H = pd.N4H;
|
||||
int n4Wx4 = 4 * num4x4W;
|
||||
int n4Hx4 = 4 * num4x4H;
|
||||
int num4X4W = pd.N4W;
|
||||
int num4X4H = pd.N4H;
|
||||
int n4Wx4 = 4 * num4X4W;
|
||||
int n4Hx4 = 4 * num4X4H;
|
||||
ref Buf2D preBuf = ref pd.Pre[refr];
|
||||
DecBuildInterPredictors(
|
||||
ref xd,
|
||||
@@ -905,7 +905,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int bwl,
|
||||
int bhl)
|
||||
{
|
||||
bool less8x8 = bsize < BlockSize.Block8x8;
|
||||
bool less8X8 = bsize < BlockSize.Block8X8;
|
||||
int bw = 1 << (bwl - 1);
|
||||
int bh = 1 << (bhl - 1);
|
||||
int xMis = Math.Min(bw, cm.MiCols - miCol);
|
||||
@@ -915,7 +915,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
ref ModeInfo mi = ref SetOffsets(ref cm, ref xd, bsize, miRow, miCol, bw, bh, xMis, yMis, bwl, bhl);
|
||||
|
||||
if (bsize >= BlockSize.Block8x8 && (cm.SubsamplingX != 0 || cm.SubsamplingY != 0))
|
||||
if (bsize >= BlockSize.Block8X8 && (cm.SubsamplingX != 0 || cm.SubsamplingY != 0))
|
||||
{
|
||||
BlockSize uvSubsize = Luts.SsSizeLookup[(int)bsize][cm.SubsamplingX][cm.SubsamplingY];
|
||||
if (uvSubsize == BlockSize.BlockInvalid)
|
||||
@@ -938,14 +938,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
ref MacroBlockDPlane pd = ref xd.Plane[plane];
|
||||
TxSize txSize = plane != 0 ? mi.GetUvTxSize(ref pd) : mi.TxSize;
|
||||
int num4x4W = pd.N4W;
|
||||
int num4x4H = pd.N4H;
|
||||
int num4X4W = pd.N4W;
|
||||
int num4X4H = pd.N4H;
|
||||
int step = 1 << (int)txSize;
|
||||
int row, col;
|
||||
int maxBlocksWide =
|
||||
num4x4W + (xd.MbToRightEdge >= 0 ? 0 : xd.MbToRightEdge >> (5 + pd.SubsamplingX));
|
||||
num4X4W + (xd.MbToRightEdge >= 0 ? 0 : xd.MbToRightEdge >> (5 + pd.SubsamplingX));
|
||||
int maxBlocksHigh =
|
||||
num4x4H + (xd.MbToBottomEdge >= 0 ? 0 : xd.MbToBottomEdge >> (5 + pd.SubsamplingY));
|
||||
num4X4H + (xd.MbToBottomEdge >= 0 ? 0 : xd.MbToBottomEdge >> (5 + pd.SubsamplingY));
|
||||
|
||||
xd.MaxBlocksWide = (uint)(xd.MbToRightEdge >= 0 ? 0 : maxBlocksWide);
|
||||
xd.MaxBlocksHigh = (uint)(xd.MbToBottomEdge >= 0 ? 0 : maxBlocksHigh);
|
||||
@@ -974,13 +974,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
ref MacroBlockDPlane pd = ref xd.Plane[plane];
|
||||
TxSize txSize = plane != 0 ? mi.GetUvTxSize(ref pd) : mi.TxSize;
|
||||
int num4x4W = pd.N4W;
|
||||
int num4x4H = pd.N4H;
|
||||
int num4X4W = pd.N4W;
|
||||
int num4X4H = pd.N4H;
|
||||
int step = 1 << (int)txSize;
|
||||
int row, col;
|
||||
int maxBlocksWide =
|
||||
num4x4W + (xd.MbToRightEdge >= 0 ? 0 : xd.MbToRightEdge >> (5 + pd.SubsamplingX));
|
||||
int maxBlocksHigh = num4x4H +
|
||||
num4X4W + (xd.MbToRightEdge >= 0 ? 0 : xd.MbToRightEdge >> (5 + pd.SubsamplingX));
|
||||
int maxBlocksHigh = num4X4H +
|
||||
(xd.MbToBottomEdge >= 0 ? 0 : xd.MbToBottomEdge >> (5 + pd.SubsamplingY));
|
||||
|
||||
xd.MaxBlocksWide = (uint)(xd.MbToRightEdge >= 0 ? 0 : maxBlocksWide);
|
||||
@@ -995,7 +995,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
if (!less8x8 && eobtotal == 0)
|
||||
if (!less8X8 && eobtotal == 0)
|
||||
{
|
||||
mi.Skip = 1; // Skip loopfilter
|
||||
}
|
||||
@@ -1072,11 +1072,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int miRow,
|
||||
int miCol,
|
||||
BlockSize bsize,
|
||||
int n4x4L2)
|
||||
int n4X4L2)
|
||||
{
|
||||
int n8x8L2 = n4x4L2 - 1;
|
||||
int num8x8Wh = 1 << n8x8L2;
|
||||
int hbs = num8x8Wh >> 1;
|
||||
int n8X8L2 = n4X4L2 - 1;
|
||||
int num8X8Wh = 1 << n8X8L2;
|
||||
int hbs = num8X8Wh >> 1;
|
||||
PartitionType partition;
|
||||
BlockSize subsize;
|
||||
bool hasRows = miRow + hbs < cm.MiRows;
|
||||
@@ -1088,7 +1088,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return;
|
||||
}
|
||||
|
||||
partition = ReadPartition(ref twd, miRow, miCol, hasRows ? 1 : 0, hasCols ? 1 : 0, n8x8L2);
|
||||
partition = ReadPartition(ref twd, miRow, miCol, hasRows ? 1 : 0, hasCols ? 1 : 0, n8X8L2);
|
||||
subsize = Luts.SubsizeLookup[(int)partition][(int)bsize];
|
||||
if (hbs == 0)
|
||||
{
|
||||
@@ -1102,29 +1102,29 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
switch (partition)
|
||||
{
|
||||
case PartitionType.PartitionNone:
|
||||
DecodeBlock(ref twd, ref cm, miRow, miCol, subsize, n4x4L2, n4x4L2);
|
||||
DecodeBlock(ref twd, ref cm, miRow, miCol, subsize, n4X4L2, n4X4L2);
|
||||
break;
|
||||
case PartitionType.PartitionHorz:
|
||||
DecodeBlock(ref twd, ref cm, miRow, miCol, subsize, n4x4L2, n8x8L2);
|
||||
DecodeBlock(ref twd, ref cm, miRow, miCol, subsize, n4X4L2, n8X8L2);
|
||||
if (hasRows)
|
||||
{
|
||||
DecodeBlock(ref twd, ref cm, miRow + hbs, miCol, subsize, n4x4L2, n8x8L2);
|
||||
DecodeBlock(ref twd, ref cm, miRow + hbs, miCol, subsize, n4X4L2, n8X8L2);
|
||||
}
|
||||
|
||||
break;
|
||||
case PartitionType.PartitionVert:
|
||||
DecodeBlock(ref twd, ref cm, miRow, miCol, subsize, n8x8L2, n4x4L2);
|
||||
DecodeBlock(ref twd, ref cm, miRow, miCol, subsize, n8X8L2, n4X4L2);
|
||||
if (hasCols)
|
||||
{
|
||||
DecodeBlock(ref twd, ref cm, miRow, miCol + hbs, subsize, n8x8L2, n4x4L2);
|
||||
DecodeBlock(ref twd, ref cm, miRow, miCol + hbs, subsize, n8X8L2, n4X4L2);
|
||||
}
|
||||
|
||||
break;
|
||||
case PartitionType.PartitionSplit:
|
||||
DecodePartition(ref twd, ref cm, miRow, miCol, subsize, n8x8L2);
|
||||
DecodePartition(ref twd, ref cm, miRow, miCol + hbs, subsize, n8x8L2);
|
||||
DecodePartition(ref twd, ref cm, miRow + hbs, miCol, subsize, n8x8L2);
|
||||
DecodePartition(ref twd, ref cm, miRow + hbs, miCol + hbs, subsize, n8x8L2);
|
||||
DecodePartition(ref twd, ref cm, miRow, miCol, subsize, n8X8L2);
|
||||
DecodePartition(ref twd, ref cm, miRow, miCol + hbs, subsize, n8X8L2);
|
||||
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");
|
||||
@@ -1133,10 +1133,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
// Update partition context
|
||||
if (bsize >= BlockSize.Block8x8 &&
|
||||
(bsize == BlockSize.Block8x8 || partition != PartitionType.PartitionSplit))
|
||||
if (bsize >= BlockSize.Block8X8 &&
|
||||
(bsize == BlockSize.Block8X8 || partition != PartitionType.PartitionSplit))
|
||||
{
|
||||
DecUpdatePartitionContext(ref twd, miRow, miCol, subsize, num8x8Wh);
|
||||
DecUpdatePartitionContext(ref twd, miRow, miCol, subsize, num8X8Wh);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1186,7 +1186,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
private static void ReadCoefProbs(ref Vp9EntropyProbs fc, TxMode txMode, ref Reader r)
|
||||
{
|
||||
int maxTxSize = (int)Luts.TxModeToBiggestTxSize[(int)txMode];
|
||||
for (int txSize = (int)TxSize.Tx4x4; txSize <= maxTxSize; ++txSize)
|
||||
for (int txSize = (int)TxSize.Tx4X4; txSize <= maxTxSize; ++txSize)
|
||||
{
|
||||
ReadCoefProbsCommon(ref fc.CoefProbs[txSize], ref r, txSize);
|
||||
}
|
||||
@@ -1238,16 +1238,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
xd.Bd = (int)cm.BitDepth;
|
||||
}
|
||||
|
||||
private static readonly byte[] LiteralToFilter =
|
||||
{
|
||||
private static readonly byte[] _literalToFilter =
|
||||
[
|
||||
Constants.EightTapSmooth, Constants.EightTap, Constants.EightTapSharp, Constants.Bilinear
|
||||
};
|
||||
];
|
||||
|
||||
private static byte ReadInterpFilter(ref ReadBitBuffer rb)
|
||||
{
|
||||
return rb.ReadBit() != 0
|
||||
? (byte)Constants.Switchable
|
||||
: LiteralToFilter[rb.ReadLiteral(2)];
|
||||
: _literalToFilter[rb.ReadLiteral(2)];
|
||||
}
|
||||
|
||||
private static void SetupRenderSize(ref Vp9Common cm, ref ReadBitBuffer rb)
|
||||
@@ -1519,7 +1519,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
tileData.Xd.LeftSegContext = new Array8<sbyte>();
|
||||
for (miCol = tile.MiColStart; miCol < tile.MiColEnd; miCol += Constants.MiBlockSize)
|
||||
{
|
||||
DecodePartition(ref tileData, ref cm, miRow, miCol, BlockSize.Block64x64, 4);
|
||||
DecodePartition(ref tileData, ref cm, miRow, miCol, BlockSize.Block64X64, 4);
|
||||
}
|
||||
|
||||
cm.Mb.Corrupted |= tileData.Xd.Corrupted;
|
||||
@@ -1563,7 +1563,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
tileData.Xd.LeftSegContext = new Array8<sbyte>();
|
||||
for (int miCol = tile.MiColStart; miCol < tile.MiColEnd; miCol += Constants.MiBlockSize)
|
||||
{
|
||||
DecodePartition(ref tileData, ref cm, miRow, miCol, BlockSize.Block64x64, 4);
|
||||
DecodePartition(ref tileData, ref cm, miRow, miCol, BlockSize.Block64X64, 4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1990,7 +1990,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
cm.Error.InternalError(CodecErr.MemError, "Failed to allocate bool decoder 0");
|
||||
}
|
||||
|
||||
cm.TxMode = xd.Lossless ? TxMode.Only4x4 : r.ReadTxMode();
|
||||
cm.TxMode = xd.Lossless ? TxMode.Only4X4 : r.ReadTxMode();
|
||||
if (cm.TxMode == TxMode.TxModeSelect)
|
||||
{
|
||||
ReadTxModeProbs(ref fc, ref r);
|
||||
|
||||
@@ -59,9 +59,9 @@ 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();
|
||||
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,9 +72,9 @@ 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();
|
||||
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;
|
||||
@@ -86,10 +86,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int ctx = xd.GetTxSizeContext();
|
||||
ReadOnlySpan<byte> txProbs = GetTxProbs(ref cm.Fc.Value, maxTxSize, ctx);
|
||||
TxSize txSize = (TxSize)r.Read(txProbs[0]);
|
||||
if (txSize != TxSize.Tx4x4 && maxTxSize >= TxSize.Tx16x16)
|
||||
if (txSize != TxSize.Tx4X4 && maxTxSize >= TxSize.Tx16X16)
|
||||
{
|
||||
txSize += r.Read(txProbs[1]);
|
||||
if (txSize != TxSize.Tx8x8 && maxTxSize >= TxSize.Tx32x32)
|
||||
if (txSize != TxSize.Tx8X8 && maxTxSize >= TxSize.Tx32X32)
|
||||
{
|
||||
txSize += r.Read(txProbs[2]);
|
||||
}
|
||||
@@ -108,7 +108,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
TxMode txMode = cm.TxMode;
|
||||
BlockSize bsize = xd.Mi[0].Value.SbType;
|
||||
TxSize maxTxSize = Luts.MaxTxSizeLookup[(int)bsize];
|
||||
if (allowSelect && txMode == TxMode.TxModeSelect && bsize >= BlockSize.Block8x8)
|
||||
if (allowSelect && txMode == TxMode.TxModeSelect && bsize >= BlockSize.Block8X8)
|
||||
{
|
||||
return ReadSelectedTxSize(ref cm, ref xd, maxTxSize, ref r);
|
||||
}
|
||||
@@ -276,7 +276,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
// Fractional part
|
||||
fr = r.ReadTree(Luts.MvFPTree, class0 ? fc.Class0Fp[mvcomp][d].AsSpan() : fc.Fp[mvcomp].AsSpan());
|
||||
fr = r.ReadTree(Luts.MvFpTree, class0 ? fc.Class0Fp[mvcomp][d].AsSpan() : fc.Fp[mvcomp].AsSpan());
|
||||
|
||||
// High precision part (if hp is not used, the default value of the hp is 1)
|
||||
hp = usehp ? r.Read(class0 ? fc.Class0Hp[mvcomp] : fc.Hp[mvcomp]) : 1;
|
||||
@@ -415,7 +415,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
switch (bsize)
|
||||
{
|
||||
case BlockSize.Block4x4:
|
||||
case BlockSize.Block4X4:
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
mi.Bmi[i].Mode = ReadIntraModeY(ref cm, ref xd, ref r, 0);
|
||||
@@ -423,11 +423,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
mi.Mode = mi.Bmi[3].Mode;
|
||||
break;
|
||||
case BlockSize.Block4x8:
|
||||
case BlockSize.Block4X8:
|
||||
mi.Bmi[0].Mode = mi.Bmi[2].Mode = ReadIntraModeY(ref cm, ref xd, ref r, 0);
|
||||
mi.Bmi[1].Mode = mi.Bmi[3].Mode = mi.Mode = ReadIntraModeY(ref cm, ref xd, ref r, 0);
|
||||
break;
|
||||
case BlockSize.Block8x4:
|
||||
case BlockSize.Block8X4:
|
||||
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;
|
||||
@@ -595,7 +595,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int miRow,
|
||||
int miCol,
|
||||
int block,
|
||||
int isSub8x8)
|
||||
int isSub8X8)
|
||||
{
|
||||
ref Array4<sbyte> refSignBias = ref cm.RefFrameSignBias;
|
||||
int i, refmvCount = 0;
|
||||
@@ -612,7 +612,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
mvRefList.Slice(0, Constants.MaxMvRefCandidates).Fill(new Mv());
|
||||
|
||||
i = 0;
|
||||
if (isSub8x8 != 0)
|
||||
if (isSub8X8 != 0)
|
||||
{
|
||||
// If the size < 8x8 we get the mv from the bmi substructure for the
|
||||
// nearest two blocks.
|
||||
@@ -770,7 +770,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return refmvCount;
|
||||
}
|
||||
|
||||
private static void AppendSub8x8ForIdx(
|
||||
private static void AppendSub8X8ForIdx(
|
||||
ref Vp9Common cm,
|
||||
ref MacroBlockD xd,
|
||||
Span<Position> mvRefSearch,
|
||||
@@ -779,7 +779,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int refr,
|
||||
int miRow,
|
||||
int miCol,
|
||||
ref Mv bestSub8x8)
|
||||
ref Mv bestSub8X8)
|
||||
{
|
||||
Span<Mv> mvList = stackalloc Mv[Constants.MaxMvRefCandidates];
|
||||
ref ModeInfo mi = ref xd.Mi[0].Value;
|
||||
@@ -794,22 +794,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
switch (block)
|
||||
{
|
||||
case 0:
|
||||
bestSub8x8 = mvList[refmvCount - 1];
|
||||
bestSub8X8 = mvList[refmvCount - 1];
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
if (bMode == PredictionMode.NearestMv)
|
||||
{
|
||||
bestSub8x8 = bmi[0].Mv[refr];
|
||||
bestSub8X8 = bmi[0].Mv[refr];
|
||||
}
|
||||
else
|
||||
{
|
||||
bestSub8x8 = new Mv();
|
||||
bestSub8X8 = new Mv();
|
||||
for (int n = 0; n < refmvCount; ++n)
|
||||
{
|
||||
if (Unsafe.As<Mv, int>(ref bmi[0].Mv[refr]) != Unsafe.As<Mv, int>(ref mvList[n]))
|
||||
{
|
||||
bestSub8x8 = mvList[n];
|
||||
bestSub8X8 = mvList[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -819,7 +819,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
case 3:
|
||||
if (bMode == PredictionMode.NearestMv)
|
||||
{
|
||||
bestSub8x8 = bmi[2].Mv[refr];
|
||||
bestSub8X8 = bmi[2].Mv[refr];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -828,12 +828,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
candidates[1] = bmi[0].Mv[refr];
|
||||
candidates[2] = mvList[0];
|
||||
candidates[3] = mvList[1];
|
||||
bestSub8x8 = new Mv();
|
||||
bestSub8X8 = new Mv();
|
||||
for (int n = 0; n < 2 + Constants.MaxMvRefCandidates; ++n)
|
||||
{
|
||||
if (Unsafe.As<Mv, int>(ref bmi[2].Mv[refr]) != Unsafe.As<Mv, int>(ref candidates[n]))
|
||||
{
|
||||
bestSub8x8 = candidates[n];
|
||||
bestSub8X8 = candidates[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -889,7 +889,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (cm.Seg.IsSegFeatureActive(mi.SegmentId, SegLvlFeatures.Skip) != 0)
|
||||
{
|
||||
mi.Mode = PredictionMode.ZeroMv;
|
||||
if (bsize < BlockSize.Block8x8)
|
||||
if (bsize < BlockSize.Block8X8)
|
||||
{
|
||||
xd.ErrorInfo.Value.InternalError(CodecErr.UnsupBitstream,
|
||||
"Invalid usage of segement feature on small blocks");
|
||||
@@ -898,7 +898,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bsize >= BlockSize.Block8x8)
|
||||
if (bsize >= BlockSize.Block8X8)
|
||||
{
|
||||
mi.Mode = ReadInterMode(ref cm, ref xd, ref r, interModeCtx);
|
||||
}
|
||||
@@ -932,20 +932,20 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
? ReadSwitchableInterpFilter(ref cm, ref xd, ref r)
|
||||
: cm.InterpFilter;
|
||||
|
||||
if (bsize < BlockSize.Block8x8)
|
||||
if (bsize < BlockSize.Block8X8)
|
||||
{
|
||||
int num4x4W = 1 << xd.BmodeBlocksWl;
|
||||
int num4x4H = 1 << xd.BmodeBlocksHl;
|
||||
int num4X4W = 1 << xd.BmodeBlocksWl;
|
||||
int num4X4H = 1 << xd.BmodeBlocksHl;
|
||||
int idx, idy;
|
||||
PredictionMode bMode = 0;
|
||||
Array2<Mv> bestSub8x8 = new();
|
||||
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;
|
||||
for (idy = 0; idy < 2; idy += num4x4H)
|
||||
Unsafe.As<Mv, uint>(ref bestSub8X8[1]) = InvalidMv;
|
||||
for (idy = 0; idy < 2; idy += num4X4H)
|
||||
{
|
||||
for (idx = 0; idx < 2; idx += num4x4W)
|
||||
for (idx = 0; idx < 2; idx += num4X4W)
|
||||
{
|
||||
int j = (idy * 2) + idx;
|
||||
bMode = ReadInterMode(ref cm, ref xd, ref r, interModeCtx);
|
||||
@@ -954,24 +954,24 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
for (refr = 0; refr < 1 + isCompound; ++refr)
|
||||
{
|
||||
AppendSub8x8ForIdx(ref cm, ref xd, mvRefSearch, bMode, j, refr, miRow, miCol,
|
||||
ref bestSub8x8[refr]);
|
||||
AppendSub8X8ForIdx(ref cm, ref xd, mvRefSearch, bMode, j, refr, miRow, miCol,
|
||||
ref bestSub8X8[refr]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Assign(ref cm, ref xd, bMode, ref mi.Bmi[j].Mv, ref bestRefMvs, ref bestSub8x8,
|
||||
if (!Assign(ref cm, ref xd, bMode, ref mi.Bmi[j].Mv, ref bestRefMvs, ref bestSub8X8,
|
||||
isCompound, allowHp, ref r))
|
||||
{
|
||||
xd.Corrupted |= true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (num4x4H == 2)
|
||||
if (num4X4H == 2)
|
||||
{
|
||||
mi.Bmi[j + 2] = mi.Bmi[j];
|
||||
}
|
||||
|
||||
if (num4x4W == 2)
|
||||
if (num4X4W == 2)
|
||||
{
|
||||
mi.Bmi[j + 1] = mi.Bmi[j];
|
||||
}
|
||||
@@ -1084,7 +1084,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
switch (bsize)
|
||||
{
|
||||
case BlockSize.Block4x4:
|
||||
case BlockSize.Block4X4:
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
mi.Value.Bmi[i].Mode =
|
||||
@@ -1093,13 +1093,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
mi.Value.Mode = mi.Value.Bmi[3].Mode;
|
||||
break;
|
||||
case BlockSize.Block4x8:
|
||||
case BlockSize.Block4X8:
|
||||
mi.Value.Bmi[0].Mode = mi.Value.Bmi[2].Mode =
|
||||
ReadIntraMode(ref r, GetYModeProbs(ref cm.Fc.Value, mi, aboveMi, leftMi, 0));
|
||||
mi.Value.Bmi[1].Mode = mi.Value.Bmi[3].Mode = mi.Value.Mode =
|
||||
ReadIntraMode(ref r, GetYModeProbs(ref cm.Fc.Value, mi, aboveMi, leftMi, 1));
|
||||
break;
|
||||
case BlockSize.Block8x4:
|
||||
case BlockSize.Block8X4:
|
||||
mi.Value.Bmi[0].Mode = mi.Value.Bmi[1].Mode =
|
||||
ReadIntraMode(ref r, GetYModeProbs(ref cm.Fc.Value, mi, aboveMi, leftMi, 0));
|
||||
mi.Value.Bmi[2].Mode = mi.Value.Bmi[3].Mode = mi.Value.Mode =
|
||||
|
||||
@@ -17,10 +17,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return new Surface(width, height);
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> LiteralToFilter => new byte[]
|
||||
{
|
||||
private static ReadOnlySpan<byte> LiteralToFilter =>
|
||||
[
|
||||
Constants.EightTapSmooth, Constants.EightTap, Constants.EightTapSharp, Constants.Bilinear
|
||||
};
|
||||
];
|
||||
|
||||
public unsafe bool Decode(
|
||||
ref Vp9PictureInfo pictureInfo,
|
||||
|
||||
@@ -17,10 +17,10 @@ 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 DecodeCoefs(
|
||||
@@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
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.GetBandTranslate(txSize);
|
||||
int dqShift = txSize == TxSize.Tx32x32 ? 1 : 0;
|
||||
int dqShift = txSize == TxSize.Tx32X32 ? 1 : 0;
|
||||
int v;
|
||||
short dqv = dq[0];
|
||||
ReadOnlySpan<byte> cat6Prob = xd.Bd == 12
|
||||
@@ -242,7 +242,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
switch (txSize)
|
||||
{
|
||||
case TxSize.Tx4x4:
|
||||
case TxSize.Tx4X4:
|
||||
ctx = a[0] != 0 ? 1 : 0;
|
||||
ctx += l[0] != 0 ? 1 : 0;
|
||||
eob = DecodeCoefs(
|
||||
@@ -257,8 +257,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref r);
|
||||
a[0] = l[0] = (sbyte)(eob > 0 ? 1 : 0);
|
||||
break;
|
||||
case TxSize.Tx8x8:
|
||||
GetCtxShift(ref xd, ref ctxShiftA, ref ctxShiftL, x, y, 1 << (int)TxSize.Tx8x8);
|
||||
case TxSize.Tx8X8:
|
||||
GetCtxShift(ref xd, ref ctxShiftA, ref ctxShiftL, x, y, 1 << (int)TxSize.Tx8X8);
|
||||
ctx = MemoryMarshal.Cast<sbyte, ushort>(a)[0] != 0 ? 1 : 0;
|
||||
ctx += MemoryMarshal.Cast<sbyte, ushort>(l)[0] != 0 ? 1 : 0;
|
||||
eob = DecodeCoefs(
|
||||
@@ -274,8 +274,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
MemoryMarshal.Cast<sbyte, ushort>(a)[0] = (ushort)((eob > 0 ? 0x0101 : 0) >> ctxShiftA);
|
||||
MemoryMarshal.Cast<sbyte, ushort>(l)[0] = (ushort)((eob > 0 ? 0x0101 : 0) >> ctxShiftL);
|
||||
break;
|
||||
case TxSize.Tx16x16:
|
||||
GetCtxShift(ref xd, ref ctxShiftA, ref ctxShiftL, x, y, 1 << (int)TxSize.Tx16x16);
|
||||
case TxSize.Tx16X16:
|
||||
GetCtxShift(ref xd, ref ctxShiftA, ref ctxShiftL, x, y, 1 << (int)TxSize.Tx16X16);
|
||||
ctx = MemoryMarshal.Cast<sbyte, uint>(a)[0] != 0 ? 1 : 0;
|
||||
ctx += MemoryMarshal.Cast<sbyte, uint>(l)[0] != 0 ? 1 : 0;
|
||||
eob = DecodeCoefs(
|
||||
@@ -291,8 +291,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
MemoryMarshal.Cast<sbyte, uint>(a)[0] = (uint)((eob > 0 ? 0x01010101 : 0) >> ctxShiftA);
|
||||
MemoryMarshal.Cast<sbyte, uint>(l)[0] = (uint)((eob > 0 ? 0x01010101 : 0) >> ctxShiftL);
|
||||
break;
|
||||
case TxSize.Tx32x32:
|
||||
GetCtxShift(ref xd, ref ctxShiftA, ref ctxShiftL, x, y, 1 << (int)TxSize.Tx32x32);
|
||||
case TxSize.Tx32X32:
|
||||
GetCtxShift(ref xd, ref ctxShiftA, ref ctxShiftL, x, y, 1 << (int)TxSize.Tx32X32);
|
||||
// NOTE: Casting to ulong here is safe because the default memory
|
||||
// alignment is at least 8 bytes and the Tx32x32 is aligned on 8 byte
|
||||
// boundaries.
|
||||
|
||||
@@ -34,17 +34,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
return (ushort)((a + b + 1) >> 1);
|
||||
}
|
||||
|
||||
public static unsafe void D207Predictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D207Predictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D207Predictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D207Predictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D207Predictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D207Predictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D207Predictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D207Predictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D207Predictor(dst, stride, 32, above, left);
|
||||
}
|
||||
@@ -85,17 +85,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void D63Predictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D63Predictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D63Predictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D63Predictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D63Predictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D63Predictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D63Predictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D63Predictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D63Predictor(dst, stride, 32, above, left);
|
||||
}
|
||||
@@ -117,17 +117,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void D45Predictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D45Predictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D45Predictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D45Predictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D45Predictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D45Predictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D45Predictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D45Predictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D45Predictor(dst, stride, 32, above, left);
|
||||
}
|
||||
@@ -152,17 +152,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void D117Predictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D117Predictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D117Predictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D117Predictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D117Predictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D117Predictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D117Predictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D117Predictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D117Predictor(dst, stride, 32, above, left);
|
||||
}
|
||||
@@ -205,17 +205,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void D135Predictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D135Predictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D135Predictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D135Predictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D135Predictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D135Predictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D135Predictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D135Predictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D135Predictor(dst, stride, 32, above, left);
|
||||
}
|
||||
@@ -245,17 +245,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void D153Predictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D153Predictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D153Predictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D153Predictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D153Predictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D153Predictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void D153Predictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D153Predictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
D153Predictor(dst, stride, 32, above, left);
|
||||
}
|
||||
@@ -297,22 +297,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void VPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void VPredictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
VPredictor(dst, stride, 4, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void VPredictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void VPredictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
VPredictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void VPredictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void VPredictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
VPredictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void VPredictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void VPredictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
VPredictor(dst, stride, 32, above, left);
|
||||
}
|
||||
@@ -326,22 +326,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void HPredictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
HPredictor(dst, stride, 4, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void HPredictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void HPredictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
HPredictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void HPredictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void HPredictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
HPredictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void HPredictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void HPredictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
HPredictor(dst, stride, 32, above, left);
|
||||
}
|
||||
@@ -355,22 +355,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void TmPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TmPredictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TmPredictor(dst, stride, 4, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void TmPredictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TmPredictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TmPredictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void TmPredictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TmPredictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TmPredictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void TmPredictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TmPredictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TmPredictor(dst, stride, 32, above, left);
|
||||
}
|
||||
@@ -390,22 +390,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void Dc128Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void Dc128Predictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
Dc128Predictor(dst, stride, 4, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void Dc128Predictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void Dc128Predictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
Dc128Predictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void Dc128Predictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void Dc128Predictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
Dc128Predictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void Dc128Predictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void Dc128Predictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
Dc128Predictor(dst, stride, 32, above, left);
|
||||
}
|
||||
@@ -419,36 +419,36 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void DcLeftPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcLeftPredictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcLeftPredictor(dst, stride, 4, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void DcLeftPredictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcLeftPredictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcLeftPredictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void DcLeftPredictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcLeftPredictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcLeftPredictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void DcLeftPredictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcLeftPredictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcLeftPredictor(dst, stride, 32, above, left);
|
||||
}
|
||||
|
||||
private static unsafe void DcLeftPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int sum = 0;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
{
|
||||
sum += left[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
int expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
@@ -457,36 +457,36 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void DcTopPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcTopPredictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcTopPredictor(dst, stride, 4, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void DcTopPredictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcTopPredictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcTopPredictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void DcTopPredictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcTopPredictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcTopPredictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void DcTopPredictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcTopPredictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcTopPredictor(dst, stride, 32, above, left);
|
||||
}
|
||||
|
||||
private static unsafe void DcTopPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int sum = 0;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
{
|
||||
sum += above[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
int expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
@@ -495,29 +495,29 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void DcPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcPredictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcPredictor(dst, stride, 4, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void DcPredictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcPredictor8X8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcPredictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void DcPredictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcPredictor16X16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcPredictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void DcPredictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void DcPredictor32X32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
DcPredictor(dst, stride, 32, above, left);
|
||||
}
|
||||
|
||||
private static unsafe void DcPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int sum = 0;
|
||||
int count = 2 * bs;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
@@ -526,7 +526,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
sum += left[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (count >> 1)) / count;
|
||||
int expectedDc = (sum + (count >> 1)) / count;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
@@ -535,31 +535,31 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HePredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void HePredictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte h = above[-1];
|
||||
byte I = left[0];
|
||||
byte i = left[0];
|
||||
byte j = left[1];
|
||||
byte k = left[2];
|
||||
byte l = left[3];
|
||||
|
||||
MemoryUtil.Fill(dst + (stride * 0), Avg3(h, I, j), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 1), Avg3(I, j, k), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 0), Avg3(h, i, j), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 1), Avg3(i, j, k), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 2), Avg3(j, k, l), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 3), Avg3(k, l, l), 4);
|
||||
}
|
||||
|
||||
public static unsafe void VePredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void VePredictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte h = above[-1];
|
||||
byte I = above[0];
|
||||
byte i = above[0];
|
||||
byte j = above[1];
|
||||
byte k = above[2];
|
||||
byte l = above[3];
|
||||
byte m = above[4];
|
||||
|
||||
dst[0] = Avg3(h, I, j);
|
||||
dst[1] = Avg3(I, j, k);
|
||||
dst[0] = Avg3(h, i, j);
|
||||
dst[1] = Avg3(i, j, k);
|
||||
dst[2] = Avg3(j, k, l);
|
||||
dst[3] = Avg3(k, l, m);
|
||||
MemoryUtil.Copy(dst + (stride * 1), dst, 4);
|
||||
@@ -567,23 +567,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
MemoryUtil.Copy(dst + (stride * 3), dst, 4);
|
||||
}
|
||||
|
||||
public static unsafe void D207Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D207Predictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte I = left[0];
|
||||
byte i = left[0];
|
||||
byte j = left[1];
|
||||
byte k = left[2];
|
||||
byte l = left[3];
|
||||
Dst(dst, stride, 0, 0) = Avg2(I, j);
|
||||
Dst(dst, stride, 0, 0) = Avg2(i, j);
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 0, 1) = Avg2(j, k);
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 0, 2) = Avg2(k, l);
|
||||
Dst(dst, stride, 1, 0) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 1, 0) = Avg3(i, j, k);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 1, 1) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 1, 2) = Avg3(k, l, l);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 0, 3) =
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 2, 3) = Dst(dst, stride, 3, 3) = l;
|
||||
}
|
||||
|
||||
public static unsafe void D63Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D63Predictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte a = above[0];
|
||||
byte b = above[1];
|
||||
@@ -605,7 +605,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
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)
|
||||
public static unsafe void D63EPredictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte a = above[0];
|
||||
byte b = above[1];
|
||||
@@ -628,7 +628,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 3, 3) = Avg3(f, g, h);
|
||||
}
|
||||
|
||||
public static unsafe void D45Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D45Predictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte a = above[0];
|
||||
byte b = above[1];
|
||||
@@ -648,7 +648,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 3, 3) = h; // differs from vp8
|
||||
}
|
||||
|
||||
public static unsafe void D45EPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D45EPredictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte a = above[0];
|
||||
byte b = above[1];
|
||||
@@ -668,9 +668,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 3, 3) = Avg3(g, h, h);
|
||||
}
|
||||
|
||||
public static unsafe void D117Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D117Predictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte I = left[0];
|
||||
byte i = left[0];
|
||||
byte j = left[1];
|
||||
byte k = left[2];
|
||||
byte x = above[-1];
|
||||
@@ -683,17 +683,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 3, 2) = Avg2(b, c);
|
||||
Dst(dst, stride, 3, 0) = Avg2(c, d);
|
||||
|
||||
Dst(dst, stride, 0, 3) = Avg3(k, j, I);
|
||||
Dst(dst, stride, 0, 2) = Avg3(j, I, x);
|
||||
Dst(dst, stride, 0, 1) = Dst(dst, stride, 1, 3) = Avg3(I, x, a);
|
||||
Dst(dst, stride, 0, 3) = Avg3(k, j, i);
|
||||
Dst(dst, stride, 0, 2) = Avg3(j, i, x);
|
||||
Dst(dst, stride, 0, 1) = Dst(dst, stride, 1, 3) = Avg3(i, x, a);
|
||||
Dst(dst, stride, 1, 1) = Dst(dst, stride, 2, 3) = Avg3(x, a, b);
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 3, 3) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 3, 1) = Avg3(b, c, d);
|
||||
}
|
||||
|
||||
public static unsafe void D135Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D135Predictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte I = left[0];
|
||||
byte i = left[0];
|
||||
byte j = left[1];
|
||||
byte k = left[2];
|
||||
byte l = left[3];
|
||||
@@ -703,18 +703,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
byte c = above[2];
|
||||
byte d = above[3];
|
||||
Dst(dst, stride, 0, 3) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 0, 2) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 2, 3) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 1) = Avg3(x, I, j);
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 0, 2) = Avg3(i, j, k);
|
||||
Dst(dst, stride, 2, 3) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 1) = Avg3(x, i, j);
|
||||
Dst(dst, stride, 3, 3) =
|
||||
Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, I);
|
||||
Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, i);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 0) = Avg3(b, a, x);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 0) = Avg3(c, b, a);
|
||||
Dst(dst, stride, 3, 0) = Avg3(d, c, b);
|
||||
}
|
||||
|
||||
public static unsafe void D153Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D153Predictor4X4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte I = left[0];
|
||||
byte i = left[0];
|
||||
byte j = left[1];
|
||||
byte k = left[2];
|
||||
byte l = left[3];
|
||||
@@ -722,30 +722,30 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
byte a = above[0];
|
||||
byte b = above[1];
|
||||
byte c = above[2];
|
||||
Dst(dst, stride, 0, 0) = Dst(dst, stride, 2, 1) = Avg2(I, x);
|
||||
Dst(dst, stride, 0, 1) = Dst(dst, stride, 2, 2) = Avg2(j, I);
|
||||
Dst(dst, stride, 0, 0) = Dst(dst, stride, 2, 1) = Avg2(i, x);
|
||||
Dst(dst, stride, 0, 1) = Dst(dst, stride, 2, 2) = Avg2(j, i);
|
||||
Dst(dst, stride, 0, 2) = Dst(dst, stride, 2, 3) = Avg2(k, j);
|
||||
Dst(dst, stride, 0, 3) = Avg2(l, k);
|
||||
|
||||
Dst(dst, stride, 3, 0) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 2, 0) = Avg3(x, a, b);
|
||||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 3, 1) = Avg3(I, x, a);
|
||||
Dst(dst, stride, 1, 1) = Dst(dst, stride, 3, 2) = Avg3(j, I, x);
|
||||
Dst(dst, stride, 1, 2) = Dst(dst, stride, 3, 3) = Avg3(k, j, I);
|
||||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 3, 1) = Avg3(i, x, a);
|
||||
Dst(dst, stride, 1, 1) = Dst(dst, stride, 3, 2) = Avg3(j, i, x);
|
||||
Dst(dst, stride, 1, 2) = Dst(dst, stride, 3, 3) = Avg3(k, j, i);
|
||||
Dst(dst, stride, 1, 3) = Avg3(l, k, j);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD207Predictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD207Predictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD207Predictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD207Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD207Predictor16X16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD207Predictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD207Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD207Predictor32X32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD207Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
@@ -787,17 +787,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD63Predictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD63Predictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD63Predictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD63Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD63Predictor16X16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD63Predictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD63Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD63Predictor32X32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD63Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
@@ -820,17 +820,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD45Predictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD45Predictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD45Predictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD45Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD45Predictor16X16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD45Predictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD45Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD45Predictor32X32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD45Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
@@ -856,17 +856,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD117Predictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD117Predictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD117Predictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD117Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD117Predictor16X16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD117Predictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD117Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD117Predictor32X32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD117Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
@@ -910,17 +910,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD135Predictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD135Predictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD135Predictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD135Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD135Predictor16X16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD135Predictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD135Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD135Predictor32X32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD135Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
@@ -951,17 +951,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD153Predictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD153Predictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD153Predictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD153Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD153Predictor16X16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD153Predictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD153Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD153Predictor32X32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdD153Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
@@ -1004,22 +1004,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdVPredictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdVPredictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdVPredictor(dst, stride, 4, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdVPredictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdVPredictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdVPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdVPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdVPredictor16X16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdVPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdVPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdVPredictor32X32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdVPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
@@ -1034,22 +1034,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdHPredictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdHPredictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdHPredictor(dst, stride, 4, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdHPredictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdHPredictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdHPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdHPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdHPredictor16X16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdHPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdHPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdHPredictor32X32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdHPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
@@ -1064,22 +1064,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTmPredictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTmPredictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTmPredictor(dst, stride, 4, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTmPredictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTmPredictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTmPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTmPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTmPredictor16X16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTmPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTmPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTmPredictor32X32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTmPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
@@ -1100,23 +1100,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDc128Predictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDc128Predictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDc128Predictor(dst, stride, 4, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDc128Predictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDc128Predictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDc128Predictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDc128Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
public static unsafe void HighbdDc128Predictor16X16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDc128Predictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDc128Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
public static unsafe void HighbdDc128Predictor32X32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDc128Predictor(dst, stride, 32, above, left, bd);
|
||||
@@ -1132,23 +1132,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcLeftPredictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcLeftPredictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcLeftPredictor(dst, stride, 4, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcLeftPredictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcLeftPredictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcLeftPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcLeftPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
public static unsafe void HighbdDcLeftPredictor16X16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDcLeftPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcLeftPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
public static unsafe void HighbdDcLeftPredictor32X32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDcLeftPredictor(dst, stride, 32, above, left, bd);
|
||||
@@ -1157,14 +1157,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
private static unsafe void HighbdDcLeftPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int sum = 0;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
{
|
||||
sum += left[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
int expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
@@ -1173,23 +1173,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcTopPredictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcTopPredictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcTopPredictor(dst, stride, 4, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcTopPredictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcTopPredictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcTopPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcTopPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
public static unsafe void HighbdDcTopPredictor16X16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDcTopPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcTopPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
public static unsafe void HighbdDcTopPredictor32X32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDcTopPredictor(dst, stride, 32, above, left, bd);
|
||||
@@ -1198,14 +1198,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
private static unsafe void HighbdDcTopPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int sum = 0;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
{
|
||||
sum += above[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
int expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
@@ -1214,22 +1214,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcPredictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcPredictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcPredictor(dst, stride, 4, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcPredictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcPredictor8X8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcPredictor16X16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcPredictor32X32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdDcPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
@@ -1237,7 +1237,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
private static unsafe void HighbdDcPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int expectedDc, sum = 0;
|
||||
int sum = 0;
|
||||
int count = 2 * bs;
|
||||
|
||||
for (int i = 0; i < bs; i++)
|
||||
@@ -1246,7 +1246,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
sum += left[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (count >> 1)) / count;
|
||||
int expectedDc = (sum + (count >> 1)) / count;
|
||||
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
@@ -1255,23 +1255,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD207Predictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD207Predictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
ushort I = left[0];
|
||||
ushort i = left[0];
|
||||
ushort j = left[1];
|
||||
ushort k = left[2];
|
||||
ushort l = left[3];
|
||||
Dst(dst, stride, 0, 0) = Avg2(I, j);
|
||||
Dst(dst, stride, 0, 0) = Avg2(i, j);
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 0, 1) = Avg2(j, k);
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 0, 2) = Avg2(k, l);
|
||||
Dst(dst, stride, 1, 0) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 1, 0) = Avg3(i, j, k);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 1, 1) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 1, 2) = Avg3(k, l, l);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 0, 3) =
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 2, 3) = Dst(dst, stride, 3, 3) = l;
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD63Predictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD63Predictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
ushort a = above[0];
|
||||
ushort b = above[1];
|
||||
@@ -1293,7 +1293,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
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)
|
||||
public static unsafe void HighbdD45Predictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
ushort a = above[0];
|
||||
ushort b = above[1];
|
||||
@@ -1313,9 +1313,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 3, 3) = h; // Differs from vp8
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD117Predictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD117Predictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
ushort I = left[0];
|
||||
ushort i = left[0];
|
||||
ushort j = left[1];
|
||||
ushort k = left[2];
|
||||
ushort x = above[-1];
|
||||
@@ -1328,17 +1328,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 3, 2) = Avg2(b, c);
|
||||
Dst(dst, stride, 3, 0) = Avg2(c, d);
|
||||
|
||||
Dst(dst, stride, 0, 3) = Avg3(k, j, I);
|
||||
Dst(dst, stride, 0, 2) = Avg3(j, I, x);
|
||||
Dst(dst, stride, 0, 1) = Dst(dst, stride, 1, 3) = Avg3(I, x, a);
|
||||
Dst(dst, stride, 0, 3) = Avg3(k, j, i);
|
||||
Dst(dst, stride, 0, 2) = Avg3(j, i, x);
|
||||
Dst(dst, stride, 0, 1) = Dst(dst, stride, 1, 3) = Avg3(i, x, a);
|
||||
Dst(dst, stride, 1, 1) = Dst(dst, stride, 2, 3) = Avg3(x, a, b);
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 3, 3) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 3, 1) = Avg3(b, c, d);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD135Predictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD135Predictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
ushort I = left[0];
|
||||
ushort i = left[0];
|
||||
ushort j = left[1];
|
||||
ushort k = left[2];
|
||||
ushort l = left[3];
|
||||
@@ -1348,18 +1348,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
ushort c = above[2];
|
||||
ushort d = above[3];
|
||||
Dst(dst, stride, 0, 3) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 0, 2) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 2, 3) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 1) = Avg3(x, I, j);
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 0, 2) = Avg3(i, j, k);
|
||||
Dst(dst, stride, 2, 3) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 1) = Avg3(x, i, j);
|
||||
Dst(dst, stride, 3, 3) =
|
||||
Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, I);
|
||||
Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, i);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 0) = Avg3(b, a, x);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 0) = Avg3(c, b, a);
|
||||
Dst(dst, stride, 3, 0) = Avg3(d, c, b);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD153Predictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdD153Predictor4X4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
ushort I = left[0];
|
||||
ushort i = left[0];
|
||||
ushort j = left[1];
|
||||
ushort k = left[2];
|
||||
ushort l = left[3];
|
||||
@@ -1368,17 +1368,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
ushort b = above[1];
|
||||
ushort c = above[2];
|
||||
|
||||
Dst(dst, stride, 0, 0) = Dst(dst, stride, 2, 1) = Avg2(I, x);
|
||||
Dst(dst, stride, 0, 1) = Dst(dst, stride, 2, 2) = Avg2(j, I);
|
||||
Dst(dst, stride, 0, 0) = Dst(dst, stride, 2, 1) = Avg2(i, x);
|
||||
Dst(dst, stride, 0, 1) = Dst(dst, stride, 2, 2) = Avg2(j, i);
|
||||
Dst(dst, stride, 0, 2) = Dst(dst, stride, 2, 3) = Avg2(k, j);
|
||||
Dst(dst, stride, 0, 3) = Avg2(l, k);
|
||||
|
||||
Dst(dst, stride, 3, 0) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 2, 0) = Avg3(x, a, b);
|
||||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 3, 1) = Avg3(I, x, a);
|
||||
Dst(dst, stride, 1, 1) = Dst(dst, stride, 3, 2) = Avg3(j, I, x);
|
||||
Dst(dst, stride, 1, 2) = Dst(dst, stride, 3, 3) = Avg3(k, j, I);
|
||||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 3, 1) = Avg3(i, x, a);
|
||||
Dst(dst, stride, 1, 1) = Dst(dst, stride, 3, 2) = Avg3(j, i, x);
|
||||
Dst(dst, stride, 1, 2) = Dst(dst, stride, 3, 3) = Avg3(k, j, i);
|
||||
Dst(dst, stride, 1, 3) = Avg3(l, k, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Iwht4x416Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Iwht4X416Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
/* 4-point reversible, orthonormal inverse Walsh-Hadamard in 3.5 adds,
|
||||
0.5 shifts per pixel. */
|
||||
@@ -143,7 +143,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Iwht4x41Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Iwht4X41Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
long a1, e1;
|
||||
Span<int> tmp = stackalloc int[4];
|
||||
@@ -233,7 +233,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Idct4x416Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct4X416Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
Span<int> output = stackalloc int[4 * 4];
|
||||
Span<int> outptr = output;
|
||||
@@ -265,7 +265,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static void Idct4x41Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct4X41Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
long a1;
|
||||
int output = WrapLow(DctConstRoundShift((short)input[0] * CosPi1664));
|
||||
@@ -419,7 +419,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Idct8x864Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct8X864Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
Span<int> output = stackalloc int[8 * 8];
|
||||
Span<int> outptr = output;
|
||||
@@ -452,7 +452,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Idct8x812Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct8X812Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
Span<int> output = stackalloc int[8 * 8];
|
||||
Span<int> outptr = output;
|
||||
@@ -487,7 +487,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static void Idct8x81Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct8X81Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
long a1;
|
||||
int output = WrapLow(DctConstRoundShift((short)input[0] * CosPi1664));
|
||||
@@ -843,7 +843,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Idct16x16256Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct16X16256Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
@@ -876,7 +876,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Idct16x1638Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct16X1638Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
@@ -912,7 +912,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Idct16x1610Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct16X1610Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
@@ -947,7 +947,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static void Idct16x161Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct16X161Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
long a1;
|
||||
int output = WrapLow(DctConstRoundShift((short)input[0] * CosPi1664));
|
||||
@@ -1336,7 +1336,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Idct32x321024Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct32X321024Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
Span<int> output = stackalloc int[32 * 32];
|
||||
Span<int> outptr = output;
|
||||
@@ -1383,7 +1383,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Idct32x32135Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct32X32135Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
Span<int> output = stackalloc int[32 * 32];
|
||||
Span<int> outptr = output;
|
||||
@@ -1419,7 +1419,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void Idct32x3234Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct32X3234Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
Span<int> output = stackalloc int[32 * 32];
|
||||
Span<int> outptr = output;
|
||||
@@ -1454,7 +1454,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static void Idct32x321Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
public static void Idct32X321Add(ReadOnlySpan<int> input, Span<byte> dest, int stride)
|
||||
{
|
||||
long a1;
|
||||
int output = WrapLow(DctConstRoundShift((short)input[0] * CosPi1664));
|
||||
@@ -1474,7 +1474,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIwht4x416Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIwht4X416Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
/* 4-point reversible, orthonormal inverse Walsh-Hadamard in 3.5 adds,
|
||||
0.5 shifts per pixel. */
|
||||
@@ -1530,7 +1530,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIwht4x41Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIwht4X41Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
long a1, e1;
|
||||
Span<int> tmp = stackalloc int[4];
|
||||
@@ -1633,7 +1633,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIdct4x416Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct4X416Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[4 * 4];
|
||||
Span<int> outptr = output;
|
||||
@@ -1665,7 +1665,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIdct4x41Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct4X41Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
long a1;
|
||||
int output = HighbdWrapLow(DctConstRoundShift(input[0] * (long)CosPi1664), bd);
|
||||
@@ -1824,7 +1824,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIdct8x864Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct8X864Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[8 * 8];
|
||||
Span<int> outptr = output;
|
||||
@@ -1857,7 +1857,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIdct8x812Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct8X812Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[8 * 8];
|
||||
Span<int> outptr = output;
|
||||
@@ -1892,7 +1892,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static void VpxHighbdidct8x81AddC(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void VpxHighbdidct8X81AddC(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
long a1;
|
||||
int output = HighbdWrapLow(DctConstRoundShift(input[0] * (long)CosPi1664), bd);
|
||||
@@ -2261,7 +2261,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIdct16x16256Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct16X16256Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
@@ -2294,7 +2294,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIdct16x1638Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct16X1638Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
@@ -2331,7 +2331,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIdct16x1610Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct16X1610Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
@@ -2366,7 +2366,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIdct16x161Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct16X161Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
long a1;
|
||||
int output = HighbdWrapLow(DctConstRoundShift(input[0] * (long)CosPi1664), bd);
|
||||
@@ -2762,7 +2762,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIdct32x321024Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct32X321024Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[32 * 32];
|
||||
Span<int> outptr = output;
|
||||
@@ -2809,7 +2809,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIdct32x32135Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct32X32135Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[32 * 32];
|
||||
Span<int> outptr = output;
|
||||
@@ -2846,7 +2846,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public static void HighbdIdct32x3234Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct32X3234Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[32 * 32];
|
||||
Span<int> outptr = output;
|
||||
@@ -2881,7 +2881,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIdct32x321Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
public static void HighbdIdct32X321Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int bd)
|
||||
{
|
||||
int a1;
|
||||
int output = HighbdWrapLow(DctConstRoundShift(input[0] * (long)CosPi1664), bd);
|
||||
|
||||
@@ -1553,7 +1553,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe void Transpose8x16(
|
||||
private static unsafe void Transpose8X16(
|
||||
ArrayPtr<byte> in0,
|
||||
ArrayPtr<byte> in1,
|
||||
int inP,
|
||||
@@ -1633,15 +1633,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int inP,
|
||||
ReadOnlySpan<ArrayPtr<byte>> dst,
|
||||
int outP,
|
||||
int num8x8ToTranspose)
|
||||
int num8X8ToTranspose)
|
||||
{
|
||||
int idx8x8 = 0;
|
||||
int idx8X8 = 0;
|
||||
Vector128<byte> x0, x1, x2, x3, x4, x5, x6, x7;
|
||||
|
||||
do
|
||||
{
|
||||
ArrayPtr<byte> input = src[idx8x8];
|
||||
ArrayPtr<byte> output = dst[idx8x8];
|
||||
ArrayPtr<byte> input = src[idx8X8];
|
||||
ArrayPtr<byte> output = dst[idx8X8];
|
||||
|
||||
x0 = Sse2.LoadScalarVector128((long*)(input.ToPointer() + (0 * inP)))
|
||||
.AsByte(); // 00 01 02 03 04 05 06 07
|
||||
@@ -1697,7 +1697,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
Sse2.StoreScalar((long*)(output.ToPointer() + (6 * outP)), x7.AsInt64()); // 06 16 26 36 46 56 66 76
|
||||
Sse2.StoreHigh((double*)(output.ToPointer() + (7 * outP)), x7.AsDouble()); // 07 17 27 37 47 57 67 77
|
||||
} while (++idx8x8 < num8x8ToTranspose);
|
||||
} while (++idx8X8 < num8X8ToTranspose);
|
||||
}
|
||||
|
||||
public static unsafe void LpfVertical4Dual(
|
||||
@@ -1716,7 +1716,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Span<ArrayPtr<byte>> dst = stackalloc ArrayPtr<byte>[2];
|
||||
|
||||
// Transpose 8x16
|
||||
Transpose8x16(s.Slice(-4), s.Slice(-4 + (pitch * 8)), pitch, tDst, 16);
|
||||
Transpose8X16(s.Slice(-4), s.Slice(-4 + (pitch * 8)), pitch, tDst, 16);
|
||||
|
||||
// Loop filtering
|
||||
LpfHorizontal4Dual(tDst.Slice(4 * 16), 16, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
|
||||
@@ -1770,7 +1770,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Span<ArrayPtr<byte>> dst = stackalloc ArrayPtr<byte>[2];
|
||||
|
||||
// Transpose 8x16
|
||||
Transpose8x16(s.Slice(-4), s.Slice(-4 + (pitch * 8)), pitch, tDst, 16);
|
||||
Transpose8X16(s.Slice(-4), s.Slice(-4 + (pitch * 8)), pitch, tDst, 16);
|
||||
|
||||
// Loop filtering
|
||||
LpfHorizontal8Dual(tDst.Slice(4 * 16), 16, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
|
||||
@@ -1823,15 +1823,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
ArrayPtr<byte> tDst = new((byte*)tDstStorage, 256);
|
||||
|
||||
// Transpose 16x16
|
||||
Transpose8x16(s.Slice(-8), s.Slice(-8 + (8 * pitch)), pitch, tDst, 16);
|
||||
Transpose8x16(s, s.Slice(8 * pitch), pitch, tDst.Slice(8 * 16), 16);
|
||||
Transpose8X16(s.Slice(-8), s.Slice(-8 + (8 * pitch)), pitch, tDst, 16);
|
||||
Transpose8X16(s, s.Slice(8 * pitch), pitch, tDst.Slice(8 * 16), 16);
|
||||
|
||||
// Loop filtering
|
||||
LpfHorizontal16Dual(tDst.Slice(8 * 16), 16, blimit, limit, thresh);
|
||||
|
||||
// Transpose back
|
||||
Transpose8x16(tDst, tDst.Slice(8 * 16), 16, s.Slice(-8), pitch);
|
||||
Transpose8x16(tDst.Slice(8), tDst.Slice(8 + (8 * 16)), 16, s.Slice(-8 + (8 * pitch)), pitch);
|
||||
Transpose8X16(tDst, tDst.Slice(8 * 16), 16, s.Slice(-8), pitch);
|
||||
Transpose8X16(tDst.Slice(8), tDst.Slice(8 + (8 * 16)), 16, s.Slice(-8 + (8 * pitch)), pitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,10 +26,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
// MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT;
|
||||
private static readonly uint[] CountToUpdateFactor =
|
||||
{
|
||||
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
|
||||
};
|
||||
];
|
||||
|
||||
private const int ModeMvCountSat = 20;
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
internal struct Reader
|
||||
{
|
||||
private static readonly byte[] Norm =
|
||||
{
|
||||
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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
@@ -17,7 +17,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
|
||||
};
|
||||
];
|
||||
|
||||
private const int BdValueSize = sizeof(ulong) * 8;
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
{
|
||||
int shift = Norm[range];
|
||||
int shift = _norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
@@ -203,7 +203,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
range = range - split;
|
||||
value = value - bigsplit;
|
||||
{
|
||||
int shift = Norm[range];
|
||||
int shift = _norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
@@ -213,7 +213,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
range = split;
|
||||
{
|
||||
int shift = Norm[range];
|
||||
int shift = _norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
@@ -235,10 +235,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private int DecodeUniform()
|
||||
{
|
||||
const int l = 8;
|
||||
const int m = (1 << l) - 191;
|
||||
int v = ReadLiteral(l - 1);
|
||||
return v < m ? v : (v << 1) - m + ReadBit();
|
||||
const int L = 8;
|
||||
const int M = (1 << L) - 191;
|
||||
int v = ReadLiteral(L - 1);
|
||||
return v < M ? v : (v << 1) - M + ReadBit();
|
||||
}
|
||||
|
||||
public int DecodeTermSubexp()
|
||||
@@ -264,7 +264,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
public TxMode ReadTxMode()
|
||||
{
|
||||
TxMode txMode = (TxMode)ReadLiteral(2);
|
||||
if (txMode == TxMode.Allow32x32)
|
||||
if (txMode == TxMode.Allow32X32)
|
||||
{
|
||||
txMode += ReadBit();
|
||||
}
|
||||
|
||||
@@ -64,26 +64,26 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
public const int Cat5MinVal = 35;
|
||||
public const int Cat6MinVal = 67;
|
||||
|
||||
public static readonly byte[] Cat1Prob = { 159 };
|
||||
public static readonly byte[] Cat2Prob = { 165, 145 };
|
||||
public static readonly byte[] Cat3Prob = { 173, 148, 140 };
|
||||
public static readonly byte[] Cat4Prob = { 176, 155, 140, 135 };
|
||||
public static readonly byte[] Cat5Prob = { 180, 157, 141, 134, 130 };
|
||||
public static readonly byte[] Cat1Prob = [159];
|
||||
public static readonly byte[] Cat2Prob = [165, 145];
|
||||
public static readonly byte[] Cat3Prob = [173, 148, 140];
|
||||
public static readonly byte[] Cat4Prob = [176, 155, 140, 135];
|
||||
public static readonly byte[] Cat5Prob = [180, 157, 141, 134, 130];
|
||||
|
||||
public static readonly byte[] Cat6Prob =
|
||||
{
|
||||
[
|
||||
254, 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129
|
||||
};
|
||||
];
|
||||
|
||||
public static readonly byte[] Cat6ProbHigh12 =
|
||||
{
|
||||
[
|
||||
255, 255, 255, 255, 254, 254, 54, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129
|
||||
};
|
||||
];
|
||||
|
||||
public const int EobModelToken = 3;
|
||||
|
||||
private static readonly byte[] CoefbandTrans8x8Plus =
|
||||
{
|
||||
private static readonly byte[] _coefbandTrans8X8Plus =
|
||||
[
|
||||
0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
|
||||
// beyond MAXBAND_INDEX+1 all values are filled as 5
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
@@ -114,260 +114,260 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly byte[] CoefbandTrans4x4 = { 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5 };
|
||||
private static readonly byte[] _coefbandTrans4X4 = [0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5];
|
||||
|
||||
public static readonly byte[][] Pareto8Full =
|
||||
{
|
||||
new byte[] { 3, 86, 128, 6, 86, 23, 88, 29 }, new byte[] { 6, 86, 128, 11, 87, 42, 91, 52 },
|
||||
new byte[] { 9, 86, 129, 17, 88, 61, 94, 76 }, new byte[] { 12, 86, 129, 22, 88, 77, 97, 93 },
|
||||
new byte[] { 15, 87, 129, 28, 89, 93, 100, 110 }, new byte[] { 17, 87, 129, 33, 90, 105, 103, 123 },
|
||||
new byte[] { 20, 88, 130, 38, 91, 118, 106, 136 }, new byte[] { 23, 88, 130, 43, 91, 128, 108, 146 },
|
||||
new byte[] { 26, 89, 131, 48, 92, 139, 111, 156 }, new byte[] { 28, 89, 131, 53, 93, 147, 114, 163 },
|
||||
new byte[] { 31, 90, 131, 58, 94, 156, 117, 171 }, new byte[] { 34, 90, 131, 62, 94, 163, 119, 177 },
|
||||
new byte[] { 37, 90, 132, 66, 95, 171, 122, 184 }, new byte[] { 39, 90, 132, 70, 96, 177, 124, 189 },
|
||||
new byte[] { 42, 91, 132, 75, 97, 183, 127, 194 }, new byte[] { 44, 91, 132, 79, 97, 188, 129, 198 },
|
||||
new byte[] { 47, 92, 133, 83, 98, 193, 132, 202 }, new byte[] { 49, 92, 133, 86, 99, 197, 134, 205 },
|
||||
new byte[] { 52, 93, 133, 90, 100, 201, 137, 208 }, new byte[] { 54, 93, 133, 94, 100, 204, 139, 211 },
|
||||
new byte[] { 57, 94, 134, 98, 101, 208, 142, 214 }, new byte[] { 59, 94, 134, 101, 102, 211, 144, 216 },
|
||||
new byte[] { 62, 94, 135, 105, 103, 214, 146, 218 },
|
||||
new byte[] { 64, 94, 135, 108, 103, 216, 148, 220 },
|
||||
new byte[] { 66, 95, 135, 111, 104, 219, 151, 222 },
|
||||
new byte[] { 68, 95, 135, 114, 105, 221, 153, 223 },
|
||||
new byte[] { 71, 96, 136, 117, 106, 224, 155, 225 },
|
||||
new byte[] { 73, 96, 136, 120, 106, 225, 157, 226 },
|
||||
new byte[] { 76, 97, 136, 123, 107, 227, 159, 228 },
|
||||
new byte[] { 78, 97, 136, 126, 108, 229, 160, 229 },
|
||||
new byte[] { 80, 98, 137, 129, 109, 231, 162, 231 },
|
||||
new byte[] { 82, 98, 137, 131, 109, 232, 164, 232 },
|
||||
new byte[] { 84, 98, 138, 134, 110, 234, 166, 233 },
|
||||
new byte[] { 86, 98, 138, 137, 111, 235, 168, 234 },
|
||||
new byte[] { 89, 99, 138, 140, 112, 236, 170, 235 },
|
||||
new byte[] { 91, 99, 138, 142, 112, 237, 171, 235 },
|
||||
new byte[] { 93, 100, 139, 145, 113, 238, 173, 236 },
|
||||
new byte[] { 95, 100, 139, 147, 114, 239, 174, 237 },
|
||||
new byte[] { 97, 101, 140, 149, 115, 240, 176, 238 },
|
||||
new byte[] { 99, 101, 140, 151, 115, 241, 177, 238 },
|
||||
new byte[] { 101, 102, 140, 154, 116, 242, 179, 239 },
|
||||
new byte[] { 103, 102, 140, 156, 117, 242, 180, 239 },
|
||||
new byte[] { 105, 103, 141, 158, 118, 243, 182, 240 },
|
||||
new byte[] { 107, 103, 141, 160, 118, 243, 183, 240 },
|
||||
new byte[] { 109, 104, 141, 162, 119, 244, 185, 241 },
|
||||
new byte[] { 111, 104, 141, 164, 119, 244, 186, 241 },
|
||||
new byte[] { 113, 104, 142, 166, 120, 245, 187, 242 },
|
||||
new byte[] { 114, 104, 142, 168, 121, 245, 188, 242 },
|
||||
new byte[] { 116, 105, 143, 170, 122, 246, 190, 243 },
|
||||
new byte[] { 118, 105, 143, 171, 122, 246, 191, 243 },
|
||||
new byte[] { 120, 106, 143, 173, 123, 247, 192, 244 },
|
||||
new byte[] { 121, 106, 143, 175, 124, 247, 193, 244 },
|
||||
new byte[] { 123, 107, 144, 177, 125, 248, 195, 244 },
|
||||
new byte[] { 125, 107, 144, 178, 125, 248, 196, 244 },
|
||||
new byte[] { 127, 108, 145, 180, 126, 249, 197, 245 },
|
||||
new byte[] { 128, 108, 145, 181, 127, 249, 198, 245 },
|
||||
new byte[] { 130, 109, 145, 183, 128, 249, 199, 245 },
|
||||
new byte[] { 132, 109, 145, 184, 128, 249, 200, 245 },
|
||||
new byte[] { 134, 110, 146, 186, 129, 250, 201, 246 },
|
||||
new byte[] { 135, 110, 146, 187, 130, 250, 202, 246 },
|
||||
new byte[] { 137, 111, 147, 189, 131, 251, 203, 246 },
|
||||
new byte[] { 138, 111, 147, 190, 131, 251, 204, 246 },
|
||||
new byte[] { 140, 112, 147, 192, 132, 251, 205, 247 },
|
||||
new byte[] { 141, 112, 147, 193, 132, 251, 206, 247 },
|
||||
new byte[] { 143, 113, 148, 194, 133, 251, 207, 247 },
|
||||
new byte[] { 144, 113, 148, 195, 134, 251, 207, 247 },
|
||||
new byte[] { 146, 114, 149, 197, 135, 252, 208, 248 },
|
||||
new byte[] { 147, 114, 149, 198, 135, 252, 209, 248 },
|
||||
new byte[] { 149, 115, 149, 199, 136, 252, 210, 248 },
|
||||
new byte[] { 150, 115, 149, 200, 137, 252, 210, 248 },
|
||||
new byte[] { 152, 115, 150, 201, 138, 252, 211, 248 },
|
||||
new byte[] { 153, 115, 150, 202, 138, 252, 212, 248 },
|
||||
new byte[] { 155, 116, 151, 204, 139, 253, 213, 249 },
|
||||
new byte[] { 156, 116, 151, 205, 139, 253, 213, 249 },
|
||||
new byte[] { 158, 117, 151, 206, 140, 253, 214, 249 },
|
||||
new byte[] { 159, 117, 151, 207, 141, 253, 215, 249 },
|
||||
new byte[] { 161, 118, 152, 208, 142, 253, 216, 249 },
|
||||
new byte[] { 162, 118, 152, 209, 142, 253, 216, 249 },
|
||||
new byte[] { 163, 119, 153, 210, 143, 253, 217, 249 },
|
||||
new byte[] { 164, 119, 153, 211, 143, 253, 217, 249 },
|
||||
new byte[] { 166, 120, 153, 212, 144, 254, 218, 250 },
|
||||
new byte[] { 167, 120, 153, 212, 145, 254, 219, 250 },
|
||||
new byte[] { 168, 121, 154, 213, 146, 254, 220, 250 },
|
||||
new byte[] { 169, 121, 154, 214, 146, 254, 220, 250 },
|
||||
new byte[] { 171, 122, 155, 215, 147, 254, 221, 250 },
|
||||
new byte[] { 172, 122, 155, 216, 147, 254, 221, 250 },
|
||||
new byte[] { 173, 123, 155, 217, 148, 254, 222, 250 },
|
||||
new byte[] { 174, 123, 155, 217, 149, 254, 222, 250 },
|
||||
new byte[] { 176, 124, 156, 218, 150, 254, 223, 250 },
|
||||
new byte[] { 177, 124, 156, 219, 150, 254, 223, 250 },
|
||||
new byte[] { 178, 125, 157, 220, 151, 254, 224, 251 },
|
||||
new byte[] { 179, 125, 157, 220, 151, 254, 224, 251 },
|
||||
new byte[] { 180, 126, 157, 221, 152, 254, 225, 251 },
|
||||
new byte[] { 181, 126, 157, 221, 152, 254, 225, 251 },
|
||||
new byte[] { 183, 127, 158, 222, 153, 254, 226, 251 },
|
||||
new byte[] { 184, 127, 158, 223, 154, 254, 226, 251 },
|
||||
new byte[] { 185, 128, 159, 224, 155, 255, 227, 251 },
|
||||
new byte[] { 186, 128, 159, 224, 155, 255, 227, 251 },
|
||||
new byte[] { 187, 129, 160, 225, 156, 255, 228, 251 },
|
||||
new byte[] { 188, 130, 160, 225, 156, 255, 228, 251 },
|
||||
new byte[] { 189, 131, 160, 226, 157, 255, 228, 251 },
|
||||
new byte[] { 190, 131, 160, 226, 158, 255, 228, 251 },
|
||||
new byte[] { 191, 132, 161, 227, 159, 255, 229, 251 },
|
||||
new byte[] { 192, 132, 161, 227, 159, 255, 229, 251 },
|
||||
new byte[] { 193, 133, 162, 228, 160, 255, 230, 252 },
|
||||
new byte[] { 194, 133, 162, 229, 160, 255, 230, 252 },
|
||||
new byte[] { 195, 134, 163, 230, 161, 255, 231, 252 },
|
||||
new byte[] { 196, 134, 163, 230, 161, 255, 231, 252 },
|
||||
new byte[] { 197, 135, 163, 231, 162, 255, 231, 252 },
|
||||
new byte[] { 198, 135, 163, 231, 162, 255, 231, 252 },
|
||||
new byte[] { 199, 136, 164, 232, 163, 255, 232, 252 },
|
||||
new byte[] { 200, 136, 164, 232, 164, 255, 232, 252 },
|
||||
new byte[] { 201, 137, 165, 233, 165, 255, 233, 252 },
|
||||
new byte[] { 201, 137, 165, 233, 165, 255, 233, 252 },
|
||||
new byte[] { 202, 138, 166, 233, 166, 255, 233, 252 },
|
||||
new byte[] { 203, 138, 166, 233, 166, 255, 233, 252 },
|
||||
new byte[] { 204, 139, 166, 234, 167, 255, 234, 252 },
|
||||
new byte[] { 205, 139, 166, 234, 167, 255, 234, 252 },
|
||||
new byte[] { 206, 140, 167, 235, 168, 255, 235, 252 },
|
||||
new byte[] { 206, 140, 167, 235, 168, 255, 235, 252 },
|
||||
new byte[] { 207, 141, 168, 236, 169, 255, 235, 252 },
|
||||
new byte[] { 208, 141, 168, 236, 170, 255, 235, 252 },
|
||||
new byte[] { 209, 142, 169, 237, 171, 255, 236, 252 },
|
||||
new byte[] { 209, 143, 169, 237, 171, 255, 236, 252 },
|
||||
new byte[] { 210, 144, 169, 237, 172, 255, 236, 252 },
|
||||
new byte[] { 211, 144, 169, 237, 172, 255, 236, 252 },
|
||||
new byte[] { 212, 145, 170, 238, 173, 255, 237, 252 },
|
||||
new byte[] { 213, 145, 170, 238, 173, 255, 237, 252 },
|
||||
new byte[] { 214, 146, 171, 239, 174, 255, 237, 253 },
|
||||
new byte[] { 214, 146, 171, 239, 174, 255, 237, 253 },
|
||||
new byte[] { 215, 147, 172, 240, 175, 255, 238, 253 },
|
||||
new byte[] { 215, 147, 172, 240, 175, 255, 238, 253 },
|
||||
new byte[] { 216, 148, 173, 240, 176, 255, 238, 253 },
|
||||
new byte[] { 217, 148, 173, 240, 176, 255, 238, 253 },
|
||||
new byte[] { 218, 149, 173, 241, 177, 255, 239, 253 },
|
||||
new byte[] { 218, 149, 173, 241, 178, 255, 239, 253 },
|
||||
new byte[] { 219, 150, 174, 241, 179, 255, 239, 253 },
|
||||
new byte[] { 219, 151, 174, 241, 179, 255, 239, 253 },
|
||||
new byte[] { 220, 152, 175, 242, 180, 255, 240, 253 },
|
||||
new byte[] { 221, 152, 175, 242, 180, 255, 240, 253 },
|
||||
new byte[] { 222, 153, 176, 242, 181, 255, 240, 253 },
|
||||
new byte[] { 222, 153, 176, 242, 181, 255, 240, 253 },
|
||||
new byte[] { 223, 154, 177, 243, 182, 255, 240, 253 },
|
||||
new byte[] { 223, 154, 177, 243, 182, 255, 240, 253 },
|
||||
new byte[] { 224, 155, 178, 244, 183, 255, 241, 253 },
|
||||
new byte[] { 224, 155, 178, 244, 183, 255, 241, 253 },
|
||||
new byte[] { 225, 156, 178, 244, 184, 255, 241, 253 },
|
||||
new byte[] { 225, 157, 178, 244, 184, 255, 241, 253 },
|
||||
new byte[] { 226, 158, 179, 244, 185, 255, 242, 253 },
|
||||
new byte[] { 227, 158, 179, 244, 185, 255, 242, 253 },
|
||||
new byte[] { 228, 159, 180, 245, 186, 255, 242, 253 },
|
||||
new byte[] { 228, 159, 180, 245, 186, 255, 242, 253 },
|
||||
new byte[] { 229, 160, 181, 245, 187, 255, 242, 253 },
|
||||
new byte[] { 229, 160, 181, 245, 187, 255, 242, 253 },
|
||||
new byte[] { 230, 161, 182, 246, 188, 255, 243, 253 },
|
||||
new byte[] { 230, 162, 182, 246, 188, 255, 243, 253 },
|
||||
new byte[] { 231, 163, 183, 246, 189, 255, 243, 253 },
|
||||
new byte[] { 231, 163, 183, 246, 189, 255, 243, 253 },
|
||||
new byte[] { 232, 164, 184, 247, 190, 255, 243, 253 },
|
||||
new byte[] { 232, 164, 184, 247, 190, 255, 243, 253 },
|
||||
new byte[] { 233, 165, 185, 247, 191, 255, 244, 253 },
|
||||
new byte[] { 233, 165, 185, 247, 191, 255, 244, 253 },
|
||||
new byte[] { 234, 166, 185, 247, 192, 255, 244, 253 },
|
||||
new byte[] { 234, 167, 185, 247, 192, 255, 244, 253 },
|
||||
new byte[] { 235, 168, 186, 248, 193, 255, 244, 253 },
|
||||
new byte[] { 235, 168, 186, 248, 193, 255, 244, 253 },
|
||||
new byte[] { 236, 169, 187, 248, 194, 255, 244, 253 },
|
||||
new byte[] { 236, 169, 187, 248, 194, 255, 244, 253 },
|
||||
new byte[] { 236, 170, 188, 248, 195, 255, 245, 253 },
|
||||
new byte[] { 236, 170, 188, 248, 195, 255, 245, 253 },
|
||||
new byte[] { 237, 171, 189, 249, 196, 255, 245, 254 },
|
||||
new byte[] { 237, 172, 189, 249, 196, 255, 245, 254 },
|
||||
new byte[] { 238, 173, 190, 249, 197, 255, 245, 254 },
|
||||
new byte[] { 238, 173, 190, 249, 197, 255, 245, 254 },
|
||||
new byte[] { 239, 174, 191, 249, 198, 255, 245, 254 },
|
||||
new byte[] { 239, 174, 191, 249, 198, 255, 245, 254 },
|
||||
new byte[] { 240, 175, 192, 249, 199, 255, 246, 254 },
|
||||
new byte[] { 240, 176, 192, 249, 199, 255, 246, 254 },
|
||||
new byte[] { 240, 177, 193, 250, 200, 255, 246, 254 },
|
||||
new byte[] { 240, 177, 193, 250, 200, 255, 246, 254 },
|
||||
new byte[] { 241, 178, 194, 250, 201, 255, 246, 254 },
|
||||
new byte[] { 241, 178, 194, 250, 201, 255, 246, 254 },
|
||||
new byte[] { 242, 179, 195, 250, 202, 255, 246, 254 },
|
||||
new byte[] { 242, 180, 195, 250, 202, 255, 246, 254 },
|
||||
new byte[] { 242, 181, 196, 250, 203, 255, 247, 254 },
|
||||
new byte[] { 242, 181, 196, 250, 203, 255, 247, 254 },
|
||||
new byte[] { 243, 182, 197, 251, 204, 255, 247, 254 },
|
||||
new byte[] { 243, 183, 197, 251, 204, 255, 247, 254 },
|
||||
new byte[] { 244, 184, 198, 251, 205, 255, 247, 254 },
|
||||
new byte[] { 244, 184, 198, 251, 205, 255, 247, 254 },
|
||||
new byte[] { 244, 185, 199, 251, 206, 255, 247, 254 },
|
||||
new byte[] { 244, 185, 199, 251, 206, 255, 247, 254 },
|
||||
new byte[] { 245, 186, 200, 251, 207, 255, 247, 254 },
|
||||
new byte[] { 245, 187, 200, 251, 207, 255, 247, 254 },
|
||||
new byte[] { 246, 188, 201, 252, 207, 255, 248, 254 },
|
||||
new byte[] { 246, 188, 201, 252, 207, 255, 248, 254 },
|
||||
new byte[] { 246, 189, 202, 252, 208, 255, 248, 254 },
|
||||
new byte[] { 246, 190, 202, 252, 208, 255, 248, 254 },
|
||||
new byte[] { 247, 191, 203, 252, 209, 255, 248, 254 },
|
||||
new byte[] { 247, 191, 203, 252, 209, 255, 248, 254 },
|
||||
new byte[] { 247, 192, 204, 252, 210, 255, 248, 254 },
|
||||
new byte[] { 247, 193, 204, 252, 210, 255, 248, 254 },
|
||||
new byte[] { 248, 194, 205, 252, 211, 255, 248, 254 },
|
||||
new byte[] { 248, 194, 205, 252, 211, 255, 248, 254 },
|
||||
new byte[] { 248, 195, 206, 252, 212, 255, 249, 254 },
|
||||
new byte[] { 248, 196, 206, 252, 212, 255, 249, 254 },
|
||||
new byte[] { 249, 197, 207, 253, 213, 255, 249, 254 },
|
||||
new byte[] { 249, 197, 207, 253, 213, 255, 249, 254 },
|
||||
new byte[] { 249, 198, 208, 253, 214, 255, 249, 254 },
|
||||
new byte[] { 249, 199, 209, 253, 214, 255, 249, 254 },
|
||||
new byte[] { 250, 200, 210, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 200, 210, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 201, 211, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 202, 211, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 203, 212, 253, 216, 255, 249, 254 },
|
||||
new byte[] { 250, 203, 212, 253, 216, 255, 249, 254 },
|
||||
new byte[] { 251, 204, 213, 253, 217, 255, 250, 254 },
|
||||
new byte[] { 251, 205, 213, 253, 217, 255, 250, 254 },
|
||||
new byte[] { 251, 206, 214, 254, 218, 255, 250, 254 },
|
||||
new byte[] { 251, 206, 215, 254, 218, 255, 250, 254 },
|
||||
new byte[] { 252, 207, 216, 254, 219, 255, 250, 254 },
|
||||
new byte[] { 252, 208, 216, 254, 219, 255, 250, 254 },
|
||||
new byte[] { 252, 209, 217, 254, 220, 255, 250, 254 },
|
||||
new byte[] { 252, 210, 217, 254, 220, 255, 250, 254 },
|
||||
new byte[] { 252, 211, 218, 254, 221, 255, 250, 254 },
|
||||
new byte[] { 252, 212, 218, 254, 221, 255, 250, 254 },
|
||||
new byte[] { 253, 213, 219, 254, 222, 255, 250, 254 },
|
||||
new byte[] { 253, 213, 220, 254, 222, 255, 250, 254 },
|
||||
new byte[] { 253, 214, 221, 254, 223, 255, 250, 254 },
|
||||
new byte[] { 253, 215, 221, 254, 223, 255, 250, 254 },
|
||||
new byte[] { 253, 216, 222, 254, 224, 255, 251, 254 },
|
||||
new byte[] { 253, 217, 223, 254, 224, 255, 251, 254 },
|
||||
new byte[] { 253, 218, 224, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 253, 219, 224, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 254, 220, 225, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 254, 221, 226, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 254, 222, 227, 255, 226, 255, 251, 254 },
|
||||
new byte[] { 254, 223, 227, 255, 226, 255, 251, 254 },
|
||||
new byte[] { 254, 224, 228, 255, 227, 255, 251, 254 },
|
||||
new byte[] { 254, 225, 229, 255, 227, 255, 251, 254 },
|
||||
new byte[] { 254, 226, 230, 255, 228, 255, 251, 254 },
|
||||
new byte[] { 254, 227, 230, 255, 229, 255, 251, 254 },
|
||||
new byte[] { 255, 228, 231, 255, 230, 255, 251, 254 },
|
||||
new byte[] { 255, 229, 232, 255, 230, 255, 251, 254 },
|
||||
new byte[] { 255, 230, 233, 255, 231, 255, 252, 254 },
|
||||
new byte[] { 255, 231, 234, 255, 231, 255, 252, 254 },
|
||||
new byte[] { 255, 232, 235, 255, 232, 255, 252, 254 },
|
||||
new byte[] { 255, 233, 236, 255, 232, 255, 252, 254 },
|
||||
new byte[] { 255, 235, 237, 255, 233, 255, 252, 254 },
|
||||
new byte[] { 255, 236, 238, 255, 234, 255, 252, 254 },
|
||||
new byte[] { 255, 238, 240, 255, 235, 255, 252, 255 },
|
||||
new byte[] { 255, 239, 241, 255, 235, 255, 252, 254 },
|
||||
new byte[] { 255, 241, 243, 255, 236, 255, 252, 254 },
|
||||
new byte[] { 255, 243, 245, 255, 237, 255, 252, 254 },
|
||||
new byte[] { 255, 246, 247, 255, 239, 255, 253, 255 }
|
||||
};
|
||||
[
|
||||
[3, 86, 128, 6, 86, 23, 88, 29], [6, 86, 128, 11, 87, 42, 91, 52],
|
||||
[9, 86, 129, 17, 88, 61, 94, 76], [12, 86, 129, 22, 88, 77, 97, 93],
|
||||
[15, 87, 129, 28, 89, 93, 100, 110], [17, 87, 129, 33, 90, 105, 103, 123],
|
||||
[20, 88, 130, 38, 91, 118, 106, 136], [23, 88, 130, 43, 91, 128, 108, 146],
|
||||
[26, 89, 131, 48, 92, 139, 111, 156], [28, 89, 131, 53, 93, 147, 114, 163],
|
||||
[31, 90, 131, 58, 94, 156, 117, 171], [34, 90, 131, 62, 94, 163, 119, 177],
|
||||
[37, 90, 132, 66, 95, 171, 122, 184], [39, 90, 132, 70, 96, 177, 124, 189],
|
||||
[42, 91, 132, 75, 97, 183, 127, 194], [44, 91, 132, 79, 97, 188, 129, 198],
|
||||
[47, 92, 133, 83, 98, 193, 132, 202], [49, 92, 133, 86, 99, 197, 134, 205],
|
||||
[52, 93, 133, 90, 100, 201, 137, 208], [54, 93, 133, 94, 100, 204, 139, 211],
|
||||
[57, 94, 134, 98, 101, 208, 142, 214], [59, 94, 134, 101, 102, 211, 144, 216],
|
||||
[62, 94, 135, 105, 103, 214, 146, 218],
|
||||
[64, 94, 135, 108, 103, 216, 148, 220],
|
||||
[66, 95, 135, 111, 104, 219, 151, 222],
|
||||
[68, 95, 135, 114, 105, 221, 153, 223],
|
||||
[71, 96, 136, 117, 106, 224, 155, 225],
|
||||
[73, 96, 136, 120, 106, 225, 157, 226],
|
||||
[76, 97, 136, 123, 107, 227, 159, 228],
|
||||
[78, 97, 136, 126, 108, 229, 160, 229],
|
||||
[80, 98, 137, 129, 109, 231, 162, 231],
|
||||
[82, 98, 137, 131, 109, 232, 164, 232],
|
||||
[84, 98, 138, 134, 110, 234, 166, 233],
|
||||
[86, 98, 138, 137, 111, 235, 168, 234],
|
||||
[89, 99, 138, 140, 112, 236, 170, 235],
|
||||
[91, 99, 138, 142, 112, 237, 171, 235],
|
||||
[93, 100, 139, 145, 113, 238, 173, 236],
|
||||
[95, 100, 139, 147, 114, 239, 174, 237],
|
||||
[97, 101, 140, 149, 115, 240, 176, 238],
|
||||
[99, 101, 140, 151, 115, 241, 177, 238],
|
||||
[101, 102, 140, 154, 116, 242, 179, 239],
|
||||
[103, 102, 140, 156, 117, 242, 180, 239],
|
||||
[105, 103, 141, 158, 118, 243, 182, 240],
|
||||
[107, 103, 141, 160, 118, 243, 183, 240],
|
||||
[109, 104, 141, 162, 119, 244, 185, 241],
|
||||
[111, 104, 141, 164, 119, 244, 186, 241],
|
||||
[113, 104, 142, 166, 120, 245, 187, 242],
|
||||
[114, 104, 142, 168, 121, 245, 188, 242],
|
||||
[116, 105, 143, 170, 122, 246, 190, 243],
|
||||
[118, 105, 143, 171, 122, 246, 191, 243],
|
||||
[120, 106, 143, 173, 123, 247, 192, 244],
|
||||
[121, 106, 143, 175, 124, 247, 193, 244],
|
||||
[123, 107, 144, 177, 125, 248, 195, 244],
|
||||
[125, 107, 144, 178, 125, 248, 196, 244],
|
||||
[127, 108, 145, 180, 126, 249, 197, 245],
|
||||
[128, 108, 145, 181, 127, 249, 198, 245],
|
||||
[130, 109, 145, 183, 128, 249, 199, 245],
|
||||
[132, 109, 145, 184, 128, 249, 200, 245],
|
||||
[134, 110, 146, 186, 129, 250, 201, 246],
|
||||
[135, 110, 146, 187, 130, 250, 202, 246],
|
||||
[137, 111, 147, 189, 131, 251, 203, 246],
|
||||
[138, 111, 147, 190, 131, 251, 204, 246],
|
||||
[140, 112, 147, 192, 132, 251, 205, 247],
|
||||
[141, 112, 147, 193, 132, 251, 206, 247],
|
||||
[143, 113, 148, 194, 133, 251, 207, 247],
|
||||
[144, 113, 148, 195, 134, 251, 207, 247],
|
||||
[146, 114, 149, 197, 135, 252, 208, 248],
|
||||
[147, 114, 149, 198, 135, 252, 209, 248],
|
||||
[149, 115, 149, 199, 136, 252, 210, 248],
|
||||
[150, 115, 149, 200, 137, 252, 210, 248],
|
||||
[152, 115, 150, 201, 138, 252, 211, 248],
|
||||
[153, 115, 150, 202, 138, 252, 212, 248],
|
||||
[155, 116, 151, 204, 139, 253, 213, 249],
|
||||
[156, 116, 151, 205, 139, 253, 213, 249],
|
||||
[158, 117, 151, 206, 140, 253, 214, 249],
|
||||
[159, 117, 151, 207, 141, 253, 215, 249],
|
||||
[161, 118, 152, 208, 142, 253, 216, 249],
|
||||
[162, 118, 152, 209, 142, 253, 216, 249],
|
||||
[163, 119, 153, 210, 143, 253, 217, 249],
|
||||
[164, 119, 153, 211, 143, 253, 217, 249],
|
||||
[166, 120, 153, 212, 144, 254, 218, 250],
|
||||
[167, 120, 153, 212, 145, 254, 219, 250],
|
||||
[168, 121, 154, 213, 146, 254, 220, 250],
|
||||
[169, 121, 154, 214, 146, 254, 220, 250],
|
||||
[171, 122, 155, 215, 147, 254, 221, 250],
|
||||
[172, 122, 155, 216, 147, 254, 221, 250],
|
||||
[173, 123, 155, 217, 148, 254, 222, 250],
|
||||
[174, 123, 155, 217, 149, 254, 222, 250],
|
||||
[176, 124, 156, 218, 150, 254, 223, 250],
|
||||
[177, 124, 156, 219, 150, 254, 223, 250],
|
||||
[178, 125, 157, 220, 151, 254, 224, 251],
|
||||
[179, 125, 157, 220, 151, 254, 224, 251],
|
||||
[180, 126, 157, 221, 152, 254, 225, 251],
|
||||
[181, 126, 157, 221, 152, 254, 225, 251],
|
||||
[183, 127, 158, 222, 153, 254, 226, 251],
|
||||
[184, 127, 158, 223, 154, 254, 226, 251],
|
||||
[185, 128, 159, 224, 155, 255, 227, 251],
|
||||
[186, 128, 159, 224, 155, 255, 227, 251],
|
||||
[187, 129, 160, 225, 156, 255, 228, 251],
|
||||
[188, 130, 160, 225, 156, 255, 228, 251],
|
||||
[189, 131, 160, 226, 157, 255, 228, 251],
|
||||
[190, 131, 160, 226, 158, 255, 228, 251],
|
||||
[191, 132, 161, 227, 159, 255, 229, 251],
|
||||
[192, 132, 161, 227, 159, 255, 229, 251],
|
||||
[193, 133, 162, 228, 160, 255, 230, 252],
|
||||
[194, 133, 162, 229, 160, 255, 230, 252],
|
||||
[195, 134, 163, 230, 161, 255, 231, 252],
|
||||
[196, 134, 163, 230, 161, 255, 231, 252],
|
||||
[197, 135, 163, 231, 162, 255, 231, 252],
|
||||
[198, 135, 163, 231, 162, 255, 231, 252],
|
||||
[199, 136, 164, 232, 163, 255, 232, 252],
|
||||
[200, 136, 164, 232, 164, 255, 232, 252],
|
||||
[201, 137, 165, 233, 165, 255, 233, 252],
|
||||
[201, 137, 165, 233, 165, 255, 233, 252],
|
||||
[202, 138, 166, 233, 166, 255, 233, 252],
|
||||
[203, 138, 166, 233, 166, 255, 233, 252],
|
||||
[204, 139, 166, 234, 167, 255, 234, 252],
|
||||
[205, 139, 166, 234, 167, 255, 234, 252],
|
||||
[206, 140, 167, 235, 168, 255, 235, 252],
|
||||
[206, 140, 167, 235, 168, 255, 235, 252],
|
||||
[207, 141, 168, 236, 169, 255, 235, 252],
|
||||
[208, 141, 168, 236, 170, 255, 235, 252],
|
||||
[209, 142, 169, 237, 171, 255, 236, 252],
|
||||
[209, 143, 169, 237, 171, 255, 236, 252],
|
||||
[210, 144, 169, 237, 172, 255, 236, 252],
|
||||
[211, 144, 169, 237, 172, 255, 236, 252],
|
||||
[212, 145, 170, 238, 173, 255, 237, 252],
|
||||
[213, 145, 170, 238, 173, 255, 237, 252],
|
||||
[214, 146, 171, 239, 174, 255, 237, 253],
|
||||
[214, 146, 171, 239, 174, 255, 237, 253],
|
||||
[215, 147, 172, 240, 175, 255, 238, 253],
|
||||
[215, 147, 172, 240, 175, 255, 238, 253],
|
||||
[216, 148, 173, 240, 176, 255, 238, 253],
|
||||
[217, 148, 173, 240, 176, 255, 238, 253],
|
||||
[218, 149, 173, 241, 177, 255, 239, 253],
|
||||
[218, 149, 173, 241, 178, 255, 239, 253],
|
||||
[219, 150, 174, 241, 179, 255, 239, 253],
|
||||
[219, 151, 174, 241, 179, 255, 239, 253],
|
||||
[220, 152, 175, 242, 180, 255, 240, 253],
|
||||
[221, 152, 175, 242, 180, 255, 240, 253],
|
||||
[222, 153, 176, 242, 181, 255, 240, 253],
|
||||
[222, 153, 176, 242, 181, 255, 240, 253],
|
||||
[223, 154, 177, 243, 182, 255, 240, 253],
|
||||
[223, 154, 177, 243, 182, 255, 240, 253],
|
||||
[224, 155, 178, 244, 183, 255, 241, 253],
|
||||
[224, 155, 178, 244, 183, 255, 241, 253],
|
||||
[225, 156, 178, 244, 184, 255, 241, 253],
|
||||
[225, 157, 178, 244, 184, 255, 241, 253],
|
||||
[226, 158, 179, 244, 185, 255, 242, 253],
|
||||
[227, 158, 179, 244, 185, 255, 242, 253],
|
||||
[228, 159, 180, 245, 186, 255, 242, 253],
|
||||
[228, 159, 180, 245, 186, 255, 242, 253],
|
||||
[229, 160, 181, 245, 187, 255, 242, 253],
|
||||
[229, 160, 181, 245, 187, 255, 242, 253],
|
||||
[230, 161, 182, 246, 188, 255, 243, 253],
|
||||
[230, 162, 182, 246, 188, 255, 243, 253],
|
||||
[231, 163, 183, 246, 189, 255, 243, 253],
|
||||
[231, 163, 183, 246, 189, 255, 243, 253],
|
||||
[232, 164, 184, 247, 190, 255, 243, 253],
|
||||
[232, 164, 184, 247, 190, 255, 243, 253],
|
||||
[233, 165, 185, 247, 191, 255, 244, 253],
|
||||
[233, 165, 185, 247, 191, 255, 244, 253],
|
||||
[234, 166, 185, 247, 192, 255, 244, 253],
|
||||
[234, 167, 185, 247, 192, 255, 244, 253],
|
||||
[235, 168, 186, 248, 193, 255, 244, 253],
|
||||
[235, 168, 186, 248, 193, 255, 244, 253],
|
||||
[236, 169, 187, 248, 194, 255, 244, 253],
|
||||
[236, 169, 187, 248, 194, 255, 244, 253],
|
||||
[236, 170, 188, 248, 195, 255, 245, 253],
|
||||
[236, 170, 188, 248, 195, 255, 245, 253],
|
||||
[237, 171, 189, 249, 196, 255, 245, 254],
|
||||
[237, 172, 189, 249, 196, 255, 245, 254],
|
||||
[238, 173, 190, 249, 197, 255, 245, 254],
|
||||
[238, 173, 190, 249, 197, 255, 245, 254],
|
||||
[239, 174, 191, 249, 198, 255, 245, 254],
|
||||
[239, 174, 191, 249, 198, 255, 245, 254],
|
||||
[240, 175, 192, 249, 199, 255, 246, 254],
|
||||
[240, 176, 192, 249, 199, 255, 246, 254],
|
||||
[240, 177, 193, 250, 200, 255, 246, 254],
|
||||
[240, 177, 193, 250, 200, 255, 246, 254],
|
||||
[241, 178, 194, 250, 201, 255, 246, 254],
|
||||
[241, 178, 194, 250, 201, 255, 246, 254],
|
||||
[242, 179, 195, 250, 202, 255, 246, 254],
|
||||
[242, 180, 195, 250, 202, 255, 246, 254],
|
||||
[242, 181, 196, 250, 203, 255, 247, 254],
|
||||
[242, 181, 196, 250, 203, 255, 247, 254],
|
||||
[243, 182, 197, 251, 204, 255, 247, 254],
|
||||
[243, 183, 197, 251, 204, 255, 247, 254],
|
||||
[244, 184, 198, 251, 205, 255, 247, 254],
|
||||
[244, 184, 198, 251, 205, 255, 247, 254],
|
||||
[244, 185, 199, 251, 206, 255, 247, 254],
|
||||
[244, 185, 199, 251, 206, 255, 247, 254],
|
||||
[245, 186, 200, 251, 207, 255, 247, 254],
|
||||
[245, 187, 200, 251, 207, 255, 247, 254],
|
||||
[246, 188, 201, 252, 207, 255, 248, 254],
|
||||
[246, 188, 201, 252, 207, 255, 248, 254],
|
||||
[246, 189, 202, 252, 208, 255, 248, 254],
|
||||
[246, 190, 202, 252, 208, 255, 248, 254],
|
||||
[247, 191, 203, 252, 209, 255, 248, 254],
|
||||
[247, 191, 203, 252, 209, 255, 248, 254],
|
||||
[247, 192, 204, 252, 210, 255, 248, 254],
|
||||
[247, 193, 204, 252, 210, 255, 248, 254],
|
||||
[248, 194, 205, 252, 211, 255, 248, 254],
|
||||
[248, 194, 205, 252, 211, 255, 248, 254],
|
||||
[248, 195, 206, 252, 212, 255, 249, 254],
|
||||
[248, 196, 206, 252, 212, 255, 249, 254],
|
||||
[249, 197, 207, 253, 213, 255, 249, 254],
|
||||
[249, 197, 207, 253, 213, 255, 249, 254],
|
||||
[249, 198, 208, 253, 214, 255, 249, 254],
|
||||
[249, 199, 209, 253, 214, 255, 249, 254],
|
||||
[250, 200, 210, 253, 215, 255, 249, 254],
|
||||
[250, 200, 210, 253, 215, 255, 249, 254],
|
||||
[250, 201, 211, 253, 215, 255, 249, 254],
|
||||
[250, 202, 211, 253, 215, 255, 249, 254],
|
||||
[250, 203, 212, 253, 216, 255, 249, 254],
|
||||
[250, 203, 212, 253, 216, 255, 249, 254],
|
||||
[251, 204, 213, 253, 217, 255, 250, 254],
|
||||
[251, 205, 213, 253, 217, 255, 250, 254],
|
||||
[251, 206, 214, 254, 218, 255, 250, 254],
|
||||
[251, 206, 215, 254, 218, 255, 250, 254],
|
||||
[252, 207, 216, 254, 219, 255, 250, 254],
|
||||
[252, 208, 216, 254, 219, 255, 250, 254],
|
||||
[252, 209, 217, 254, 220, 255, 250, 254],
|
||||
[252, 210, 217, 254, 220, 255, 250, 254],
|
||||
[252, 211, 218, 254, 221, 255, 250, 254],
|
||||
[252, 212, 218, 254, 221, 255, 250, 254],
|
||||
[253, 213, 219, 254, 222, 255, 250, 254],
|
||||
[253, 213, 220, 254, 222, 255, 250, 254],
|
||||
[253, 214, 221, 254, 223, 255, 250, 254],
|
||||
[253, 215, 221, 254, 223, 255, 250, 254],
|
||||
[253, 216, 222, 254, 224, 255, 251, 254],
|
||||
[253, 217, 223, 254, 224, 255, 251, 254],
|
||||
[253, 218, 224, 254, 225, 255, 251, 254],
|
||||
[253, 219, 224, 254, 225, 255, 251, 254],
|
||||
[254, 220, 225, 254, 225, 255, 251, 254],
|
||||
[254, 221, 226, 254, 225, 255, 251, 254],
|
||||
[254, 222, 227, 255, 226, 255, 251, 254],
|
||||
[254, 223, 227, 255, 226, 255, 251, 254],
|
||||
[254, 224, 228, 255, 227, 255, 251, 254],
|
||||
[254, 225, 229, 255, 227, 255, 251, 254],
|
||||
[254, 226, 230, 255, 228, 255, 251, 254],
|
||||
[254, 227, 230, 255, 229, 255, 251, 254],
|
||||
[255, 228, 231, 255, 230, 255, 251, 254],
|
||||
[255, 229, 232, 255, 230, 255, 251, 254],
|
||||
[255, 230, 233, 255, 231, 255, 252, 254],
|
||||
[255, 231, 234, 255, 231, 255, 252, 254],
|
||||
[255, 232, 235, 255, 232, 255, 252, 254],
|
||||
[255, 233, 236, 255, 232, 255, 252, 254],
|
||||
[255, 235, 237, 255, 233, 255, 252, 254],
|
||||
[255, 236, 238, 255, 234, 255, 252, 254],
|
||||
[255, 238, 240, 255, 235, 255, 252, 255],
|
||||
[255, 239, 241, 255, 235, 255, 252, 254],
|
||||
[255, 241, 243, 255, 236, 255, 252, 254],
|
||||
[255, 243, 245, 255, 237, 255, 252, 254],
|
||||
[255, 246, 247, 255, 239, 255, 253, 255]
|
||||
];
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs4x4 =
|
||||
{
|
||||
internal static readonly byte[] DefaultCoefProbs4X4 =
|
||||
[
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
@@ -422,10 +422,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
127, 145, 243, 71, 129, 228, 17, 93, 177, 3, 61, 124, 1, 41, 84, 1, 21, 52,
|
||||
// Band 5
|
||||
157, 78, 244, 140, 72, 231, 69, 58, 184, 31, 44, 137, 14, 38, 105, 8, 23, 61
|
||||
};
|
||||
];
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs8x8 =
|
||||
{
|
||||
internal static readonly byte[] DefaultCoefProbs8X8 =
|
||||
[
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
@@ -480,10 +480,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
62, 190, 238, 21, 159, 222, 2, 107, 172, 1, 72, 122, 1, 40, 71, 1, 18, 32,
|
||||
// Band 5
|
||||
61, 199, 240, 27, 161, 226, 4, 113, 180, 1, 76, 129, 1, 46, 80, 1, 23, 41
|
||||
};
|
||||
];
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs16x16 =
|
||||
{
|
||||
internal static readonly byte[] DefaultCoefProbs16X16 =
|
||||
[
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
@@ -538,10 +538,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
40, 194, 227, 8, 147, 204, 1, 94, 155, 1, 65, 112, 1, 39, 66, 1, 14, 26,
|
||||
// Band 5
|
||||
16, 208, 228, 3, 151, 207, 1, 98, 160, 1, 67, 117, 1, 41, 74, 1, 17, 31
|
||||
};
|
||||
];
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs32x32 =
|
||||
{
|
||||
internal static readonly byte[] DefaultCoefProbs32X32 =
|
||||
[
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
@@ -596,11 +596,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
84, 220, 246, 31, 177, 231, 2, 115, 180, 1, 79, 134, 1, 55, 77, 1, 60, 79,
|
||||
// Band 5
|
||||
43, 243, 240, 8, 180, 217, 1, 115, 166, 1, 84, 121, 1, 51, 67, 1, 16, 6
|
||||
};
|
||||
];
|
||||
|
||||
public static byte[] GetBandTranslate(int txSize)
|
||||
{
|
||||
return txSize == (int)TxSize.Tx4x4 ? CoefbandTrans4x4 : CoefbandTrans8x8Plus;
|
||||
return txSize == (int)TxSize.Tx4X4 ? _coefbandTrans4X4 : _coefbandTrans8X8Plus;
|
||||
}
|
||||
|
||||
public static void CopyProbs<T>(ref T dest, ReadOnlySpan<byte> probs) where T : unmanaged
|
||||
|
||||
@@ -13,173 +13,163 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
public const int TxSizeContexts = 2;
|
||||
|
||||
public static readonly byte[][][] KfYModeProb =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
[
|
||||
[
|
||||
// above = dc
|
||||
new byte[] { 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc
|
||||
new byte[] { 92, 45, 102, 136, 116, 180, 74, 90, 100 }, // left = v
|
||||
new byte[] { 73, 32, 19, 187, 222, 215, 46, 34, 100 }, // left = h
|
||||
new byte[] { 91, 30, 32, 116, 121, 186, 93, 86, 94 }, // left = d45
|
||||
new byte[] { 72, 35, 36, 149, 68, 206, 68, 63, 105 }, // left = d135
|
||||
new byte[] { 73, 31, 28, 138, 57, 124, 55, 122, 151 }, // left = d117
|
||||
new byte[] { 67, 23, 21, 140, 126, 197, 40, 37, 171 }, // left = d153
|
||||
new byte[] { 86, 27, 28, 128, 154, 212, 45, 43, 53 }, // left = d207
|
||||
new byte[] { 74, 32, 27, 107, 86, 160, 63, 134, 102 }, // left = d63
|
||||
new byte[] { 59, 67, 44, 140, 161, 202, 78, 67, 119 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
[137, 30, 42, 148, 151, 207, 70, 52, 91], // left = dc
|
||||
[92, 45, 102, 136, 116, 180, 74, 90, 100], // left = v
|
||||
[73, 32, 19, 187, 222, 215, 46, 34, 100], // left = h
|
||||
[91, 30, 32, 116, 121, 186, 93, 86, 94], // left = d45
|
||||
[72, 35, 36, 149, 68, 206, 68, 63, 105], // left = d135
|
||||
[73, 31, 28, 138, 57, 124, 55, 122, 151], // left = d117
|
||||
[67, 23, 21, 140, 126, 197, 40, 37, 171], // left = d153
|
||||
[86, 27, 28, 128, 154, 212, 45, 43, 53], // left = d207
|
||||
[74, 32, 27, 107, 86, 160, 63, 134, 102], // left = d63
|
||||
[59, 67, 44, 140, 161, 202, 78, 67, 119] // left = tm
|
||||
],
|
||||
[
|
||||
// above = v
|
||||
new byte[] { 63, 36, 126, 146, 123, 158, 60, 90, 96 }, // left = dc
|
||||
new byte[] { 43, 46, 168, 134, 107, 128, 69, 142, 92 }, // left = v
|
||||
new byte[] { 44, 29, 68, 159, 201, 177, 50, 57, 77 }, // left = h
|
||||
new byte[] { 58, 38, 76, 114, 97, 172, 78, 133, 92 }, // left = d45
|
||||
new byte[] { 46, 41, 76, 140, 63, 184, 69, 112, 57 }, // left = d135
|
||||
new byte[] { 38, 32, 85, 140, 46, 112, 54, 151, 133 }, // left = d117
|
||||
new byte[] { 39, 27, 61, 131, 110, 175, 44, 75, 136 }, // left = d153
|
||||
new byte[] { 52, 30, 74, 113, 130, 175, 51, 64, 58 }, // left = d207
|
||||
new byte[] { 47, 35, 80, 100, 74, 143, 64, 163, 74 }, // left = d63
|
||||
new byte[] { 36, 61, 116, 114, 128, 162, 80, 125, 82 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
[63, 36, 126, 146, 123, 158, 60, 90, 96], // left = dc
|
||||
[43, 46, 168, 134, 107, 128, 69, 142, 92], // left = v
|
||||
[44, 29, 68, 159, 201, 177, 50, 57, 77], // left = h
|
||||
[58, 38, 76, 114, 97, 172, 78, 133, 92], // left = d45
|
||||
[46, 41, 76, 140, 63, 184, 69, 112, 57], // left = d135
|
||||
[38, 32, 85, 140, 46, 112, 54, 151, 133], // left = d117
|
||||
[39, 27, 61, 131, 110, 175, 44, 75, 136], // left = d153
|
||||
[52, 30, 74, 113, 130, 175, 51, 64, 58], // left = d207
|
||||
[47, 35, 80, 100, 74, 143, 64, 163, 74], // left = d63
|
||||
[36, 61, 116, 114, 128, 162, 80, 125, 82] // left = tm
|
||||
],
|
||||
[
|
||||
// above = h
|
||||
new byte[] { 82, 26, 26, 171, 208, 204, 44, 32, 105 }, // left = dc
|
||||
new byte[] { 55, 44, 68, 166, 179, 192, 57, 57, 108 }, // left = v
|
||||
new byte[] { 42, 26, 11, 199, 241, 228, 23, 15, 85 }, // left = h
|
||||
new byte[] { 68, 42, 19, 131, 160, 199, 55, 52, 83 }, // left = d45
|
||||
new byte[] { 58, 50, 25, 139, 115, 232, 39, 52, 118 }, // left = d135
|
||||
new byte[] { 50, 35, 33, 153, 104, 162, 64, 59, 131 }, // left = d117
|
||||
new byte[] { 44, 24, 16, 150, 177, 202, 33, 19, 156 }, // left = d153
|
||||
new byte[] { 55, 27, 12, 153, 203, 218, 26, 27, 49 }, // left = d207
|
||||
new byte[] { 53, 49, 21, 110, 116, 168, 59, 80, 76 }, // left = d63
|
||||
new byte[] { 38, 72, 19, 168, 203, 212, 50, 50, 107 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
[82, 26, 26, 171, 208, 204, 44, 32, 105], // left = dc
|
||||
[55, 44, 68, 166, 179, 192, 57, 57, 108], // left = v
|
||||
[42, 26, 11, 199, 241, 228, 23, 15, 85], // left = h
|
||||
[68, 42, 19, 131, 160, 199, 55, 52, 83], // left = d45
|
||||
[58, 50, 25, 139, 115, 232, 39, 52, 118], // left = d135
|
||||
[50, 35, 33, 153, 104, 162, 64, 59, 131], // left = d117
|
||||
[44, 24, 16, 150, 177, 202, 33, 19, 156], // left = d153
|
||||
[55, 27, 12, 153, 203, 218, 26, 27, 49], // left = d207
|
||||
[53, 49, 21, 110, 116, 168, 59, 80, 76], // left = d63
|
||||
[38, 72, 19, 168, 203, 212, 50, 50, 107] // left = tm
|
||||
],
|
||||
[
|
||||
// above = d45
|
||||
new byte[] { 103, 26, 36, 129, 132, 201, 83, 80, 93 }, // left = dc
|
||||
new byte[] { 59, 38, 83, 112, 103, 162, 98, 136, 90 }, // left = v
|
||||
new byte[] { 62, 30, 23, 158, 200, 207, 59, 57, 50 }, // left = h
|
||||
new byte[] { 67, 30, 29, 84, 86, 191, 102, 91, 59 }, // left = d45
|
||||
new byte[] { 60, 32, 33, 112, 71, 220, 64, 89, 104 }, // left = d135
|
||||
new byte[] { 53, 26, 34, 130, 56, 149, 84, 120, 103 }, // left = d117
|
||||
new byte[] { 53, 21, 23, 133, 109, 210, 56, 77, 172 }, // left = d153
|
||||
new byte[] { 77, 19, 29, 112, 142, 228, 55, 66, 36 }, // left = d207
|
||||
new byte[] { 61, 29, 29, 93, 97, 165, 83, 175, 162 }, // left = d63
|
||||
new byte[] { 47, 47, 43, 114, 137, 181, 100, 99, 95 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
[103, 26, 36, 129, 132, 201, 83, 80, 93], // left = dc
|
||||
[59, 38, 83, 112, 103, 162, 98, 136, 90], // left = v
|
||||
[62, 30, 23, 158, 200, 207, 59, 57, 50], // left = h
|
||||
[67, 30, 29, 84, 86, 191, 102, 91, 59], // left = d45
|
||||
[60, 32, 33, 112, 71, 220, 64, 89, 104], // left = d135
|
||||
[53, 26, 34, 130, 56, 149, 84, 120, 103], // left = d117
|
||||
[53, 21, 23, 133, 109, 210, 56, 77, 172], // left = d153
|
||||
[77, 19, 29, 112, 142, 228, 55, 66, 36], // left = d207
|
||||
[61, 29, 29, 93, 97, 165, 83, 175, 162], // left = d63
|
||||
[47, 47, 43, 114, 137, 181, 100, 99, 95] // left = tm
|
||||
],
|
||||
[
|
||||
// above = d135
|
||||
new byte[] { 69, 23, 29, 128, 83, 199, 46, 44, 101 }, // left = dc
|
||||
new byte[] { 53, 40, 55, 139, 69, 183, 61, 80, 110 }, // left = v
|
||||
new byte[] { 40, 29, 19, 161, 180, 207, 43, 24, 91 }, // left = h
|
||||
new byte[] { 60, 34, 19, 105, 61, 198, 53, 64, 89 }, // left = d45
|
||||
new byte[] { 52, 31, 22, 158, 40, 209, 58, 62, 89 }, // left = d135
|
||||
new byte[] { 44, 31, 29, 147, 46, 158, 56, 102, 198 }, // left = d117
|
||||
new byte[] { 35, 19, 12, 135, 87, 209, 41, 45, 167 }, // left = d153
|
||||
new byte[] { 55, 25, 21, 118, 95, 215, 38, 39, 66 }, // left = d207
|
||||
new byte[] { 51, 38, 25, 113, 58, 164, 70, 93, 97 }, // left = d63
|
||||
new byte[] { 47, 54, 34, 146, 108, 203, 72, 103, 151 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
[69, 23, 29, 128, 83, 199, 46, 44, 101], // left = dc
|
||||
[53, 40, 55, 139, 69, 183, 61, 80, 110], // left = v
|
||||
[40, 29, 19, 161, 180, 207, 43, 24, 91], // left = h
|
||||
[60, 34, 19, 105, 61, 198, 53, 64, 89], // left = d45
|
||||
[52, 31, 22, 158, 40, 209, 58, 62, 89], // left = d135
|
||||
[44, 31, 29, 147, 46, 158, 56, 102, 198], // left = d117
|
||||
[35, 19, 12, 135, 87, 209, 41, 45, 167], // left = d153
|
||||
[55, 25, 21, 118, 95, 215, 38, 39, 66], // left = d207
|
||||
[51, 38, 25, 113, 58, 164, 70, 93, 97], // left = d63
|
||||
[47, 54, 34, 146, 108, 203, 72, 103, 151] // left = tm
|
||||
],
|
||||
[
|
||||
// above = d117
|
||||
new byte[] { 64, 19, 37, 156, 66, 138, 49, 95, 133 }, // left = dc
|
||||
new byte[] { 46, 27, 80, 150, 55, 124, 55, 121, 135 }, // left = v
|
||||
new byte[] { 36, 23, 27, 165, 149, 166, 54, 64, 118 }, // left = h
|
||||
new byte[] { 53, 21, 36, 131, 63, 163, 60, 109, 81 }, // left = d45
|
||||
new byte[] { 40, 26, 35, 154, 40, 185, 51, 97, 123 }, // left = d135
|
||||
new byte[] { 35, 19, 34, 179, 19, 97, 48, 129, 124 }, // left = d117
|
||||
new byte[] { 36, 20, 26, 136, 62, 164, 33, 77, 154 }, // left = d153
|
||||
new byte[] { 45, 18, 32, 130, 90, 157, 40, 79, 91 }, // left = d207
|
||||
new byte[] { 45, 26, 28, 129, 45, 129, 49, 147, 123 }, // left = d63
|
||||
new byte[] { 38, 44, 51, 136, 74, 162, 57, 97, 121 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
[64, 19, 37, 156, 66, 138, 49, 95, 133], // left = dc
|
||||
[46, 27, 80, 150, 55, 124, 55, 121, 135], // left = v
|
||||
[36, 23, 27, 165, 149, 166, 54, 64, 118], // left = h
|
||||
[53, 21, 36, 131, 63, 163, 60, 109, 81], // left = d45
|
||||
[40, 26, 35, 154, 40, 185, 51, 97, 123], // left = d135
|
||||
[35, 19, 34, 179, 19, 97, 48, 129, 124], // left = d117
|
||||
[36, 20, 26, 136, 62, 164, 33, 77, 154], // left = d153
|
||||
[45, 18, 32, 130, 90, 157, 40, 79, 91], // left = d207
|
||||
[45, 26, 28, 129, 45, 129, 49, 147, 123], // left = d63
|
||||
[38, 44, 51, 136, 74, 162, 57, 97, 121] // left = tm
|
||||
],
|
||||
[
|
||||
// above = d153
|
||||
new byte[] { 75, 17, 22, 136, 138, 185, 32, 34, 166 }, // left = dc
|
||||
new byte[] { 56, 39, 58, 133, 117, 173, 48, 53, 187 }, // left = v
|
||||
new byte[] { 35, 21, 12, 161, 212, 207, 20, 23, 145 }, // left = h
|
||||
new byte[] { 56, 29, 19, 117, 109, 181, 55, 68, 112 }, // left = d45
|
||||
new byte[] { 47, 29, 17, 153, 64, 220, 59, 51, 114 }, // left = d135
|
||||
new byte[] { 46, 16, 24, 136, 76, 147, 41, 64, 172 }, // left = d117
|
||||
new byte[] { 34, 17, 11, 108, 152, 187, 13, 15, 209 }, // left = d153
|
||||
new byte[] { 51, 24, 14, 115, 133, 209, 32, 26, 104 }, // left = d207
|
||||
new byte[] { 55, 30, 18, 122, 79, 179, 44, 88, 116 }, // left = d63
|
||||
new byte[] { 37, 49, 25, 129, 168, 164, 41, 54, 148 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
[75, 17, 22, 136, 138, 185, 32, 34, 166], // left = dc
|
||||
[56, 39, 58, 133, 117, 173, 48, 53, 187], // left = v
|
||||
[35, 21, 12, 161, 212, 207, 20, 23, 145], // left = h
|
||||
[56, 29, 19, 117, 109, 181, 55, 68, 112], // left = d45
|
||||
[47, 29, 17, 153, 64, 220, 59, 51, 114], // left = d135
|
||||
[46, 16, 24, 136, 76, 147, 41, 64, 172], // left = d117
|
||||
[34, 17, 11, 108, 152, 187, 13, 15, 209], // left = d153
|
||||
[51, 24, 14, 115, 133, 209, 32, 26, 104], // left = d207
|
||||
[55, 30, 18, 122, 79, 179, 44, 88, 116], // left = d63
|
||||
[37, 49, 25, 129, 168, 164, 41, 54, 148] // left = tm
|
||||
],
|
||||
[
|
||||
// above = d207
|
||||
new byte[] { 82, 22, 32, 127, 143, 213, 39, 41, 70 }, // left = dc
|
||||
new byte[] { 62, 44, 61, 123, 105, 189, 48, 57, 64 }, // left = v
|
||||
new byte[] { 47, 25, 17, 175, 222, 220, 24, 30, 86 }, // left = h
|
||||
new byte[] { 68, 36, 17, 106, 102, 206, 59, 74, 74 }, // left = d45
|
||||
new byte[] { 57, 39, 23, 151, 68, 216, 55, 63, 58 }, // left = d135
|
||||
new byte[] { 49, 30, 35, 141, 70, 168, 82, 40, 115 }, // left = d117
|
||||
new byte[] { 51, 25, 15, 136, 129, 202, 38, 35, 139 }, // left = d153
|
||||
new byte[] { 68, 26, 16, 111, 141, 215, 29, 28, 28 }, // left = d207
|
||||
new byte[] { 59, 39, 19, 114, 75, 180, 77, 104, 42 }, // left = d63
|
||||
new byte[] { 40, 61, 26, 126, 152, 206, 61, 59, 93 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
[82, 22, 32, 127, 143, 213, 39, 41, 70], // left = dc
|
||||
[62, 44, 61, 123, 105, 189, 48, 57, 64], // left = v
|
||||
[47, 25, 17, 175, 222, 220, 24, 30, 86], // left = h
|
||||
[68, 36, 17, 106, 102, 206, 59, 74, 74], // left = d45
|
||||
[57, 39, 23, 151, 68, 216, 55, 63, 58], // left = d135
|
||||
[49, 30, 35, 141, 70, 168, 82, 40, 115], // left = d117
|
||||
[51, 25, 15, 136, 129, 202, 38, 35, 139], // left = d153
|
||||
[68, 26, 16, 111, 141, 215, 29, 28, 28], // left = d207
|
||||
[59, 39, 19, 114, 75, 180, 77, 104, 42], // left = d63
|
||||
[40, 61, 26, 126, 152, 206, 61, 59, 93] // left = tm
|
||||
],
|
||||
[
|
||||
// above = d63
|
||||
new byte[] { 78, 23, 39, 111, 117, 170, 74, 124, 94 }, // left = dc
|
||||
new byte[] { 48, 34, 86, 101, 92, 146, 78, 179, 134 }, // left = v
|
||||
new byte[] { 47, 22, 24, 138, 187, 178, 68, 69, 59 }, // left = h
|
||||
new byte[] { 56, 25, 33, 105, 112, 187, 95, 177, 129 }, // left = d45
|
||||
new byte[] { 48, 31, 27, 114, 63, 183, 82, 116, 56 }, // left = d135
|
||||
new byte[] { 43, 28, 37, 121, 63, 123, 61, 192, 169 }, // left = d117
|
||||
new byte[] { 42, 17, 24, 109, 97, 177, 56, 76, 122 }, // left = d153
|
||||
new byte[] { 58, 18, 28, 105, 139, 182, 70, 92, 63 }, // left = d207
|
||||
new byte[] { 46, 23, 32, 74, 86, 150, 67, 183, 88 }, // left = d63
|
||||
new byte[] { 36, 38, 48, 92, 122, 165, 88, 137, 91 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
[78, 23, 39, 111, 117, 170, 74, 124, 94], // left = dc
|
||||
[48, 34, 86, 101, 92, 146, 78, 179, 134], // left = v
|
||||
[47, 22, 24, 138, 187, 178, 68, 69, 59], // left = h
|
||||
[56, 25, 33, 105, 112, 187, 95, 177, 129], // left = d45
|
||||
[48, 31, 27, 114, 63, 183, 82, 116, 56], // left = d135
|
||||
[43, 28, 37, 121, 63, 123, 61, 192, 169], // left = d117
|
||||
[42, 17, 24, 109, 97, 177, 56, 76, 122], // left = d153
|
||||
[58, 18, 28, 105, 139, 182, 70, 92, 63], // left = d207
|
||||
[46, 23, 32, 74, 86, 150, 67, 183, 88], // left = d63
|
||||
[36, 38, 48, 92, 122, 165, 88, 137, 91] // left = tm
|
||||
],
|
||||
[
|
||||
// above = tm
|
||||
new byte[] { 65, 70, 60, 155, 159, 199, 61, 60, 81 }, // left = dc
|
||||
new byte[] { 44, 78, 115, 132, 119, 173, 71, 112, 93 }, // left = v
|
||||
new byte[] { 39, 38, 21, 184, 227, 206, 42, 32, 64 }, // left = h
|
||||
new byte[] { 58, 47, 36, 124, 137, 193, 80, 82, 78 }, // left = d45
|
||||
new byte[] { 49, 50, 35, 144, 95, 205, 63, 78, 59 }, // left = d135
|
||||
new byte[] { 41, 53, 52, 148, 71, 142, 65, 128, 51 }, // left = d117
|
||||
new byte[] { 40, 36, 28, 143, 143, 202, 40, 55, 137 }, // left = d153
|
||||
new byte[] { 52, 34, 29, 129, 183, 227, 42, 35, 43 }, // left = d207
|
||||
new byte[] { 42, 44, 44, 104, 105, 164, 64, 130, 80 }, // left = d63
|
||||
new byte[] { 43, 81, 53, 140, 169, 204, 68, 84, 72 } // left = tm
|
||||
}
|
||||
};
|
||||
[65, 70, 60, 155, 159, 199, 61, 60, 81], // left = dc
|
||||
[44, 78, 115, 132, 119, 173, 71, 112, 93], // left = v
|
||||
[39, 38, 21, 184, 227, 206, 42, 32, 64], // left = h
|
||||
[58, 47, 36, 124, 137, 193, 80, 82, 78], // left = d45
|
||||
[49, 50, 35, 144, 95, 205, 63, 78, 59], // left = d135
|
||||
[41, 53, 52, 148, 71, 142, 65, 128, 51], // left = d117
|
||||
[40, 36, 28, 143, 143, 202, 40, 55, 137], // left = d153
|
||||
[52, 34, 29, 129, 183, 227, 42, 35, 43], // left = d207
|
||||
[42, 44, 44, 104, 105, 164, 64, 130, 80], // left = d63
|
||||
[43, 81, 53, 140, 169, 204, 68, 84, 72] // left = tm
|
||||
]
|
||||
];
|
||||
|
||||
public static readonly byte[][] KfUvModeProb =
|
||||
{
|
||||
new byte[] { 144, 11, 54, 157, 195, 130, 46, 58, 108 }, // y = dc
|
||||
new byte[] { 118, 15, 123, 148, 131, 101, 44, 93, 131 }, // y = v
|
||||
new byte[] { 113, 12, 23, 188, 226, 142, 26, 32, 125 }, // y = h
|
||||
new byte[] { 120, 11, 50, 123, 163, 135, 64, 77, 103 }, // y = d45
|
||||
new byte[] { 113, 9, 36, 155, 111, 157, 32, 44, 161 }, // y = d135
|
||||
new byte[] { 116, 9, 55, 176, 76, 96, 37, 61, 149 }, // y = d117
|
||||
new byte[] { 115, 9, 28, 141, 161, 167, 21, 25, 193 }, // y = d153
|
||||
new byte[] { 120, 12, 32, 145, 195, 142, 32, 38, 86 }, // y = d207
|
||||
new byte[] { 116, 12, 64, 120, 140, 125, 49, 115, 121 }, // y = d63
|
||||
new byte[] { 102, 19, 66, 162, 182, 122, 35, 59, 128 } // y = tm
|
||||
};
|
||||
[
|
||||
[144, 11, 54, 157, 195, 130, 46, 58, 108], // y = dc
|
||||
[118, 15, 123, 148, 131, 101, 44, 93, 131], // y = v
|
||||
[113, 12, 23, 188, 226, 142, 26, 32, 125], // y = h
|
||||
[120, 11, 50, 123, 163, 135, 64, 77, 103], // y = d45
|
||||
[113, 9, 36, 155, 111, 157, 32, 44, 161], // y = d135
|
||||
[116, 9, 55, 176, 76, 96, 37, 61, 149], // y = d117
|
||||
[115, 9, 28, 141, 161, 167, 21, 25, 193], // y = d153
|
||||
[120, 12, 32, 145, 195, 142, 32, 38, 86], // y = d207
|
||||
[116, 12, 64, 120, 140, 125, 49, 115, 121], // y = d63
|
||||
[102, 19, 66, 162, 182, 122, 35, 59, 128] // y = tm
|
||||
];
|
||||
|
||||
private static readonly byte[] DefaultIfYProbs =
|
||||
{
|
||||
private static readonly byte[] _defaultIfYProbs =
|
||||
[
|
||||
65, 32, 18, 144, 162, 194, 41, 51, 98, // block_size < 8x8
|
||||
132, 68, 18, 165, 217, 196, 45, 40, 78, // block_size < 16x16
|
||||
173, 80, 19, 176, 240, 193, 64, 35, 46, // block_size < 32x32
|
||||
221, 135, 38, 194, 248, 121, 96, 85, 29 // block_size >= 32x32
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly byte[] DefaultIfUvProbs =
|
||||
{
|
||||
private static readonly byte[] _defaultIfUvProbs =
|
||||
[
|
||||
120, 7, 76, 176, 208, 126, 28, 54, 103, // y = dc
|
||||
48, 12, 154, 155, 139, 90, 34, 117, 119, // y = v
|
||||
67, 6, 25, 204, 243, 158, 13, 21, 96, // y = h
|
||||
@@ -190,10 +180,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
85, 5, 32, 156, 216, 148, 19, 29, 73, // y = d207
|
||||
77, 7, 64, 116, 132, 122, 37, 126, 120, // y = d63
|
||||
101, 21, 107, 181, 192, 103, 19, 67, 125 // y = tm
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly byte[] DefaultPartitionProbs =
|
||||
{
|
||||
private static readonly byte[] _defaultPartitionProbs =
|
||||
[
|
||||
// 8x8 . 4x4
|
||||
199, 122, 141, // a/l both not split
|
||||
147, 63, 159, // a split, l not split
|
||||
@@ -214,10 +204,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
72, 16, 44, // a split, l not split
|
||||
58, 32, 12, // l split, a not split
|
||||
10, 7, 6 // a/l both split
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly byte[] DefaultInterModeProbs =
|
||||
{
|
||||
private static readonly byte[] _defaultInterModeProbs =
|
||||
[
|
||||
2, 173, 34, // 0 = both zero mv
|
||||
7, 145, 85, // 1 = one zero mv + one a predicted mv
|
||||
7, 166, 63, // 2 = two predicted mvs
|
||||
@@ -225,120 +215,120 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
8, 64, 46, // 4 = two new mvs
|
||||
17, 81, 31, // 5 = one intra neighbour + x
|
||||
25, 29, 30 // 6 = two intra neighbours
|
||||
};
|
||||
];
|
||||
|
||||
/* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
|
||||
public static readonly sbyte[] IntraModeTree =
|
||||
{
|
||||
[
|
||||
-(int)PredictionMode.DcPred, 2, /* 0 = DC_NODE */ -(int)PredictionMode.TmPred, 4, /* 1 = TM_NODE */
|
||||
-(int)PredictionMode.VPred, 6, /* 2 = V_NODE */ 8, 12, /* 3 = COM_NODE */ -(int)PredictionMode.HPred,
|
||||
10, /* 4 = H_NODE */ -(int)PredictionMode.D135Pred, -(int)PredictionMode.D117Pred, /* 5 = D135_NODE */
|
||||
-(int)PredictionMode.D45Pred, 14, /* 6 = D45_NODE */ -(int)PredictionMode.D63Pred,
|
||||
16, /* 7 = D63_NODE */ -(int)PredictionMode.D153Pred, -(int)PredictionMode.D207Pred /* 8 = D153_NODE */
|
||||
};
|
||||
];
|
||||
|
||||
public static readonly sbyte[] InterModeTree =
|
||||
{
|
||||
[
|
||||
-((int)PredictionMode.ZeroMv - (int)PredictionMode.NearestMv), 2,
|
||||
-((int)PredictionMode.NearestMv - (int)PredictionMode.NearestMv), 4,
|
||||
-((int)PredictionMode.NearMv - (int)PredictionMode.NearestMv),
|
||||
-((int)PredictionMode.NewMv - (int)PredictionMode.NearestMv)
|
||||
};
|
||||
];
|
||||
|
||||
public static readonly sbyte[] PartitionTree =
|
||||
{
|
||||
[
|
||||
-(sbyte)PartitionType.PartitionNone, 2, -(sbyte)PartitionType.PartitionHorz, 4,
|
||||
-(sbyte)PartitionType.PartitionVert, -(sbyte)PartitionType.PartitionSplit
|
||||
};
|
||||
];
|
||||
|
||||
public static readonly sbyte[] SwitchableInterpTree =
|
||||
{
|
||||
[
|
||||
-Constants.EightTap, 2, -Constants.EightTapSmooth, -Constants.EightTapSharp
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly byte[] DefaultIntraInterP = { 9, 102, 187, 225 };
|
||||
private static readonly byte[] DefaultCompInterP = { 239, 183, 119, 96, 41 };
|
||||
private static readonly byte[] DefaultCompRefP = { 50, 126, 123, 221, 226 };
|
||||
private static readonly byte[] DefaultSingleRefP = { 33, 16, 77, 74, 142, 142, 172, 170, 238, 247 };
|
||||
private static readonly byte[] DefaultTxProbs = { 3, 136, 37, 5, 52, 13, 20, 152, 15, 101, 100, 66 };
|
||||
private static readonly byte[] _defaultIntraInterP = [9, 102, 187, 225];
|
||||
private static readonly byte[] _defaultCompInterP = [239, 183, 119, 96, 41];
|
||||
private static readonly byte[] _defaultCompRefP = [50, 126, 123, 221, 226];
|
||||
private static readonly byte[] _defaultSingleRefP = [33, 16, 77, 74, 142, 142, 172, 170, 238, 247];
|
||||
private static readonly byte[] _defaultTxProbs = [3, 136, 37, 5, 52, 13, 20, 152, 15, 101, 100, 66];
|
||||
|
||||
static EntropyMode()
|
||||
{
|
||||
byte[][] KfPartitionProbs =
|
||||
{
|
||||
byte[][] kfPartitionProbs =
|
||||
[
|
||||
// 8x8 . 4x4
|
||||
new byte[] { 158, 97, 94 }, // a/l both not split
|
||||
new byte[] { 93, 24, 99 }, // a split, l not split
|
||||
new byte[] { 85, 119, 44 }, // l split, a not split
|
||||
new byte[] { 62, 59, 67 }, // a/l both split
|
||||
[158, 97, 94], // a/l both not split
|
||||
[93, 24, 99], // a split, l not split
|
||||
[85, 119, 44], // l split, a not split
|
||||
[62, 59, 67], // a/l both split
|
||||
|
||||
// 16x16 . 8x8
|
||||
new byte[] { 149, 53, 53 }, // a/l both not split
|
||||
new byte[] { 94, 20, 48 }, // a split, l not split
|
||||
new byte[] { 83, 53, 24 }, // l split, a not split
|
||||
new byte[] { 52, 18, 18 }, // a/l both split
|
||||
[149, 53, 53], // a/l both not split
|
||||
[94, 20, 48], // a split, l not split
|
||||
[83, 53, 24], // l split, a not split
|
||||
[52, 18, 18], // a/l both split
|
||||
|
||||
// 32x32 . 16x16
|
||||
new byte[] { 150, 40, 39 }, // a/l both not split
|
||||
new byte[] { 78, 12, 26 }, // a split, l not split
|
||||
new byte[] { 67, 33, 11 }, // l split, a not split
|
||||
new byte[] { 24, 7, 5 }, // a/l both split
|
||||
[150, 40, 39], // a/l both not split
|
||||
[78, 12, 26], // a split, l not split
|
||||
[67, 33, 11], // l split, a not split
|
||||
[24, 7, 5], // a/l both split
|
||||
|
||||
// 64x64 . 32x32
|
||||
new byte[] { 174, 35, 49 }, // a/l both not split
|
||||
new byte[] { 68, 11, 27 }, // a split, l not split
|
||||
new byte[] { 57, 15, 9 }, // l split, a not split
|
||||
new byte[] { 12, 3, 3 } // a/l both split
|
||||
};
|
||||
[174, 35, 49], // a/l both not split
|
||||
[68, 11, 27], // a split, l not split
|
||||
[57, 15, 9], // l split, a not split
|
||||
[12, 3, 3] // a/l both split
|
||||
];
|
||||
}
|
||||
|
||||
private static readonly byte[] DefaultSkipProbs = { 192, 128, 64 };
|
||||
private static readonly byte[] _defaultSkipProbs = [192, 128, 64];
|
||||
|
||||
private static readonly byte[] DefaultSwitchableInterpProb = { 235, 162, 36, 255, 34, 3, 149, 144 };
|
||||
private static readonly byte[] _defaultSwitchableInterpProb = [235, 162, 36, 255, 34, 3, 149, 144];
|
||||
|
||||
private static void InitModeProbs(ref Vp9EntropyProbs fc)
|
||||
{
|
||||
Entropy.CopyProbs(ref fc.UvModeProb, DefaultIfUvProbs);
|
||||
Entropy.CopyProbs(ref fc.YModeProb, DefaultIfYProbs);
|
||||
Entropy.CopyProbs(ref fc.SwitchableInterpProb, DefaultSwitchableInterpProb);
|
||||
Entropy.CopyProbs(ref fc.PartitionProb, DefaultPartitionProbs);
|
||||
Entropy.CopyProbs(ref fc.IntraInterProb, DefaultIntraInterP);
|
||||
Entropy.CopyProbs(ref fc.CompInterProb, DefaultCompInterP);
|
||||
Entropy.CopyProbs(ref fc.CompRefProb, DefaultCompRefP);
|
||||
Entropy.CopyProbs(ref fc.SingleRefProb, DefaultSingleRefP);
|
||||
Entropy.CopyProbs(ref fc.Tx32x32Prob, DefaultTxProbs.AsSpan().Slice(0, 6));
|
||||
Entropy.CopyProbs(ref fc.Tx16x16Prob, DefaultTxProbs.AsSpan().Slice(6, 4));
|
||||
Entropy.CopyProbs(ref fc.Tx8x8Prob, DefaultTxProbs.AsSpan().Slice(10, 2));
|
||||
Entropy.CopyProbs(ref fc.SkipProb, DefaultSkipProbs);
|
||||
Entropy.CopyProbs(ref fc.InterModeProb, DefaultInterModeProbs);
|
||||
Entropy.CopyProbs(ref fc.UvModeProb, _defaultIfUvProbs);
|
||||
Entropy.CopyProbs(ref fc.YModeProb, _defaultIfYProbs);
|
||||
Entropy.CopyProbs(ref fc.SwitchableInterpProb, _defaultSwitchableInterpProb);
|
||||
Entropy.CopyProbs(ref fc.PartitionProb, _defaultPartitionProbs);
|
||||
Entropy.CopyProbs(ref fc.IntraInterProb, _defaultIntraInterP);
|
||||
Entropy.CopyProbs(ref fc.CompInterProb, _defaultCompInterP);
|
||||
Entropy.CopyProbs(ref fc.CompRefProb, _defaultCompRefP);
|
||||
Entropy.CopyProbs(ref fc.SingleRefProb, _defaultSingleRefP);
|
||||
Entropy.CopyProbs(ref fc.Tx32x32Prob, _defaultTxProbs.AsSpan().Slice(0, 6));
|
||||
Entropy.CopyProbs(ref fc.Tx16x16Prob, _defaultTxProbs.AsSpan().Slice(6, 4));
|
||||
Entropy.CopyProbs(ref fc.Tx8x8Prob, _defaultTxProbs.AsSpan().Slice(10, 2));
|
||||
Entropy.CopyProbs(ref fc.SkipProb, _defaultSkipProbs);
|
||||
Entropy.CopyProbs(ref fc.InterModeProb, _defaultInterModeProbs);
|
||||
}
|
||||
|
||||
internal static void TxCountsToBranchCounts32x32(ReadOnlySpan<uint> txCount32x32P,
|
||||
ref Array3<Array2<uint>> ct32x32P)
|
||||
internal static void TxCountsToBranchCounts32X32(ReadOnlySpan<uint> txCount32X32P,
|
||||
ref Array3<Array2<uint>> ct32X32P)
|
||||
{
|
||||
ct32x32P[0][0] = txCount32x32P[(int)TxSize.Tx4x4];
|
||||
ct32x32P[0][1] = txCount32x32P[(int)TxSize.Tx8x8] + txCount32x32P[(int)TxSize.Tx16x16] +
|
||||
txCount32x32P[(int)TxSize.Tx32x32];
|
||||
ct32x32P[1][0] = txCount32x32P[(int)TxSize.Tx8x8];
|
||||
ct32x32P[1][1] = txCount32x32P[(int)TxSize.Tx16x16] + txCount32x32P[(int)TxSize.Tx32x32];
|
||||
ct32x32P[2][0] = txCount32x32P[(int)TxSize.Tx16x16];
|
||||
ct32x32P[2][1] = txCount32x32P[(int)TxSize.Tx32x32];
|
||||
ct32X32P[0][0] = txCount32X32P[(int)TxSize.Tx4X4];
|
||||
ct32X32P[0][1] = txCount32X32P[(int)TxSize.Tx8X8] + txCount32X32P[(int)TxSize.Tx16X16] +
|
||||
txCount32X32P[(int)TxSize.Tx32X32];
|
||||
ct32X32P[1][0] = txCount32X32P[(int)TxSize.Tx8X8];
|
||||
ct32X32P[1][1] = txCount32X32P[(int)TxSize.Tx16X16] + txCount32X32P[(int)TxSize.Tx32X32];
|
||||
ct32X32P[2][0] = txCount32X32P[(int)TxSize.Tx16X16];
|
||||
ct32X32P[2][1] = txCount32X32P[(int)TxSize.Tx32X32];
|
||||
}
|
||||
|
||||
internal static void TxCountsToBranchCounts16x16(ReadOnlySpan<uint> txCount16x16P,
|
||||
ref Array2<Array2<uint>> ct16x16P)
|
||||
internal static void TxCountsToBranchCounts16X16(ReadOnlySpan<uint> txCount16X16P,
|
||||
ref Array2<Array2<uint>> ct16X16P)
|
||||
{
|
||||
ct16x16P[0][0] = txCount16x16P[(int)TxSize.Tx4x4];
|
||||
ct16x16P[0][1] = txCount16x16P[(int)TxSize.Tx8x8] + txCount16x16P[(int)TxSize.Tx16x16];
|
||||
ct16x16P[1][0] = txCount16x16P[(int)TxSize.Tx8x8];
|
||||
ct16x16P[1][1] = txCount16x16P[(int)TxSize.Tx16x16];
|
||||
ct16X16P[0][0] = txCount16X16P[(int)TxSize.Tx4X4];
|
||||
ct16X16P[0][1] = txCount16X16P[(int)TxSize.Tx8X8] + txCount16X16P[(int)TxSize.Tx16X16];
|
||||
ct16X16P[1][0] = txCount16X16P[(int)TxSize.Tx8X8];
|
||||
ct16X16P[1][1] = txCount16X16P[(int)TxSize.Tx16X16];
|
||||
}
|
||||
|
||||
internal static void TxCountsToBranchCounts8x8(ReadOnlySpan<uint> txCount8x8P,
|
||||
ref Array1<Array2<uint>> ct8x8P)
|
||||
internal static void TxCountsToBranchCounts8X8(ReadOnlySpan<uint> txCount8X8P,
|
||||
ref Array1<Array2<uint>> ct8X8P)
|
||||
{
|
||||
ct8x8P[0][0] = txCount8x8P[(int)TxSize.Tx4x4];
|
||||
ct8x8P[0][1] = txCount8x8P[(int)TxSize.Tx8x8];
|
||||
ct8X8P[0][0] = txCount8X8P[(int)TxSize.Tx4X4];
|
||||
ct8X8P[0][1] = txCount8X8P[(int)TxSize.Tx8X8];
|
||||
}
|
||||
|
||||
public static unsafe void SetupPastIndependence(ref Vp9Common cm)
|
||||
|
||||
@@ -14,22 +14,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
|
||||
public static readonly sbyte[] JointTree =
|
||||
{
|
||||
[
|
||||
-(sbyte)MvJointType.Zero, 2, -(sbyte)MvJointType.Hnzvz, 4,
|
||||
-(sbyte)MvJointType.Hzvnz, -(sbyte)MvJointType.Hnzvnz
|
||||
};
|
||||
];
|
||||
|
||||
public static readonly sbyte[] ClassTree =
|
||||
{
|
||||
[
|
||||
-(sbyte)MvClassType.Class0, 2, -(sbyte)MvClassType.Class1, 4, 6, 8, -(sbyte)MvClassType.Class2,
|
||||
-(sbyte)MvClassType.Class3, 10, 12, -(sbyte)MvClassType.Class4, -(sbyte)MvClassType.Class5,
|
||||
-(sbyte)MvClassType.Class6, 14, 16, 18, -(sbyte)MvClassType.Class7, -(sbyte)MvClassType.Class8,
|
||||
-(sbyte)MvClassType.Class9, -(sbyte)MvClassType.Class10
|
||||
};
|
||||
];
|
||||
|
||||
public static readonly sbyte[] Class0Tree = { -0, -1 };
|
||||
public static readonly sbyte[] Class0Tree = [-0, -1];
|
||||
|
||||
public static readonly sbyte[] FpTree = { -0, 2, -1, 4, -2, -3 };
|
||||
public static readonly sbyte[] FpTree = [-0, 2, -1, 4, -2, -3];
|
||||
|
||||
private static bool JointVertical(MvJointType type)
|
||||
{
|
||||
@@ -41,8 +41,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return type == MvJointType.Hnzvz || type == MvJointType.Hnzvnz;
|
||||
}
|
||||
|
||||
private static readonly byte[] LogInBase2 =
|
||||
{
|
||||
private static readonly byte[] _logInBase2 =
|
||||
[
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
@@ -73,7 +73,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
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
|
||||
};
|
||||
];
|
||||
|
||||
private static int ClassBase(MvClassType c)
|
||||
{
|
||||
@@ -84,7 +84,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
MvClassType c = z >= Class0Size * 4096
|
||||
? MvClassType.Class10
|
||||
: (MvClassType)LogInBase2[z >> 3];
|
||||
: (MvClassType)_logInBase2[z >> 3];
|
||||
if (!offset.IsNull)
|
||||
{
|
||||
offset.Value = z - ClassBase(c);
|
||||
@@ -95,18 +95,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private static void IncComponent(int v, ref Vp9BackwardUpdates compCounts, int compIndex, int incr, int usehp)
|
||||
{
|
||||
int s, z, c, o = 0, d, e, f;
|
||||
int o = 0;
|
||||
Debug.Assert(v != 0); /* should not be zero */
|
||||
s = v < 0 ? 1 : 0;
|
||||
int s = v < 0 ? 1 : 0;
|
||||
compCounts.Sign[compIndex][s] += (uint)incr;
|
||||
z = (s != 0 ? -v : v) - 1; /* magnitude - 1 */
|
||||
int z = (s != 0 ? -v : v) - 1 /* magnitude - 1 */;
|
||||
|
||||
c = (int)GetClass(z, new Ptr<int>(ref o));
|
||||
int c = (int)GetClass(z, new Ptr<int>(ref o));
|
||||
compCounts.Classes[compIndex][c] += (uint)incr;
|
||||
|
||||
d = o >> 3; /* int mv data */
|
||||
f = (o >> 1) & 3; /* fractional pel mv data */
|
||||
e = o & 1; /* high precision mv data */
|
||||
int d = o >> 3 /* int mv data */;
|
||||
int f = (o >> 1) & 3 /* fractional pel mv data */;
|
||||
int e = o & 1 /* high precision mv data */;
|
||||
|
||||
if (c == (int)MvClassType.Class0)
|
||||
{
|
||||
@@ -162,4 +162,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
public const int Upp = (1 << InUseBits) - 1;
|
||||
public const int Low = -(1 << InUseBits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,48 +21,47 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref VpxCodecFrameBuffer fb)
|
||||
{
|
||||
int i;
|
||||
Ptr<InternalFrameBufferList> intFbList = cbPriv;
|
||||
if (intFbList.IsNull)
|
||||
if (cbPriv.IsNull)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Find a free frame buffer.
|
||||
for (i = 0; i < intFbList.Value.IntFb.Length; ++i)
|
||||
for (i = 0; i < cbPriv.Value.IntFb.Length; ++i)
|
||||
{
|
||||
if (!intFbList.Value.IntFb[i].InUse)
|
||||
if (!cbPriv.Value.IntFb[i].InUse)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == intFbList.Value.IntFb.Length)
|
||||
if (i == cbPriv.Value.IntFb.Length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ulong)intFbList.Value.IntFb[i].Data.Length < minSize)
|
||||
if ((ulong)cbPriv.Value.IntFb[i].Data.Length < minSize)
|
||||
{
|
||||
if (!intFbList.Value.IntFb[i].Data.IsNull)
|
||||
if (!cbPriv.Value.IntFb[i].Data.IsNull)
|
||||
{
|
||||
allocator.Free(intFbList.Value.IntFb[i].Data);
|
||||
allocator.Free(cbPriv.Value.IntFb[i].Data);
|
||||
}
|
||||
|
||||
// The data must be zeroed to fix a valgrind error from the C loop filter
|
||||
// due to access uninitialized memory in frame border. It could be
|
||||
// skipped if border were totally removed.
|
||||
intFbList.Value.IntFb[i].Data = allocator.Allocate<byte>((int)minSize);
|
||||
if (intFbList.Value.IntFb[i].Data.IsNull)
|
||||
cbPriv.Value.IntFb[i].Data = allocator.Allocate<byte>((int)minSize);
|
||||
if (cbPriv.Value.IntFb[i].Data.IsNull)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fb.Data = intFbList.Value.IntFb[i].Data;
|
||||
intFbList.Value.IntFb[i].InUse = true;
|
||||
fb.Data = cbPriv.Value.IntFb[i].Data;
|
||||
cbPriv.Value.IntFb[i].InUse = true;
|
||||
|
||||
// Set the frame buffer's private data to point at the internal frame buffer.
|
||||
fb.Priv = new Ptr<InternalFrameBuffer>(ref intFbList.Value.IntFb[i]);
|
||||
fb.Priv = new Ptr<InternalFrameBuffer>(ref cbPriv.Value.IntFb[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -76,4 +75,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,15 +35,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] Iht4 =
|
||||
{
|
||||
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)
|
||||
public static void Iht4X416Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
||||
{
|
||||
Span<int> output = stackalloc int[4 * 4];
|
||||
Span<int> outptr = output;
|
||||
@@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// Inverse transform row vectors
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
Iht4[txType].Rows(input, outptr);
|
||||
_iht4[txType].Rows(input, outptr);
|
||||
input = input.Slice(4);
|
||||
outptr = outptr.Slice(4);
|
||||
}
|
||||
@@ -66,7 +66,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
tempIn[j] = output[(j * 4) + i];
|
||||
}
|
||||
|
||||
Iht4[txType].Cols(tempIn, tempOut);
|
||||
_iht4[txType].Cols(tempIn, tempOut);
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
dest[(j * stride) + i] =
|
||||
@@ -75,21 +75,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] Iht8 =
|
||||
{
|
||||
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)
|
||||
public static void Iht8X864Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
||||
{
|
||||
Span<int> output = stackalloc int[8 * 8];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[8];
|
||||
Span<int> tempOut = stackalloc int[8];
|
||||
Transform2D ht = Iht8[txType];
|
||||
Transform2D ht = _iht8[txType];
|
||||
|
||||
// Inverse transform row vectors
|
||||
for (int i = 0; i < 8; ++i)
|
||||
@@ -116,21 +116,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] Iht16 =
|
||||
{
|
||||
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)
|
||||
public static void Iht16X16256Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
||||
{
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
Transform2D ht = Iht16[txType];
|
||||
Transform2D ht = _iht16[txType];
|
||||
|
||||
// Rows
|
||||
for (int i = 0; i < 16; ++i)
|
||||
@@ -158,31 +158,31 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
// Idct
|
||||
public static void Idct4x4Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
public static void Idct4X4Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
{
|
||||
if (eob > 1)
|
||||
{
|
||||
Idct4x416Add(input, dest, stride);
|
||||
Idct4X416Add(input, dest, stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
Idct4x41Add(input, dest, stride);
|
||||
Idct4X41Add(input, dest, stride);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Iwht4x4Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
public static void Iwht4X4Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
{
|
||||
if (eob > 1)
|
||||
{
|
||||
Iwht4x416Add(input, dest, stride);
|
||||
Iwht4X416Add(input, dest, stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
Iwht4x41Add(input, dest, stride);
|
||||
Iwht4X41Add(input, dest, stride);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Idct8x8Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
public static void Idct8X8Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
{
|
||||
// If dc is 1, then input[0] is the reconstructed value, do not need
|
||||
// dequantization. Also, when dc is 1, dc is counted in eobs, namely eobs >=1.
|
||||
@@ -192,109 +192,109 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (eob == 1)
|
||||
{
|
||||
// DC only DCT coefficient
|
||||
Idct8x81Add(input, dest, stride);
|
||||
Idct8X81Add(input, dest, stride);
|
||||
}
|
||||
else if (eob <= 12)
|
||||
{
|
||||
Idct8x812Add(input, dest, stride);
|
||||
Idct8X812Add(input, dest, stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
Idct8x864Add(input, dest, stride);
|
||||
Idct8X864Add(input, dest, stride);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Idct16x16Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
public static void Idct16X16Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
{
|
||||
/* The calculation can be simplified if there are not many non-zero dct
|
||||
* coefficients. Use eobs to separate different cases. */
|
||||
if (eob == 1) /* DC only DCT coefficient. */
|
||||
{
|
||||
Idct16x161Add(input, dest, stride);
|
||||
Idct16X161Add(input, dest, stride);
|
||||
}
|
||||
else if (eob <= 10)
|
||||
{
|
||||
Idct16x1610Add(input, dest, stride);
|
||||
Idct16X1610Add(input, dest, stride);
|
||||
}
|
||||
else if (eob <= 38)
|
||||
{
|
||||
Idct16x1638Add(input, dest, stride);
|
||||
Idct16X1638Add(input, dest, stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
Idct16x16256Add(input, dest, stride);
|
||||
Idct16X16256Add(input, dest, stride);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Idct32x32Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
public static void Idct32X32Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
{
|
||||
if (eob == 1)
|
||||
{
|
||||
Idct32x321Add(input, dest, stride);
|
||||
Idct32X321Add(input, dest, stride);
|
||||
}
|
||||
else if (eob <= 34)
|
||||
{
|
||||
// Non-zero coeff only in upper-left 8x8
|
||||
Idct32x3234Add(input, dest, stride);
|
||||
Idct32X3234Add(input, dest, stride);
|
||||
}
|
||||
else if (eob <= 135)
|
||||
{
|
||||
// Non-zero coeff only in upper-left 16x16
|
||||
Idct32x32135Add(input, dest, stride);
|
||||
Idct32X32135Add(input, dest, stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
Idct32x321024Add(input, dest, stride);
|
||||
Idct32X321024Add(input, dest, stride);
|
||||
}
|
||||
}
|
||||
|
||||
// Iht
|
||||
public static void Iht4x4Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
public static void Iht4X4Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
Idct4x4Add(input, dest, stride, eob);
|
||||
Idct4X4Add(input, dest, stride, eob);
|
||||
}
|
||||
else
|
||||
{
|
||||
Iht4x416Add(input, dest, stride, (int)txType);
|
||||
Iht4X416Add(input, dest, stride, (int)txType);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Iht8x8Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
public static void Iht8X8Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
Idct8x8Add(input, dest, stride, eob);
|
||||
Idct8X8Add(input, dest, stride, eob);
|
||||
}
|
||||
else
|
||||
{
|
||||
Iht8x864Add(input, dest, stride, (int)txType);
|
||||
Iht8X864Add(input, dest, stride, (int)txType);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Iht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest,
|
||||
public static void Iht16X16Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest,
|
||||
int stride, int eob)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
Idct16x16Add(input, dest, stride, eob);
|
||||
Idct16X16Add(input, dest, stride, eob);
|
||||
}
|
||||
else
|
||||
{
|
||||
Iht16x16256Add(input, dest, stride, (int)txType);
|
||||
Iht16X16256Add(input, dest, stride, (int)txType);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] HighbdIht4 =
|
||||
{
|
||||
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)
|
||||
public static void HighbdIht4X416Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[4 * 4];
|
||||
Span<int> outptr = output;
|
||||
@@ -304,7 +304,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// Inverse transform row vectors.
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
HighbdIht4[txType].Rows(input, outptr, bd);
|
||||
_highbdIht4[txType].Rows(input, outptr, bd);
|
||||
input = input.Slice(4);
|
||||
outptr = outptr.Slice(4);
|
||||
}
|
||||
@@ -317,7 +317,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 (int j = 0; j < 4; ++j)
|
||||
{
|
||||
dest[(j * stride) + i] = HighbdClipPixelAdd(dest[(j * stride) + i],
|
||||
@@ -326,21 +326,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] HighIht8 =
|
||||
{
|
||||
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)
|
||||
public static void HighbdIht8X864Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[8 * 8];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[8];
|
||||
Span<int> tempOut = stackalloc int[8];
|
||||
HighbdTransform2D ht = HighIht8[txType];
|
||||
HighbdTransform2D ht = _highIht8[txType];
|
||||
|
||||
// Inverse transform row vectors.
|
||||
for (int i = 0; i < 8; ++i)
|
||||
@@ -367,22 +367,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] HighIht16 =
|
||||
{
|
||||
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,
|
||||
public static void HighbdIht16X16256Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType,
|
||||
int bd)
|
||||
{
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
HighbdTransform2D ht = HighIht16[txType];
|
||||
HighbdTransform2D ht = _highIht16[txType];
|
||||
|
||||
// Rows
|
||||
for (int i = 0; i < 16; ++i)
|
||||
@@ -410,31 +410,31 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
// Idct
|
||||
public static void HighbdIdct4x4Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
public static void HighbdIdct4X4Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
{
|
||||
if (eob > 1)
|
||||
{
|
||||
HighbdIdct4x416Add(input, dest, stride, bd);
|
||||
HighbdIdct4X416Add(input, dest, stride, bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
HighbdIdct4x41Add(input, dest, stride, bd);
|
||||
HighbdIdct4X41Add(input, dest, stride, bd);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIwht4x4Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
public static void HighbdIwht4X4Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
{
|
||||
if (eob > 1)
|
||||
{
|
||||
HighbdIwht4x416Add(input, dest, stride, bd);
|
||||
HighbdIwht4X416Add(input, dest, stride, bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
HighbdIwht4x41Add(input, dest, stride, bd);
|
||||
HighbdIwht4X41Add(input, dest, stride, bd);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIdct8x8Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
public static void HighbdIdct8X8Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
{
|
||||
// If dc is 1, then input[0] is the reconstructed value, do not need
|
||||
// dequantization. Also, when dc is 1, dc is counted in eobs, namely eobs >=1.
|
||||
@@ -444,99 +444,99 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// DC only DCT coefficient
|
||||
if (eob == 1)
|
||||
{
|
||||
VpxHighbdidct8x81AddC(input, dest, stride, bd);
|
||||
VpxHighbdidct8X81AddC(input, dest, stride, bd);
|
||||
}
|
||||
else if (eob <= 12)
|
||||
{
|
||||
HighbdIdct8x812Add(input, dest, stride, bd);
|
||||
HighbdIdct8X812Add(input, dest, stride, bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
HighbdIdct8x864Add(input, dest, stride, bd);
|
||||
HighbdIdct8X864Add(input, dest, stride, bd);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIdct16x16Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
public static void HighbdIdct16X16Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
{
|
||||
// The calculation can be simplified if there are not many non-zero dct
|
||||
// coefficients. Use eobs to separate different cases.
|
||||
// DC only DCT coefficient.
|
||||
if (eob == 1)
|
||||
{
|
||||
HighbdIdct16x161Add(input, dest, stride, bd);
|
||||
HighbdIdct16X161Add(input, dest, stride, bd);
|
||||
}
|
||||
else if (eob <= 10)
|
||||
{
|
||||
HighbdIdct16x1610Add(input, dest, stride, bd);
|
||||
HighbdIdct16X1610Add(input, dest, stride, bd);
|
||||
}
|
||||
else if (eob <= 38)
|
||||
{
|
||||
HighbdIdct16x1638Add(input, dest, stride, bd);
|
||||
HighbdIdct16X1638Add(input, dest, stride, bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
HighbdIdct16x16256Add(input, dest, stride, bd);
|
||||
HighbdIdct16X16256Add(input, dest, stride, bd);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIdct32x32Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
public static void HighbdIdct32X32Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
{
|
||||
// Non-zero coeff only in upper-left 8x8
|
||||
if (eob == 1)
|
||||
{
|
||||
HighbdIdct32x321Add(input, dest, stride, bd);
|
||||
HighbdIdct32X321Add(input, dest, stride, bd);
|
||||
}
|
||||
else if (eob <= 34)
|
||||
{
|
||||
HighbdIdct32x3234Add(input, dest, stride, bd);
|
||||
HighbdIdct32X3234Add(input, dest, stride, bd);
|
||||
}
|
||||
else if (eob <= 135)
|
||||
{
|
||||
HighbdIdct32x32135Add(input, dest, stride, bd);
|
||||
HighbdIdct32X32135Add(input, dest, stride, bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
HighbdIdct32x321024Add(input, dest, stride, bd);
|
||||
HighbdIdct32X321024Add(input, dest, stride, bd);
|
||||
}
|
||||
}
|
||||
|
||||
// Iht
|
||||
public static void HighbdIht4x4Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
public static void HighbdIht4X4Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
int eob, int bd)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
HighbdIdct4x4Add(input, dest, stride, eob, bd);
|
||||
HighbdIdct4X4Add(input, dest, stride, eob, bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
HighbdIht4x416Add(input, dest, stride, (int)txType, bd);
|
||||
HighbdIht4X416Add(input, dest, stride, (int)txType, bd);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIht8x8Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
public static void HighbdIht8X8Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
int eob, int bd)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
HighbdIdct8x8Add(input, dest, stride, eob, bd);
|
||||
HighbdIdct8X8Add(input, dest, stride, eob, bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
HighbdIht8x864Add(input, dest, stride, (int)txType, bd);
|
||||
HighbdIht8X864Add(input, dest, stride, (int)txType, bd);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
public static void HighbdIht16X16Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
int eob, int bd)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
HighbdIdct16x16Add(input, dest, stride, eob, bd);
|
||||
HighbdIdct16X16Add(input, dest, stride, eob, bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
HighbdIht16x16256Add(input, dest, stride, (int)txType, bd);
|
||||
HighbdIht16X16256Add(input, dest, stride, (int)txType, bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -46,10 +46,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
// MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT;
|
||||
private static readonly uint[] CountToUpdateFactor =
|
||||
{
|
||||
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
|
||||
};
|
||||
];
|
||||
|
||||
private const int ModeMvCountSat = 20;
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
uint count = Math.Min(den, ModeMvCountSat);
|
||||
uint factor = CountToUpdateFactor[(int)count];
|
||||
uint factor = _countToUpdateFactor[(int)count];
|
||||
byte prob = GetProb(ct[0], den);
|
||||
return WeightedProb(preProb, prob, (int)factor);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
public const int MaxQ = 255;
|
||||
public const int QindexBits = 8;
|
||||
|
||||
private static readonly short[] DcQlookup =
|
||||
{
|
||||
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, 43, 43, 44, 45, 46, 47, 48, 48, 49, 50, 51,
|
||||
52, 53, 53, 54, 55, 56, 57, 57, 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 70, 71, 72,
|
||||
@@ -22,10 +22,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
447, 454, 461, 467, 475, 482, 489, 497, 505, 513, 522, 530, 539, 549, 559, 569, 579, 590, 602, 614, 626,
|
||||
640, 654, 668, 684, 700, 717, 736, 755, 775, 796, 819, 843, 869, 896, 925, 955, 988, 1022, 1058, 1098,
|
||||
1139, 1184, 1232, 1282, 1336
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly short[] DcQlookup10 =
|
||||
{
|
||||
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, 136, 140, 143, 147, 151, 155, 159, 163,
|
||||
166, 170, 174, 178, 182, 185, 189, 193, 197, 200, 204, 208, 212, 215, 219, 223, 226, 230, 233, 237, 241,
|
||||
@@ -39,10 +39,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
1692, 1717, 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, 1958, 1990, 2021, 2054, 2088, 2123, 2159,
|
||||
2197, 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, 2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102,
|
||||
3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953, 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly short[] DcQlookup12 =
|
||||
{
|
||||
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, 421, 437, 453, 469, 484, 500, 516, 532, 548, 564, 580,
|
||||
596, 611, 627, 643, 659, 674, 690, 706, 721, 737, 752, 768, 783, 798, 814, 829, 844, 859, 874, 889, 904,
|
||||
@@ -58,10 +58,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
8214, 8352, 8492, 8635, 8788, 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, 10465, 10702, 10946,
|
||||
11210, 11482, 11776, 12081, 12409, 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, 16356, 16943,
|
||||
17575, 18237, 18949, 19718, 20521, 21387
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly short[] AcQlookup =
|
||||
{
|
||||
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, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
|
||||
@@ -74,10 +74,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
729, 743, 757, 771, 786, 801, 816, 832, 848, 864, 881, 898, 915, 933, 951, 969, 988, 1007, 1026, 1046,
|
||||
1066, 1087, 1108, 1129, 1151, 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, 1369, 1396, 1423, 1451,
|
||||
1479, 1508, 1537, 1567, 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly short[] AcQlookup10 =
|
||||
{
|
||||
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, 154, 158, 163, 168, 172, 177, 181, 186,
|
||||
190, 195, 199, 204, 208, 213, 217, 222, 226, 231, 235, 240, 244, 249, 253, 258, 262, 267, 271, 275, 280,
|
||||
@@ -92,10 +92,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
3659, 3731, 3803, 3876, 3952, 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, 4692, 4784, 4876, 4972,
|
||||
5068, 5168, 5268, 5372, 5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268, 6388, 6512, 6640, 6768, 6900,
|
||||
7036, 7172, 7312
|
||||
};
|
||||
];
|
||||
|
||||
private static readonly short[] AcQlookup12 =
|
||||
{
|
||||
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, 475, 493, 511, 530, 548, 567, 586, 604, 623, 642, 660,
|
||||
679, 698, 716, 735, 753, 772, 791, 809, 828, 846, 865, 884, 902, 920, 939, 957, 976, 994, 1012, 1030,
|
||||
@@ -111,15 +111,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
13565, 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806, 16110, 16414, 16734, 17054, 17390, 17726,
|
||||
18062, 18414, 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, 21902, 22334, 22766, 23214, 23662,
|
||||
24126, 24590, 25070, 25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247
|
||||
};
|
||||
];
|
||||
|
||||
public static short DcQuant(int qindex, int delta, BitDepth bitDepth)
|
||||
{
|
||||
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, "bitDepth should be Bits8, Bits10 or Bits12");
|
||||
return -1;
|
||||
@@ -130,9 +130,9 @@ 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, "bitDepth should be Bits8, Bits10 or Bits12");
|
||||
return -1;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
internal static class ReconIntra
|
||||
{
|
||||
public static readonly TxType[] IntraModeToTxTypeLookup =
|
||||
{
|
||||
[
|
||||
TxType.DctDct, // DC
|
||||
TxType.AdstDct, // V
|
||||
TxType.DctAdst, // H
|
||||
@@ -19,14 +19,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
TxType.DctAdst, // D207
|
||||
TxType.AdstDct, // D63
|
||||
TxType.AdstAdst // TM
|
||||
};
|
||||
];
|
||||
|
||||
private const int NeedLeft = 1 << 1;
|
||||
private const int NeedAbove = 1 << 2;
|
||||
private const int NeedAboveRight = 1 << 3;
|
||||
|
||||
private static ReadOnlySpan<byte> ExtendModes => new byte[]
|
||||
{
|
||||
private static ReadOnlySpan<byte> ExtendModes =>
|
||||
[
|
||||
NeedAbove | NeedLeft, // DC
|
||||
NeedAbove, // V
|
||||
NeedLeft, // H
|
||||
@@ -37,123 +37,103 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
NeedLeft, // D207
|
||||
NeedAboveRight, // D63
|
||||
NeedLeft | NeedAbove // TM
|
||||
};
|
||||
];
|
||||
|
||||
private unsafe delegate void IntraPredFn(byte* dst, int stride, byte* above, byte* left);
|
||||
|
||||
private static readonly unsafe IntraPredFn[][] Pred =
|
||||
{
|
||||
new IntraPredFn[] { null, null, null, null },
|
||||
new IntraPredFn[] { VPredictor4x4, VPredictor8x8, VPredictor16x16, VPredictor32x32 },
|
||||
new IntraPredFn[] { HPredictor4x4, HPredictor8x8, HPredictor16x16, HPredictor32x32 },
|
||||
new IntraPredFn[] { D45Predictor4x4, D45Predictor8x8, D45Predictor16x16, D45Predictor32x32 },
|
||||
new IntraPredFn[] { D135Predictor4x4, D135Predictor8x8, D135Predictor16x16, D135Predictor32x32 },
|
||||
new IntraPredFn[] { D117Predictor4x4, D117Predictor8x8, D117Predictor16x16, D117Predictor32x32 },
|
||||
new IntraPredFn[] { D153Predictor4x4, D153Predictor8x8, D153Predictor16x16, D153Predictor32x32 },
|
||||
new IntraPredFn[] { D207Predictor4x4, D207Predictor8x8, D207Predictor16x16, D207Predictor32x32 },
|
||||
new IntraPredFn[] { D63Predictor4x4, D63Predictor8x8, D63Predictor16x16, D63Predictor32x32 },
|
||||
new IntraPredFn[] { TmPredictor4x4, TmPredictor8x8, TmPredictor16x16, TmPredictor32x32 }
|
||||
};
|
||||
private static readonly unsafe IntraPredFn[][] _pred =
|
||||
[
|
||||
[null, null, null, null],
|
||||
[VPredictor4X4, VPredictor8X8, VPredictor16X16, VPredictor32X32],
|
||||
[HPredictor4X4, HPredictor8X8, HPredictor16X16, HPredictor32X32],
|
||||
[D45Predictor4X4, D45Predictor8X8, D45Predictor16X16, D45Predictor32X32],
|
||||
[D135Predictor4X4, D135Predictor8X8, D135Predictor16X16, D135Predictor32X32],
|
||||
[D117Predictor4X4, D117Predictor8X8, D117Predictor16X16, D117Predictor32X32],
|
||||
[D153Predictor4X4, D153Predictor8X8, D153Predictor16X16, D153Predictor32X32],
|
||||
[D207Predictor4X4, D207Predictor8X8, D207Predictor16X16, D207Predictor32X32],
|
||||
[D63Predictor4X4, D63Predictor8X8, D63Predictor16X16, D63Predictor32X32],
|
||||
[TmPredictor4X4, TmPredictor8X8, TmPredictor16X16, TmPredictor32X32]
|
||||
];
|
||||
|
||||
private static readonly unsafe IntraPredFn[][][] DcPred =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new IntraPredFn[]
|
||||
{
|
||||
Dc128Predictor4x4, Dc128Predictor8x8, Dc128Predictor16x16, Dc128Predictor32x32
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
DcTopPredictor4x4, DcTopPredictor8x8, DcTopPredictor16x16, DcTopPredictor32x32
|
||||
}
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new IntraPredFn[]
|
||||
{
|
||||
DcLeftPredictor4x4, DcLeftPredictor8x8, DcLeftPredictor16x16, DcLeftPredictor32x32
|
||||
},
|
||||
new IntraPredFn[] { DcPredictor4x4, DcPredictor8x8, DcPredictor16x16, DcPredictor32x32 }
|
||||
}
|
||||
};
|
||||
private static readonly unsafe IntraPredFn[][][] _dcPred =
|
||||
[
|
||||
[
|
||||
[
|
||||
Dc128Predictor4X4, Dc128Predictor8X8, Dc128Predictor16X16, Dc128Predictor32X32
|
||||
],
|
||||
[
|
||||
DcTopPredictor4X4, DcTopPredictor8X8, DcTopPredictor16X16, DcTopPredictor32X32
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
DcLeftPredictor4X4, DcLeftPredictor8X8, DcLeftPredictor16X16, DcLeftPredictor32X32
|
||||
],
|
||||
[DcPredictor4X4, DcPredictor8X8, DcPredictor16X16, DcPredictor32X32]
|
||||
]
|
||||
];
|
||||
|
||||
private unsafe delegate void IntraHighPredFn(ushort* dst, int stride, ushort* above, ushort* left, int bd);
|
||||
|
||||
private static readonly unsafe IntraHighPredFn[][] PredHigh =
|
||||
{
|
||||
new IntraHighPredFn[] { null, null, null, null },
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdVPredictor4x4, HighbdVPredictor8x8, HighbdVPredictor16x16, HighbdVPredictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdHPredictor4x4, HighbdHPredictor8x8, HighbdHPredictor16x16, HighbdHPredictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD45Predictor4x4, HighbdD45Predictor8x8, HighbdD45Predictor16x16, HighbdD45Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD135Predictor4x4, HighbdD135Predictor8x8, HighbdD135Predictor16x16,
|
||||
HighbdD135Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD117Predictor4x4, HighbdD117Predictor8x8, HighbdD117Predictor16x16,
|
||||
HighbdD117Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD153Predictor4x4, HighbdD153Predictor8x8, HighbdD153Predictor16x16,
|
||||
HighbdD153Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD207Predictor4x4, HighbdD207Predictor8x8, HighbdD207Predictor16x16,
|
||||
HighbdD207Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD63Predictor4x4, HighbdD63Predictor8x8, HighbdD63Predictor16x16, HighbdD63Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdTmPredictor4x4, HighbdTmPredictor8x8, HighbdTmPredictor16x16, HighbdTmPredictor32x32
|
||||
}
|
||||
};
|
||||
private static readonly unsafe IntraHighPredFn[][] _predHigh =
|
||||
[
|
||||
[null, null, null, null],
|
||||
[
|
||||
HighbdVPredictor4X4, HighbdVPredictor8X8, HighbdVPredictor16X16, HighbdVPredictor32X32
|
||||
],
|
||||
[
|
||||
HighbdHPredictor4X4, HighbdHPredictor8X8, HighbdHPredictor16X16, HighbdHPredictor32X32
|
||||
],
|
||||
[
|
||||
HighbdD45Predictor4X4, HighbdD45Predictor8X8, HighbdD45Predictor16X16, HighbdD45Predictor32X32
|
||||
],
|
||||
[
|
||||
HighbdD135Predictor4X4, HighbdD135Predictor8X8, HighbdD135Predictor16X16,
|
||||
HighbdD135Predictor32X32
|
||||
],
|
||||
[
|
||||
HighbdD117Predictor4X4, HighbdD117Predictor8X8, HighbdD117Predictor16X16,
|
||||
HighbdD117Predictor32X32
|
||||
],
|
||||
[
|
||||
HighbdD153Predictor4X4, HighbdD153Predictor8X8, HighbdD153Predictor16X16,
|
||||
HighbdD153Predictor32X32
|
||||
],
|
||||
[
|
||||
HighbdD207Predictor4X4, HighbdD207Predictor8X8, HighbdD207Predictor16X16,
|
||||
HighbdD207Predictor32X32
|
||||
],
|
||||
[
|
||||
HighbdD63Predictor4X4, HighbdD63Predictor8X8, HighbdD63Predictor16X16, HighbdD63Predictor32X32
|
||||
],
|
||||
[
|
||||
HighbdTmPredictor4X4, HighbdTmPredictor8X8, HighbdTmPredictor16X16, HighbdTmPredictor32X32
|
||||
]
|
||||
];
|
||||
|
||||
private static readonly unsafe IntraHighPredFn[][][] DcPredHigh =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDc128Predictor4x4, HighbdDc128Predictor8x8, HighbdDc128Predictor16x16,
|
||||
HighbdDc128Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDcTopPredictor4x4, HighbdDcTopPredictor8x8, HighbdDcTopPredictor16x16,
|
||||
HighbdDcTopPredictor32x32
|
||||
}
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDcLeftPredictor4x4, HighbdDcLeftPredictor8x8, HighbdDcLeftPredictor16x16,
|
||||
HighbdDcLeftPredictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDcPredictor4x4, HighbdDcPredictor8x8, HighbdDcPredictor16x16,
|
||||
HighbdDcPredictor32x32
|
||||
}
|
||||
}
|
||||
};
|
||||
private static readonly unsafe IntraHighPredFn[][][] _dcPredHigh =
|
||||
[
|
||||
[
|
||||
[
|
||||
HighbdDc128Predictor4X4, HighbdDc128Predictor8X8, HighbdDc128Predictor16X16,
|
||||
HighbdDc128Predictor32X32
|
||||
],
|
||||
[
|
||||
HighbdDcTopPredictor4X4, HighbdDcTopPredictor8X8, HighbdDcTopPredictor16X16,
|
||||
HighbdDcTopPredictor32X32
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
HighbdDcLeftPredictor4X4, HighbdDcLeftPredictor8X8, HighbdDcLeftPredictor16X16,
|
||||
HighbdDcLeftPredictor32X32
|
||||
],
|
||||
[
|
||||
HighbdDcPredictor4X4, HighbdDcPredictor8X8, HighbdDcPredictor16X16,
|
||||
HighbdDcPredictor32X32
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
private static unsafe void BuildIntraPredictorsHigh(
|
||||
ref MacroBlockD xd,
|
||||
@@ -371,11 +351,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// Predict
|
||||
if (mode == PredictionMode.DcPred)
|
||||
{
|
||||
DcPredHigh[leftAvailable][upAvailable][(int)txSize](dst, dstStride, constAboveRow, leftCol, xd.Bd);
|
||||
_dcPredHigh[leftAvailable][upAvailable][(int)txSize](dst, dstStride, constAboveRow, leftCol, xd.Bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
PredHigh[(int)mode][(int)txSize](dst, dstStride, constAboveRow, leftCol, xd.Bd);
|
||||
_predHigh[(int)mode][(int)txSize](dst, dstStride, constAboveRow, leftCol, xd.Bd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,11 +568,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// Predict
|
||||
if (mode == PredictionMode.DcPred)
|
||||
{
|
||||
DcPred[leftAvailable][upAvailable][(int)txSize](dst, dstStride, constAboveRow, leftCol);
|
||||
_dcPred[leftAvailable][upAvailable][(int)txSize](dst, dstStride, constAboveRow, leftCol);
|
||||
}
|
||||
else
|
||||
{
|
||||
Pred[(int)mode][(int)txSize](dst, dstStride, constAboveRow, leftCol);
|
||||
_pred[(int)mode][(int)txSize](dst, dstStride, constAboveRow, leftCol);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
{
|
||||
internal enum BlockSize
|
||||
{
|
||||
Block4x4,
|
||||
Block4x8,
|
||||
Block8x4,
|
||||
Block8x8,
|
||||
Block8x16,
|
||||
Block16x8,
|
||||
Block16x16,
|
||||
Block16x32,
|
||||
Block32x16,
|
||||
Block32x32,
|
||||
Block32x64,
|
||||
Block64x32,
|
||||
Block64x64,
|
||||
Block4X4,
|
||||
Block4X8,
|
||||
Block8X4,
|
||||
Block8X8,
|
||||
Block8X16,
|
||||
Block16X8,
|
||||
Block16X16,
|
||||
Block16X32,
|
||||
Block32X16,
|
||||
Block32X32,
|
||||
Block32X64,
|
||||
Block64X32,
|
||||
Block64X64,
|
||||
BlockSizes,
|
||||
BlockInvalid = BlockSizes
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
{
|
||||
public Array4<ulong> LeftY;
|
||||
public Array4<ulong> AboveY;
|
||||
public ulong Int4x4Y;
|
||||
public ulong Int4X4Y;
|
||||
public Array4<ushort> LeftUv;
|
||||
public Array4<ushort> AboveUv;
|
||||
public ushort Int4x4Uv;
|
||||
public ushort Int4X4Uv;
|
||||
public Array64<byte> LflY;
|
||||
}
|
||||
}
|
||||
@@ -29,12 +29,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
public PredictionMode GetYMode(int block)
|
||||
{
|
||||
return SbType < BlockSize.Block8x8 ? Bmi[block].Mode : Mode;
|
||||
return SbType < BlockSize.Block8X8 ? Bmi[block].Mode : Mode;
|
||||
}
|
||||
|
||||
public TxSize GetUvTxSize(ref MacroBlockDPlane pd)
|
||||
{
|
||||
Debug.Assert(SbType < BlockSize.Block8x8 ||
|
||||
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,17 +49,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
return RefFrame[1] > Constants.IntraFrame;
|
||||
}
|
||||
|
||||
private static readonly int[][] IdxNColumnToSubblock =
|
||||
{
|
||||
new[] { 1, 2 }, new[] { 1, 3 }, new[] { 3, 2 }, new[] { 3, 3 }
|
||||
};
|
||||
private static readonly int[][] _idxNColumnToSubblock =
|
||||
[
|
||||
[1, 2], [1, 3], [3, 2], [3, 3]
|
||||
];
|
||||
|
||||
// This function returns either the appropriate sub block or block's mv
|
||||
// on whether the block_size < 8x8 and we have check_sub_blocks set.
|
||||
public Mv GetSubBlockMv(int whichMv, int searchCol, int blockIdx)
|
||||
{
|
||||
return blockIdx >= 0 && SbType < BlockSize.Block8x8
|
||||
? Bmi[IdxNColumnToSubblock[blockIdx][searchCol == 0 ? 1 : 0]].Mv[whichMv]
|
||||
return blockIdx >= 0 && SbType < BlockSize.Block8X8
|
||||
? Bmi[_idxNColumnToSubblock[blockIdx][searchCol == 0 ? 1 : 0]].Mv[whichMv]
|
||||
: Mv[whichMv];
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
public short Row;
|
||||
public short Col;
|
||||
|
||||
private static ReadOnlySpan<byte> LogInBase2 => new byte[]
|
||||
{
|
||||
private static ReadOnlySpan<byte> LogInBase2 =>
|
||||
[
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
@@ -42,12 +42,12 @@ 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, 10
|
||||
};
|
||||
];
|
||||
|
||||
public bool UseHp()
|
||||
{
|
||||
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 JointVertical(MvJointType type)
|
||||
|
||||
@@ -38,96 +38,85 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
int h,
|
||||
int bd);
|
||||
|
||||
private static readonly unsafe ConvolveFn[][][] PredictX16Y16 =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[] { ConvolveCopy, ConvolveAvg },
|
||||
new ConvolveFn[] { Convolve8Vert, Convolve8AvgVert }
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[] { Convolve8Horiz, Convolve8AvgHoriz },
|
||||
new ConvolveFn[] { Convolve8, Convolve8Avg }
|
||||
}
|
||||
};
|
||||
private static readonly unsafe ConvolveFn[][][] _predictX16Y16 =
|
||||
[
|
||||
[
|
||||
[ConvolveCopy, ConvolveAvg],
|
||||
[Convolve8Vert, Convolve8AvgVert]
|
||||
],
|
||||
[
|
||||
[Convolve8Horiz, Convolve8AvgHoriz],
|
||||
[Convolve8, Convolve8Avg]
|
||||
]
|
||||
];
|
||||
|
||||
private static readonly unsafe ConvolveFn[][][] PredictX16 =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new ConvolveFn[] { ScaledVert, ScaledAvgVert }, new ConvolveFn[] { ScaledVert, ScaledAvgVert }
|
||||
},
|
||||
new[] { new ConvolveFn[] { Scaled2D, ScaledAvg2D }, new ConvolveFn[] { Scaled2D, ScaledAvg2D } }
|
||||
};
|
||||
private static readonly unsafe ConvolveFn[][][] _predictX16 =
|
||||
[
|
||||
[
|
||||
[ScaledVert, ScaledAvgVert], [ScaledVert, ScaledAvgVert]
|
||||
],
|
||||
[[Scaled2D, ScaledAvg2D], [Scaled2D, ScaledAvg2D]]
|
||||
];
|
||||
|
||||
private static readonly unsafe ConvolveFn[][][] PredictY16 =
|
||||
{
|
||||
new[] { new ConvolveFn[] { ScaledHoriz, ScaledAvgHoriz }, new ConvolveFn[] { Scaled2D, ScaledAvg2D } },
|
||||
new[] { new ConvolveFn[] { ScaledHoriz, ScaledAvgHoriz }, new ConvolveFn[] { Scaled2D, ScaledAvg2D } }
|
||||
};
|
||||
private static readonly unsafe ConvolveFn[][][] _predictY16 =
|
||||
[
|
||||
[[ScaledHoriz, ScaledAvgHoriz], [Scaled2D, ScaledAvg2D]],
|
||||
[[ScaledHoriz, ScaledAvgHoriz], [Scaled2D, ScaledAvg2D]]
|
||||
];
|
||||
|
||||
private static readonly unsafe ConvolveFn[][][] Predict =
|
||||
{
|
||||
new[] { new ConvolveFn[] { Scaled2D, ScaledAvg2D }, new ConvolveFn[] { Scaled2D, ScaledAvg2D } },
|
||||
new[] { new ConvolveFn[] { Scaled2D, ScaledAvg2D }, new ConvolveFn[] { Scaled2D, ScaledAvg2D } }
|
||||
};
|
||||
private static readonly unsafe ConvolveFn[][][] _predict =
|
||||
[
|
||||
[[Scaled2D, ScaledAvg2D], [Scaled2D, ScaledAvg2D]],
|
||||
[[Scaled2D, ScaledAvg2D], [Scaled2D, ScaledAvg2D]]
|
||||
];
|
||||
|
||||
private static readonly unsafe HighbdConvolveFn[][][] HighbdPredictX16Y16 =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[] { HighbdConvolveCopy, HighbdConvolveAvg },
|
||||
new HighbdConvolveFn[] { HighbdConvolve8Vert, HighbdConvolve8AvgVert }
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[] { HighbdConvolve8Horiz, HighbdConvolve8AvgHoriz },
|
||||
new HighbdConvolveFn[] { HighbdConvolve8, HighbdConvolve8Avg }
|
||||
}
|
||||
};
|
||||
private static readonly unsafe HighbdConvolveFn[][][] _highbdPredictX16Y16 =
|
||||
[
|
||||
[
|
||||
[HighbdConvolveCopy, HighbdConvolveAvg],
|
||||
[HighbdConvolve8Vert, HighbdConvolve8AvgVert]
|
||||
],
|
||||
[
|
||||
[HighbdConvolve8Horiz, HighbdConvolve8AvgHoriz],
|
||||
[HighbdConvolve8, HighbdConvolve8Avg]
|
||||
]
|
||||
];
|
||||
|
||||
private static readonly unsafe HighbdConvolveFn[][][] HighbdPredictX16 =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[] { HighbdConvolve8Vert, HighbdConvolve8AvgVert },
|
||||
new HighbdConvolveFn[] { HighbdConvolve8Vert, HighbdConvolve8AvgVert }
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[] { HighbdConvolve8, HighbdConvolve8Avg },
|
||||
new HighbdConvolveFn[] { HighbdConvolve8, HighbdConvolve8Avg }
|
||||
}
|
||||
};
|
||||
private static readonly unsafe HighbdConvolveFn[][][] _highbdPredictX16 =
|
||||
[
|
||||
[
|
||||
[HighbdConvolve8Vert, HighbdConvolve8AvgVert],
|
||||
[HighbdConvolve8Vert, HighbdConvolve8AvgVert]
|
||||
],
|
||||
[
|
||||
[HighbdConvolve8, HighbdConvolve8Avg],
|
||||
[HighbdConvolve8, HighbdConvolve8Avg]
|
||||
]
|
||||
];
|
||||
|
||||
private static readonly unsafe HighbdConvolveFn[][][] HighbdPredictY16 =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[] { HighbdConvolve8Horiz, HighbdConvolve8AvgHoriz },
|
||||
new HighbdConvolveFn[] { HighbdConvolve8, HighbdConvolve8Avg }
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[] { HighbdConvolve8Horiz, HighbdConvolve8AvgHoriz },
|
||||
new HighbdConvolveFn[] { HighbdConvolve8, HighbdConvolve8Avg }
|
||||
}
|
||||
};
|
||||
private static readonly unsafe HighbdConvolveFn[][][] _highbdPredictY16 =
|
||||
[
|
||||
[
|
||||
[HighbdConvolve8Horiz, HighbdConvolve8AvgHoriz],
|
||||
[HighbdConvolve8, HighbdConvolve8Avg]
|
||||
],
|
||||
[
|
||||
[HighbdConvolve8Horiz, HighbdConvolve8AvgHoriz],
|
||||
[HighbdConvolve8, HighbdConvolve8Avg]
|
||||
]
|
||||
];
|
||||
|
||||
private static readonly unsafe HighbdConvolveFn[][][] HighbdPredict =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[] { HighbdConvolve8, HighbdConvolve8Avg },
|
||||
new HighbdConvolveFn[] { HighbdConvolve8, HighbdConvolve8Avg }
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new HighbdConvolveFn[] { HighbdConvolve8, HighbdConvolve8Avg },
|
||||
new HighbdConvolveFn[] { HighbdConvolve8, HighbdConvolve8Avg }
|
||||
}
|
||||
};
|
||||
private static readonly unsafe HighbdConvolveFn[][][] _highbdPredict =
|
||||
[
|
||||
[
|
||||
[HighbdConvolve8, HighbdConvolve8Avg],
|
||||
[HighbdConvolve8, HighbdConvolve8Avg]
|
||||
],
|
||||
[
|
||||
[HighbdConvolve8, HighbdConvolve8Avg],
|
||||
[HighbdConvolve8, HighbdConvolve8Avg]
|
||||
]
|
||||
];
|
||||
|
||||
public int XScaleFp; // Horizontal fixed point scale factor
|
||||
public int YScaleFp; // Vertical fixed point scale factor
|
||||
@@ -166,13 +155,13 @@ 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,
|
||||
_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,
|
||||
_predictX16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w,
|
||||
h);
|
||||
}
|
||||
}
|
||||
@@ -181,13 +170,13 @@ 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,
|
||||
_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,13 +204,13 @@ 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,
|
||||
_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,
|
||||
_highbdPredictX16[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys,
|
||||
w, h, bd);
|
||||
}
|
||||
}
|
||||
@@ -230,13 +219,13 @@ 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,
|
||||
_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,
|
||||
_highbdPredict[horiz][vert][avg](src, srcStride, dst, dstStride, kernel, subpelX, xs, subpelY, ys, w,
|
||||
h, bd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
public const int PredictionProbs = 3;
|
||||
|
||||
private static readonly int[] SegFeatureDataSigned = { 1, 1, 0, 0 };
|
||||
private static readonly int[] SegFeatureDataMax = { 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;
|
||||
@@ -48,21 +48,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;
|
||||
|
||||
@@ -65,23 +65,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
public Surface(int width, int height)
|
||||
{
|
||||
const int border = 32;
|
||||
const int ssX = 1;
|
||||
const int ssY = 1;
|
||||
const bool highbd = false;
|
||||
const int Border = 32;
|
||||
const int SsX = 1;
|
||||
const int SsY = 1;
|
||||
const bool Highbd = false;
|
||||
|
||||
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));
|
||||
|
||||
nint pointer = Marshal.AllocHGlobal(frameSize);
|
||||
_pointer = pointer;
|
||||
@@ -90,8 +90,8 @@ 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;
|
||||
@@ -101,7 +101,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
return new ArrayPtr<byte>(pointer + start + border, size - border);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -146,8 +146,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
if (cb != null)
|
||||
{
|
||||
const int alignAddrExtraSize = 31;
|
||||
ulong externalFrameSize = frameSize + alignAddrExtraSize;
|
||||
const int AlignAddrExtraSize = 31;
|
||||
ulong externalFrameSize = frameSize + AlignAddrExtraSize;
|
||||
|
||||
Debug.Assert(!fb.IsNull);
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
{
|
||||
public enum TxMode
|
||||
{
|
||||
Only4x4, // Only 4x4 transform used
|
||||
Allow8x8, // Allow block transform size up to 8x8
|
||||
Allow16x16, // Allow block transform size up to 16x16
|
||||
Allow32x32, // Allow block transform size up to 32x32
|
||||
Only4X4, // Only 4x4 transform used
|
||||
Allow8X8, // Allow block transform size up to 8x8
|
||||
Allow16X16, // Allow block transform size up to 16x16
|
||||
Allow32X32, // Allow block transform size up to 32x32
|
||||
TxModeSelect, // Transform specified for each block
|
||||
TxModes
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
{
|
||||
public enum TxSize
|
||||
{
|
||||
Tx4x4, // 4x4 transform
|
||||
Tx8x8, // 8x8 transform
|
||||
Tx16x16, // 16x16 transform
|
||||
Tx32x32, // 32x32 transform
|
||||
Tx4X4, // 4x4 transform
|
||||
Tx8X8, // 8x8 transform
|
||||
Tx16X16, // 16x16 transform
|
||||
Tx32X32, // 32x32 transform
|
||||
TxSizes
|
||||
}
|
||||
}
|
||||
@@ -845,30 +845,30 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
if (TxMode == TxMode.TxModeSelect)
|
||||
{
|
||||
Array1<Array2<uint>> branchCt8x8P = new();
|
||||
Array2<Array2<uint>> branchCt16x16P = new();
|
||||
Array3<Array2<uint>> branchCt32x32P = new();
|
||||
Array1<Array2<uint>> branchCt8X8P = new();
|
||||
Array2<Array2<uint>> branchCt16X16P = new();
|
||||
Array3<Array2<uint>> branchCt32X32P = new();
|
||||
|
||||
for (int i = 0; i < EntropyMode.TxSizeContexts; ++i)
|
||||
{
|
||||
EntropyMode.TxCountsToBranchCounts8x8(counts.Tx8x8[i].AsSpan(), ref branchCt8x8P);
|
||||
EntropyMode.TxCountsToBranchCounts8X8(counts.Tx8x8[i].AsSpan(), ref branchCt8X8P);
|
||||
for (int j = 0; j < (int)TxSize.TxSizes - 3; ++j)
|
||||
{
|
||||
fc.Tx8x8Prob[i][j] = Prob.ModeMvMergeProbs(preFc.Tx8x8Prob[i][j], ref branchCt8x8P[j]);
|
||||
fc.Tx8x8Prob[i][j] = Prob.ModeMvMergeProbs(preFc.Tx8x8Prob[i][j], ref branchCt8X8P[j]);
|
||||
}
|
||||
|
||||
EntropyMode.TxCountsToBranchCounts16x16(counts.Tx16x16[i].AsSpan(), ref branchCt16x16P);
|
||||
EntropyMode.TxCountsToBranchCounts16X16(counts.Tx16x16[i].AsSpan(), ref branchCt16X16P);
|
||||
for (int j = 0; j < (int)TxSize.TxSizes - 2; ++j)
|
||||
{
|
||||
fc.Tx16x16Prob[i][j] =
|
||||
Prob.ModeMvMergeProbs(preFc.Tx16x16Prob[i][j], ref branchCt16x16P[j]);
|
||||
Prob.ModeMvMergeProbs(preFc.Tx16x16Prob[i][j], ref branchCt16X16P[j]);
|
||||
}
|
||||
|
||||
EntropyMode.TxCountsToBranchCounts32x32(counts.Tx32x32[i].AsSpan(), ref branchCt32x32P);
|
||||
EntropyMode.TxCountsToBranchCounts32X32(counts.Tx32x32[i].AsSpan(), ref branchCt32X32P);
|
||||
for (int j = 0; j < (int)TxSize.TxSizes - 1; ++j)
|
||||
{
|
||||
fc.Tx32x32Prob[i][j] =
|
||||
Prob.ModeMvMergeProbs(preFc.Tx32x32Prob[i][j], ref branchCt32x32P[j]);
|
||||
Prob.ModeMvMergeProbs(preFc.Tx32x32Prob[i][j], ref branchCt32X32P[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -900,7 +900,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
countSat = Entropy.CoefCountSat;
|
||||
}
|
||||
|
||||
for (t = (int)TxSize.Tx4x4; t <= (int)TxSize.Tx32x32; t++)
|
||||
for (t = (int)TxSize.Tx4X4; t <= (int)TxSize.Tx32X32; t++)
|
||||
{
|
||||
AdaptCoefProbs(t, countSat, updateFactor);
|
||||
}
|
||||
@@ -990,10 +990,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
public void DefaultCoefProbs()
|
||||
{
|
||||
Entropy.CopyProbs(ref Fc.Value.CoefProbs[(int)TxSize.Tx4x4], Entropy.DefaultCoefProbs4x4);
|
||||
Entropy.CopyProbs(ref Fc.Value.CoefProbs[(int)TxSize.Tx8x8], Entropy.DefaultCoefProbs8x8);
|
||||
Entropy.CopyProbs(ref Fc.Value.CoefProbs[(int)TxSize.Tx16x16], Entropy.DefaultCoefProbs16x16);
|
||||
Entropy.CopyProbs(ref Fc.Value.CoefProbs[(int)TxSize.Tx32x32], Entropy.DefaultCoefProbs32x32);
|
||||
Entropy.CopyProbs(ref Fc.Value.CoefProbs[(int)TxSize.Tx4X4], Entropy.DefaultCoefProbs4X4);
|
||||
Entropy.CopyProbs(ref Fc.Value.CoefProbs[(int)TxSize.Tx8X8], Entropy.DefaultCoefProbs8X8);
|
||||
Entropy.CopyProbs(ref Fc.Value.CoefProbs[(int)TxSize.Tx16X16], Entropy.DefaultCoefProbs16X16);
|
||||
Entropy.CopyProbs(ref Fc.Value.CoefProbs[(int)TxSize.Tx32X32], Entropy.DefaultCoefProbs32X32);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,38 +62,38 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
}
|
||||
}
|
||||
|
||||
byte[][] KfPartitionProbs =
|
||||
{
|
||||
byte[][] kfPartitionProbs =
|
||||
[
|
||||
// 8x8 . 4x4
|
||||
new byte[] { 158, 97, 94 }, // a/l both not split
|
||||
new byte[] { 93, 24, 99 }, // a split, l not split
|
||||
new byte[] { 85, 119, 44 }, // l split, a not split
|
||||
new byte[] { 62, 59, 67 }, // a/l both split
|
||||
[158, 97, 94], // a/l both not split
|
||||
[93, 24, 99], // a split, l not split
|
||||
[85, 119, 44], // l split, a not split
|
||||
[62, 59, 67], // a/l both split
|
||||
|
||||
// 16x16 . 8x8
|
||||
new byte[] { 149, 53, 53 }, // a/l both not split
|
||||
new byte[] { 94, 20, 48 }, // a split, l not split
|
||||
new byte[] { 83, 53, 24 }, // l split, a not split
|
||||
new byte[] { 52, 18, 18 }, // a/l both split
|
||||
[149, 53, 53], // a/l both not split
|
||||
[94, 20, 48], // a split, l not split
|
||||
[83, 53, 24], // l split, a not split
|
||||
[52, 18, 18], // a/l both split
|
||||
|
||||
// 32x32 . 16x16
|
||||
new byte[] { 150, 40, 39 }, // a/l both not split
|
||||
new byte[] { 78, 12, 26 }, // a split, l not split
|
||||
new byte[] { 67, 33, 11 }, // l split, a not split
|
||||
new byte[] { 24, 7, 5 }, // a/l both split
|
||||
[150, 40, 39], // a/l both not split
|
||||
[78, 12, 26], // a split, l not split
|
||||
[67, 33, 11], // l split, a not split
|
||||
[24, 7, 5], // a/l both split
|
||||
|
||||
// 64x64 . 32x32
|
||||
new byte[] { 174, 35, 49 }, // a/l both not split
|
||||
new byte[] { 68, 11, 27 }, // a split, l not split
|
||||
new byte[] { 57, 15, 9 }, // l split, a not split
|
||||
new byte[] { 12, 3, 3 } // a/l both split
|
||||
};
|
||||
[174, 35, 49], // a/l both not split
|
||||
[68, 11, 27], // a split, l not split
|
||||
[57, 15, 9], // l split, a not split
|
||||
[12, 3, 3] // a/l both split
|
||||
];
|
||||
|
||||
for (int i = 0; i < KfPartitionProbs.Length; i++)
|
||||
for (int i = 0; i < kfPartitionProbs.Length; i++)
|
||||
{
|
||||
for (int j = 0; j < KfPartitionProbs[i].Length; j++)
|
||||
for (int j = 0; j < kfPartitionProbs[i].Length; j++)
|
||||
{
|
||||
cm.Fc.Value.KfPartitionProb[i][j] = KfPartitionProbs[i][j];
|
||||
cm.Fc.Value.KfPartitionProb[i][j] = kfPartitionProbs[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
Array8<uint> frameSizes = new();
|
||||
int frameCount = 0;
|
||||
|
||||
res = Types.Decoder.ParseSuperframeIndex(data, (ulong)data.Length, ref frameSizes, out frameCount);
|
||||
res = Decoder.ParseSuperframeIndex(data, (ulong)data.Length, ref frameSizes, out frameCount);
|
||||
if (res != CodecErr.Ok)
|
||||
{
|
||||
return res;
|
||||
@@ -322,7 +322,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
// Account for suboptimal termination by the encoder.
|
||||
while (dataStart.Length != 0)
|
||||
{
|
||||
byte marker = Types.Decoder.ReadMarker(dataStart);
|
||||
byte marker = Decoder.ReadMarker(dataStart);
|
||||
if (marker != 0)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
|
||||
{
|
||||
List<BrowserOutput> result =
|
||||
[
|
||||
new BrowserOutput(BrowserOutputType.ExitReason, (uint)WebExitReason.ExitButton)
|
||||
new(BrowserOutputType.ExitReason, (uint)WebExitReason.ExitButton)
|
||||
];
|
||||
|
||||
_normalSession.Push(BuildResponseNew(result));
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Ryujinx.HLE.HOS
|
||||
private readonly ICpuContext _cpuContext;
|
||||
private T _memoryManager;
|
||||
|
||||
public IVirtualMemoryManager AddressSpace => _memoryManager;
|
||||
public IVirtualMemoryManagerTracked AddressSpace => _memoryManager;
|
||||
|
||||
public ulong AddressSpaceSize { get; }
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Ryujinx.HLE.HOS
|
||||
internal ServerBase TimeServer { get; private set; }
|
||||
internal ServerBase ViServer { get; private set; }
|
||||
internal ServerBase ViServerM { get; private set; }
|
||||
internal ServerBase ViServerS { get; private set; }
|
||||
internal ViServer ViServerS { get; private set; }
|
||||
internal ServerBase LdnServer { get; private set; }
|
||||
|
||||
internal KSharedMemory HidSharedMem { get; private set; }
|
||||
@@ -254,7 +254,7 @@ namespace Ryujinx.HLE.HOS
|
||||
TimeServer = new ServerBase(KernelContext, "TimeServer");
|
||||
ViServer = new ServerBase(KernelContext, "ViServerU");
|
||||
ViServerM = new ServerBase(KernelContext, "ViServerM");
|
||||
ViServerS = new ServerBase(KernelContext, "ViServerS");
|
||||
ViServerS = new ViServer(KernelContext, "ViServerS");
|
||||
LdnServer = new ServerBase(KernelContext, "LdnServer");
|
||||
|
||||
StartNewServices();
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
{
|
||||
interface IProcessContext : IDisposable
|
||||
{
|
||||
IVirtualMemoryManager AddressSpace { get; }
|
||||
IVirtualMemoryManagerTracked AddressSpace { get; }
|
||||
|
||||
ulong AddressSpaceSize { get; }
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
|
||||
private IProcessContextFactory _contextFactory;
|
||||
public IProcessContext Context { get; private set; }
|
||||
public IVirtualMemoryManager CpuMemory => Context.AddressSpace;
|
||||
public IVirtualMemoryManagerTracked CpuMemory => Context.AddressSpace;
|
||||
|
||||
public HleProcessDebugger Debugger { get; private set; }
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
{
|
||||
class ProcessContext : IProcessContext
|
||||
{
|
||||
public IVirtualMemoryManager AddressSpace { get; }
|
||||
public IVirtualMemoryManagerTracked AddressSpace { get; }
|
||||
|
||||
public ulong AddressSpaceSize { get; }
|
||||
|
||||
public ProcessContext(IVirtualMemoryManager asManager, ulong addressSpaceSize)
|
||||
public ProcessContext(IVirtualMemoryManagerTracked asManager, ulong addressSpaceSize)
|
||||
{
|
||||
AddressSpace = asManager;
|
||||
AddressSpaceSize = addressSpaceSize;
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.OverlayAppletProxy;
|
||||
using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService
|
||||
{
|
||||
class IOverlayAppletProxy : IpcService
|
||||
{
|
||||
private readonly ulong _pid;
|
||||
|
||||
public IOverlayAppletProxy(ulong pid)
|
||||
{
|
||||
_pid = pid;
|
||||
}
|
||||
|
||||
[CommandCmif(0)]
|
||||
// GetCommonStateGetter() -> object<nn::am::service::ICommonStateGetter>
|
||||
public ResultCode GetCommonStateGetter(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new ICommonStateGetter(context));
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(1)]
|
||||
// GetSelfController() -> object<nn::am::service::ISelfController>
|
||||
public ResultCode GetSelfController(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new ISelfController(context, _pid));
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(2)]
|
||||
// GetWindowController() -> object<nn::am::service::IWindowController>
|
||||
public ResultCode GetWindowController(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new IWindowController(_pid));
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(3)]
|
||||
// GetAudioController() -> object<nn::am::service::IAudioController>
|
||||
public ResultCode GetAudioController(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new IAudioController());
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(4)]
|
||||
// GetDisplayController() -> object<nn::am::service::IDisplayController>
|
||||
public ResultCode GetDisplayController(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new IDisplayController(context));
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(11)]
|
||||
// GetLibraryAppletCreator() -> object<nn::am::service::ILibraryAppletCreator>
|
||||
public ResultCode GetLibraryAppletCreator(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new ILibraryAppletCreator());
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(20)]
|
||||
// GetOverlayFunctions() -> object<nn::am::service::IOverlayFunctions>
|
||||
public ResultCode GetOverlayFunctions(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new IOverlayFunctions(context.Device.System));
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(21)]
|
||||
// GetAppletCommonFunctions() -> object<nn::am::service::IAppletCommonFunctions>
|
||||
public ResultCode GetAppletCommonFunctions(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new IAppletCommonFunctions());
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(23)]
|
||||
// GetGlobalStateController() -> object<nn::am::service::IGlobalStateController>
|
||||
public ResultCode GetGlobalStateController(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new IGlobalStateController());
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(1000)]
|
||||
// GetDebugFunctions() -> object<nn::am::service::IDebugFunctions>
|
||||
public ResultCode GetDebugFunctions(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new IDebugFunctions());
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
using LibHac.Util;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Ipc;
|
||||
using Ryujinx.Horizon.Common;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.OverlayAppletProxy
|
||||
{
|
||||
class IOverlayFunctions : IpcService
|
||||
{
|
||||
|
||||
public IOverlayFunctions(Horizon system)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandCmif(0)]
|
||||
// BeginToWatchShortHomeButtonMessage()
|
||||
public ResultCode BeginToWatchShortHomeButtonMessage(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(1)]
|
||||
// EndToWatchShortHomeButtonMessage()
|
||||
public ResultCode EndToWatchShortHomeButtonMessage(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(2)]
|
||||
// GetApplicationIdForLogo() -> nn::ncm::ApplicationId
|
||||
public ResultCode GetApplicationIdForLogo(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
context.ResponseData.Write(0L);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(3)]
|
||||
// SetGpuTimeSliceBoost(u64)
|
||||
public ResultCode SetGpuTimeSliceBoost(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(4)]
|
||||
// SetAutoSleepTimeAndDimmingTimeEnabled(u8)
|
||||
public ResultCode SetAutoSleepTimeAndDimmingTimeEnabled(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(5)]
|
||||
// TerminateApplicationAndSetReason(u32)
|
||||
public ResultCode TerminateApplicationAndSetReason(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(6)]
|
||||
// SetScreenShotPermissionGlobally(u8)
|
||||
public ResultCode SetScreenShotPermissionGlobally(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(10)]
|
||||
// StartShutdownSequenceForOverlay()
|
||||
public ResultCode StartShutdownSequenceForOverlay(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(11)]
|
||||
// StartRebootSequenceForOverlay()
|
||||
public ResultCode StartRebootSequenceForOverlay(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(20)]
|
||||
// SetHandlingHomeButtonShortPressedEnabled(u8)
|
||||
public ResultCode SetHandlingHomeButtonShortPressedEnabled(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(21)]
|
||||
// SetHandlingTouchScreenInputEnabled(u8)
|
||||
public ResultCode SetHandlingTouchScreenInputEnabled(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(30)]
|
||||
// SetHealthWarningShowingState(u8)
|
||||
public ResultCode SetHealthWarningShowingState(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(31)]
|
||||
// IsHealthWarningRequired() -> bool
|
||||
public ResultCode IsHealthWarningRequired(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
context.ResponseData.Write(false);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(90)]
|
||||
// SetRequiresGpuResourceUse(u8)
|
||||
public ResultCode SetRequiresGpuResourceUse(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(101)]
|
||||
// BeginToObserveHidInputForDevelop()
|
||||
public ResultCode BeginToObserveHidInputForDevelop(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceAm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,5 +102,34 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(22)]
|
||||
// AcquireLastApplicationCaptureSharedBuffer() -> (b8, u32)
|
||||
public ResultCode AcquireLastApplicationCaptureSharedBuffer(ServiceCtx context)
|
||||
{
|
||||
context.ResponseData.Write(1);
|
||||
context.ResponseData.Write(context.Device.System.ViServerS.GetApplicationLastPresentedFrameHandle(context.Device.Gpu));
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(26)]
|
||||
|
||||
// AcquireCallerAppletCaptureSharedBuffer() -> (b8, u32)
|
||||
public ResultCode AcquireCallerAppletCaptureSharedBuffer(ServiceCtx context)
|
||||
{
|
||||
// TODO: How does the handling for applets differ from the one for applications?
|
||||
context.ResponseData.Write(1);
|
||||
context.ResponseData.Write(context.Device.System.ViServerS.GetApplicationLastPresentedFrameHandle(context.Device.Gpu));
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(27)]
|
||||
public ResultCode ReleaseCallerAppletCaptureSharedBuffer(ServiceCtx context)
|
||||
{
|
||||
context.ResponseData.Write(2);
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,6 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
||||
public ResultCode CreateManagedDisplayLayer(ServiceCtx context)
|
||||
{
|
||||
context.Device.System.SurfaceFlinger.CreateLayer(out long layerId, _pid);
|
||||
context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
|
||||
|
||||
context.ResponseData.Write(layerId);
|
||||
|
||||
@@ -236,18 +235,27 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
||||
// IsSystemBufferSharingEnabled()
|
||||
public ResultCode IsSystemBufferSharingEnabled(ServiceCtx context)
|
||||
{
|
||||
// NOTE: Service checks a private field and return an error if the SystemBufferSharing is disabled.
|
||||
|
||||
return ResultCode.NotImplemented;
|
||||
// TODO: Implement this once we have a way to check if we're not an AppletId.Application
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(42)] // 4.0.0+
|
||||
// GetSystemSharedLayerHandle() -> (nn::vi::fbshare::SharedBufferHandle, nn::vi::fbshare::SharedLayerHandle)
|
||||
public ResultCode GetSystemSharedLayerHandle(ServiceCtx context)
|
||||
{
|
||||
context.ResponseData.Write((ulong)context.Device.System.ViServerS.GetSharedBufferNvMapId());
|
||||
context.ResponseData.Write(context.Device.System.ViServerS.GetSharedLayerId());
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(44)] // 10.0.0+
|
||||
// CreateManagedDisplaySeparableLayer() -> (u64, u64)
|
||||
public ResultCode CreateManagedDisplaySeparableLayer(ServiceCtx context)
|
||||
{
|
||||
context.Device.System.SurfaceFlinger.CreateLayer(out long displayLayerId, _pid);
|
||||
context.Device.System.SurfaceFlinger.CreateLayer(out long recordingLayerId, _pid);
|
||||
context.Device.System.SurfaceFlinger.SetRenderLayer(displayLayerId);
|
||||
//context.Device.System.SurfaceFlinger.SetRenderLayer(displayLayerId);
|
||||
|
||||
context.ResponseData.Write(displayLayerId);
|
||||
context.ResponseData.Write(recordingLayerId);
|
||||
|
||||
@@ -26,6 +26,15 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(300)]
|
||||
// OpenOverlayAppletProxy(pid, handle<copy>) -> object<nn::am::service::IOverlayAppletProxy>
|
||||
public ResultCode OpenOverlayAppletProxy(ServiceCtx context)
|
||||
{
|
||||
MakeObject(context, new IOverlayAppletProxy(context.Request.HandleDesc.PId));
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(350)]
|
||||
// OpenSystemApplicationProxy(u64, pid, handle<copy>) -> object<nn::am::service::IApplicationProxy>
|
||||
|
||||
@@ -35,6 +35,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
|
||||
public Dictionary<PlayerIndex, ConcurrentQueue<(VibrationValue, VibrationValue)>> RumbleQueues = new();
|
||||
public Dictionary<PlayerIndex, (VibrationValue, VibrationValue)> LastVibrationValues = new();
|
||||
|
||||
internal PlayerIndex LastActiveNpad { get; set; }
|
||||
|
||||
public NpadDevices(Switch device, bool active = true) : base(device, active)
|
||||
{
|
||||
@@ -384,6 +386,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
return;
|
||||
}
|
||||
|
||||
LastActiveNpad = state.PlayerId;
|
||||
|
||||
ref RingLifo<NpadCommonState> lifo = ref GetCommonStateLifo(ref currentNpad);
|
||||
|
||||
NpadCommonState newState = new()
|
||||
@@ -639,5 +643,20 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
|
||||
return rumbleQueue;
|
||||
}
|
||||
|
||||
public NpadIdType GetLastActiveNpadId()
|
||||
{
|
||||
return LastActiveNpad switch {
|
||||
PlayerIndex.Player1 => NpadIdType.Player1,
|
||||
PlayerIndex.Player2 => NpadIdType.Player2,
|
||||
PlayerIndex.Player3 => NpadIdType.Player3,
|
||||
PlayerIndex.Player4 => NpadIdType.Player4,
|
||||
PlayerIndex.Player5 => NpadIdType.Player5,
|
||||
PlayerIndex.Player6 => NpadIdType.Player6,
|
||||
PlayerIndex.Player7 => NpadIdType.Player7,
|
||||
PlayerIndex.Player8 => NpadIdType.Player8,
|
||||
_ => NpadIdType.Handheld,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,15 +24,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
// GetLastActiveNpad(u32) -> u8, u8
|
||||
public ResultCode GetLastActiveNpad(ServiceCtx context)
|
||||
{
|
||||
// TODO: RequestData seems to have garbage data, reading an extra uint seems to fix the issue.
|
||||
context.RequestData.ReadUInt32();
|
||||
context.ResponseData.Write((byte)context.Device.Hid.Npads.GetLastActiveNpadId());
|
||||
|
||||
ResultCode resultCode = GetAppletFooterUiTypeImpl(context, out AppletFooterUiType appletFooterUiType);
|
||||
|
||||
context.ResponseData.Write((byte)appletFooterUiType);
|
||||
context.ResponseData.Write((byte)0);
|
||||
|
||||
return resultCode;
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(307)]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Ipc;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
@@ -105,6 +106,26 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(6)]
|
||||
// SetRequirementPreset(u32)
|
||||
public ResultCode SetRequirementPreset(ServiceCtx context)
|
||||
{
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceNifm);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(9)]
|
||||
// SetNetworkProfileId(nn::util::Uuid)
|
||||
public ResultCode SetNetworkProfileId(ServiceCtx context)
|
||||
{
|
||||
UInt128 uuid = context.RequestData.ReadStruct<UInt128>();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceNifm, new { uuid });
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(11)]
|
||||
// SetConnectionConfirmationOption(i8)
|
||||
public ResultCode SetConnectionConfirmationOption(ServiceCtx context)
|
||||
@@ -142,5 +163,38 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(23)]
|
||||
// SetKeptInSleep(bool)
|
||||
public ResultCode SetKeptInSleep(ServiceCtx context)
|
||||
{
|
||||
bool keptInSleep = context.RequestData.ReadBoolean();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceNifm, new { keptInSleep });
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(24)]
|
||||
// RegisterSocketDescriptor(s32)
|
||||
public ResultCode RegisterSocketDescriptor(ServiceCtx context)
|
||||
{
|
||||
int socketDescriptor = context.RequestData.ReadInt32();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceNifm, new { socketDescriptor });
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(25)]
|
||||
// UnregisterSocketDescriptor(s32)
|
||||
public ResultCode UnregisterSocketDescriptor(ServiceCtx context)
|
||||
{
|
||||
int socketDescriptor = context.RequestData.ReadInt32();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceNifm, new { socketDescriptor });
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,8 +245,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
|
||||
}
|
||||
}
|
||||
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, arguments.NvMapHandle);
|
||||
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(arguments.NvMapHandle);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid NvMap handle 0x{arguments.NvMapHandle:x8}!");
|
||||
@@ -282,7 +282,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
|
||||
{
|
||||
if (_asContext.ValidateFixedBuffer(arguments.Offset, size, pageSize))
|
||||
{
|
||||
_asContext.Gmm.Map(physicalAddress, arguments.Offset, size, (PteKind)arguments.Kind);
|
||||
Map(physicalAddress, arguments.Offset, size, (PteKind)arguments.Kind, map.OwnerPid);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -301,7 +301,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
|
||||
_memoryAllocator.AllocateRange(va, size, freeAddressStartPosition);
|
||||
}
|
||||
|
||||
_asContext.Gmm.Map(physicalAddress, va, size, (PteKind)arguments.Kind);
|
||||
Map(physicalAddress, va, size, (PteKind)arguments.Kind, map.OwnerPid);
|
||||
arguments.Offset = va;
|
||||
}
|
||||
|
||||
@@ -380,8 +380,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
|
||||
ulong mapOffs = (ulong)argument.MapOffset << 16;
|
||||
PteKind kind = (PteKind)argument.Kind;
|
||||
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, nvmapHandle);
|
||||
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(nvmapHandle);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid NvMap handle 0x{nvmapHandle:x8}!");
|
||||
@@ -389,13 +389,25 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
|
||||
return NvInternalResult.InvalidInput;
|
||||
}
|
||||
|
||||
gmm.Map(mapOffs + map.Address, gpuVa, size, kind);
|
||||
Map(mapOffs + map.Address, gpuVa, size, kind, map.OwnerPid);
|
||||
}
|
||||
}
|
||||
|
||||
return NvInternalResult.Success;
|
||||
}
|
||||
|
||||
private void Map(ulong pa, ulong va, ulong size, PteKind kind, ulong ownerPid)
|
||||
{
|
||||
if (Owner == ownerPid)
|
||||
{
|
||||
_asContext.Gmm.Map(pa, va, size, kind);
|
||||
}
|
||||
else
|
||||
{
|
||||
_asContext.Gmm.MapForeign(pa, va, size, kind, ownerPid);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close() { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,8 +167,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
|
||||
|
||||
foreach (CommandBuffer commandBuffer in commandBuffers)
|
||||
{
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, commandBuffer.Mem);
|
||||
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(commandBuffer.Mem);
|
||||
|
||||
ReadOnlySpan<byte> data = _memory.GetSpan(map.Address + commandBuffer.Offset, commandBuffer.WordsCount * 4);
|
||||
|
||||
_host1xContext.Host1x.Submit(MemoryMarshal.Cast<byte, int>(data), _contextId);
|
||||
@@ -237,8 +237,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
|
||||
|
||||
foreach (ref CommandBufferHandle commandBufferEntry in commandBufferEntries)
|
||||
{
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, commandBufferEntry.MapHandle);
|
||||
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(commandBufferEntry.MapHandle);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid handle 0x{commandBufferEntry.MapHandle:x8}!");
|
||||
@@ -279,8 +279,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
|
||||
|
||||
foreach (ref CommandBufferHandle commandBufferEntry in commandBufferEntries)
|
||||
{
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, commandBufferEntry.MapHandle);
|
||||
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(commandBufferEntry.MapHandle);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid handle 0x{commandBufferEntry.MapHandle:x8}!");
|
||||
|
||||
@@ -71,8 +71,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
|
||||
uint size = BitUtils.AlignUp(arguments.Size, (uint)MemoryManager.PageSize);
|
||||
|
||||
arguments.Handle = CreateHandleFromMap(new NvMapHandle(size));
|
||||
|
||||
arguments.Handle = CreateHandleFromMap(new NvMapHandle(size) { OwnerPid = Owner });
|
||||
|
||||
Logger.Debug?.Print(LogClass.ServiceNv, $"Created map {arguments.Handle} with size 0x{size:x8}!");
|
||||
|
||||
return NvInternalResult.Success;
|
||||
@@ -80,8 +80,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
|
||||
private NvInternalResult FromId(ref NvMapFromId arguments)
|
||||
{
|
||||
NvMapHandle map = GetMapFromHandle(Owner, arguments.Id);
|
||||
|
||||
NvMapHandle map = GetMapFromHandle(arguments.Id);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid handle 0x{arguments.Handle:x8}!");
|
||||
@@ -98,8 +98,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
|
||||
private NvInternalResult Alloc(ref NvMapAlloc arguments)
|
||||
{
|
||||
NvMapHandle map = GetMapFromHandle(Owner, arguments.Handle);
|
||||
|
||||
NvMapHandle map = GetMapFromHandle(arguments.Handle);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid handle 0x{arguments.Handle:x8}!");
|
||||
@@ -152,8 +152,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
|
||||
private NvInternalResult Free(ref NvMapFree arguments)
|
||||
{
|
||||
NvMapHandle map = GetMapFromHandle(Owner, arguments.Handle);
|
||||
|
||||
NvMapHandle map = GetMapFromHandle(arguments.Handle);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid handle 0x{arguments.Handle:x8}!");
|
||||
@@ -179,8 +179,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
|
||||
private NvInternalResult Param(ref NvMapParam arguments)
|
||||
{
|
||||
NvMapHandle map = GetMapFromHandle(Owner, arguments.Handle);
|
||||
|
||||
NvMapHandle map = GetMapFromHandle(arguments.Handle);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid handle 0x{arguments.Handle:x8}!");
|
||||
@@ -217,8 +217,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
|
||||
private NvInternalResult GetId(ref NvMapGetId arguments)
|
||||
{
|
||||
NvMapHandle map = GetMapFromHandle(Owner, arguments.Handle);
|
||||
|
||||
NvMapHandle map = GetMapFromHandle(arguments.Handle);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid handle 0x{arguments.Handle:x8}!");
|
||||
@@ -237,25 +237,30 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
// _maps.TryRemove(GetOwner(), out _);
|
||||
}
|
||||
|
||||
private int CreateHandleFromMap(NvMapHandle map)
|
||||
public static int CreateMap(ulong pid, ulong address, uint size)
|
||||
{
|
||||
return CreateHandleFromMap(new NvMapHandle(size) { Address = address, OwnerPid = pid });
|
||||
}
|
||||
|
||||
private static int CreateHandleFromMap(NvMapHandle map)
|
||||
{
|
||||
return _maps.Add(map);
|
||||
}
|
||||
|
||||
private static bool DeleteMapWithHandle(ulong pid, int handle)
|
||||
private static bool DeleteMapWithHandle(int handle)
|
||||
{
|
||||
return _maps.Delete(handle) != null;
|
||||
}
|
||||
|
||||
public static void IncrementMapRefCount(ulong pid, int handle)
|
||||
{
|
||||
GetMapFromHandle(pid, handle)?.IncrementRefCount();
|
||||
GetMapFromHandle(handle)?.IncrementRefCount();
|
||||
}
|
||||
|
||||
public static bool DecrementMapRefCount(ulong pid, int handle)
|
||||
{
|
||||
NvMapHandle map = GetMapFromHandle(pid, handle);
|
||||
|
||||
NvMapHandle map = GetMapFromHandle(handle);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
return false;
|
||||
@@ -263,8 +268,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
|
||||
if (map.DecrementRefCount() <= 0)
|
||||
{
|
||||
DeleteMapWithHandle(pid, handle);
|
||||
|
||||
DeleteMapWithHandle(handle);
|
||||
|
||||
Logger.Debug?.Print(LogClass.ServiceNv, $"Deleted map {handle}!");
|
||||
|
||||
return true;
|
||||
@@ -275,7 +280,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
}
|
||||
}
|
||||
|
||||
public static NvMapHandle GetMapFromHandle(ulong pid, int handle)
|
||||
public static NvMapHandle GetMapFromHandle(int handle)
|
||||
{
|
||||
return _maps.Get(handle);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
public ulong Address;
|
||||
public bool Allocated;
|
||||
public ulong DmaMapAddress;
|
||||
|
||||
public ulong OwnerPid;
|
||||
|
||||
private long _dupes;
|
||||
|
||||
public NvMapHandle()
|
||||
|
||||
@@ -172,6 +172,15 @@ namespace Ryujinx.HLE.HOS.Services
|
||||
{
|
||||
ServerLoop();
|
||||
}
|
||||
|
||||
protected virtual ulong CalculateRequiredHeapSize()
|
||||
{
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
protected virtual void CustomInit(KernelContext context, ulong pid, ulong heapAddress)
|
||||
{
|
||||
}
|
||||
|
||||
private void ServerLoop()
|
||||
{
|
||||
@@ -196,10 +205,14 @@ namespace Ryujinx.HLE.HOS.Services
|
||||
Result result = _selfProcess.HandleTable.GenerateHandle(_wakeEvent.ReadableEvent, out _wakeHandle);
|
||||
|
||||
InitDone.Set();
|
||||
|
||||
ulong heapSize = CalculateRequiredHeapSize() + PointerBufferSize;
|
||||
|
||||
ulong messagePtr = _selfThread.TlsAddress;
|
||||
_context.Syscall.SetHeapSize(out ulong heapAddr, 0x200000);
|
||||
|
||||
_context.Syscall.SetHeapSize(out ulong heapAddr, BitUtils.AlignUp(heapSize, 0x200000UL));
|
||||
|
||||
CustomInit(_context, _selfProcess.Pid, heapAddr + PointerBufferSize);
|
||||
|
||||
_selfProcess.CpuMemory.Write(messagePtr + 0x0, 0);
|
||||
_selfProcess.CpuMemory.Write(messagePtr + 0x4, 2 << 10);
|
||||
_selfProcess.CpuMemory.Write(messagePtr + 0x8, heapAddr | ((ulong)PointerBufferSize << 48));
|
||||
|
||||
@@ -4,6 +4,7 @@ using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Common.PreciseSleep;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
using Ryujinx.HLE.HOS.Kernel.Process;
|
||||
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -38,8 +39,6 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
|
||||
private readonly Lock _lock = new();
|
||||
|
||||
public long RenderLayerId { get; private set; }
|
||||
|
||||
private class Layer
|
||||
{
|
||||
public int ProducerBinderId;
|
||||
@@ -60,7 +59,6 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
{
|
||||
_device = device;
|
||||
_layers = new Dictionary<long, Layer>();
|
||||
RenderLayerId = 0;
|
||||
|
||||
_composerThread = new Thread(HandleComposition)
|
||||
{
|
||||
@@ -239,34 +237,12 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
|
||||
private void CloseLayer(long layerId, Layer layer)
|
||||
{
|
||||
// If the layer was removed and the current in use, we need to change the current layer in use.
|
||||
if (RenderLayerId == layerId)
|
||||
{
|
||||
// If no layer is availaible, reset to default value.
|
||||
if (_layers.Count == 0)
|
||||
{
|
||||
SetRenderLayer(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRenderLayer(_layers.Last().Key);
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.State == LayerState.ManagedOpened)
|
||||
{
|
||||
layer.State = LayerState.ManagedClosed;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetRenderLayer(long layerId)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
RenderLayerId = layerId;
|
||||
}
|
||||
}
|
||||
|
||||
private Layer GetLayerByIdLocked(long layerId)
|
||||
{
|
||||
foreach (KeyValuePair<long, Layer> pair in _layers)
|
||||
@@ -360,41 +336,55 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
// TODO: support multilayers (& multidisplay ?)
|
||||
if (RenderLayerId == 0)
|
||||
foreach (var (layerId, layer) in _layers)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Layer layer = GetLayerByIdLocked(RenderLayerId);
|
||||
|
||||
Status acquireStatus = layer.Consumer.AcquireBuffer(out BufferItem item, 0);
|
||||
|
||||
if (acquireStatus == Status.Success)
|
||||
{
|
||||
if (_device.VSyncMode == VSyncMode.Unbounded)
|
||||
if (layer.State == LayerState.NotInitialized || layer.State == LayerState.ManagedClosed)
|
||||
continue;
|
||||
|
||||
if (_device.System.KernelContext.Processes.TryGetValue(layer.Owner, out var process))
|
||||
{
|
||||
if (_swapInterval != 0)
|
||||
if (process.State == ProcessState.Exiting || process.State == ProcessState.Exited)
|
||||
{
|
||||
UpdateSwapInterval(0);
|
||||
_vSyncMode = _device.VSyncMode;
|
||||
HOSBinderDriverServer.UnregisterBinderObject(layer.ProducerBinderId);
|
||||
|
||||
if (_layers.Remove(layerId))
|
||||
{
|
||||
CloseLayer(layerId, layer);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (_device.VSyncMode != _vSyncMode)
|
||||
|
||||
Status acquireStatus = layer.Consumer.AcquireBuffer(out BufferItem item, 0);
|
||||
|
||||
if (acquireStatus == Status.Success)
|
||||
{
|
||||
UpdateSwapInterval(_device.VSyncMode == VSyncMode.Unbounded ? 0 : item.SwapInterval);
|
||||
_vSyncMode = _device.VSyncMode;
|
||||
}
|
||||
else if (item.SwapInterval != _swapInterval || _device.TargetVSyncInterval != _targetVSyncInterval)
|
||||
{
|
||||
UpdateSwapInterval(item.SwapInterval);
|
||||
}
|
||||
if (_device.VSyncMode == VSyncMode.Unbounded)
|
||||
{
|
||||
if (_swapInterval != 0)
|
||||
{
|
||||
UpdateSwapInterval(0);
|
||||
_vSyncMode = _device.VSyncMode;
|
||||
}
|
||||
}
|
||||
else if (_device.VSyncMode != _vSyncMode)
|
||||
{
|
||||
UpdateSwapInterval(_device.VSyncMode == VSyncMode.Unbounded ? 0 : item.SwapInterval);
|
||||
_vSyncMode = _device.VSyncMode;
|
||||
}
|
||||
else if (item.SwapInterval != _swapInterval || _device.TargetVSyncInterval != _targetVSyncInterval)
|
||||
{
|
||||
UpdateSwapInterval(item.SwapInterval);
|
||||
}
|
||||
|
||||
PostFrameBuffer(layer, item);
|
||||
}
|
||||
else if (acquireStatus != Status.NoBufferAvailaible && acquireStatus != Status.InvalidOperation)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
PostFrameBuffer(layer, item);
|
||||
}
|
||||
else if (acquireStatus != Status.NoBufferAvailaible && acquireStatus != Status.InvalidOperation)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.SurfaceFlinger, $"Failed to acquire buffer for layer {layerId} (status: {acquireStatus})");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -413,8 +403,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
|
||||
ulong bufferOffset = (ulong)item.GraphicBuffer.Object.Buffer.Surfaces[0].Offset;
|
||||
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(layer.Owner, nvMapHandle);
|
||||
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(nvMapHandle);
|
||||
|
||||
ulong frameBufferAddress = map.Address + bufferOffset;
|
||||
|
||||
Format format = ConvertColorFormat(item.GraphicBuffer.Object.Buffer.Surfaces[0].ColorFormat);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
@@ -36,6 +37,6 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
public int PlanesCount;
|
||||
|
||||
[FieldOffset(0x34)]
|
||||
public NvGraphicBufferSurfaceArray Surfaces;
|
||||
public Array3<NvGraphicBufferSurface> Surfaces;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService
|
||||
ulong pid = context.Device.System.AppletState.AppletResourceUserIds.GetData<ulong>((int)appletResourceUserId);
|
||||
|
||||
context.Device.System.SurfaceFlinger.CreateLayer(out long layerId, pid);
|
||||
context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
|
||||
|
||||
context.ResponseData.Write(layerId);
|
||||
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Ipc;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using Ryujinx.HLE.HOS.Services.SurfaceFlinger;
|
||||
using Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService.Types.Fbshare;
|
||||
using Ryujinx.Horizon.Common;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService
|
||||
{
|
||||
@@ -7,6 +14,9 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService
|
||||
#pragma warning disable IDE0052 // Remove unread private member
|
||||
private readonly IApplicationDisplayService _applicationDisplayService;
|
||||
#pragma warning restore IDE0052
|
||||
|
||||
private KEvent _sharedFramebufferAcquirableEvent;
|
||||
private int _sharedFramebufferAcquirableEventHandle;
|
||||
|
||||
public ISystemDisplayService(IApplicationDisplayService applicationDisplayService)
|
||||
{
|
||||
@@ -57,5 +67,138 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(8225)] // 4.0.0+
|
||||
// GetSharedBufferMemoryHandleId()
|
||||
public ResultCode GetSharedBufferMemoryHandleId(ServiceCtx context)
|
||||
{
|
||||
context.ResponseData.Write((ulong)context.Device.System.ViServerS.GetSharedBufferNvMapId());
|
||||
context.ResponseData.Write(context.Device.System.ViServerS.GetSharedBufferSize());
|
||||
|
||||
(ulong mapAddress, ulong mapSize) = context.Request.GetBufferType0x22();
|
||||
|
||||
context.Memory.Write(mapAddress, context.Device.System.ViServerS.GetSharedBufferMap());
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(8250)] // 4.0.0+
|
||||
// OpenSharedLayer(nn::vi::fbshare::SharedLayerHandle, nn::applet::AppletResourceUserId, pid)
|
||||
public ResultCode OpenSharedLayer(ServiceCtx context)
|
||||
{
|
||||
long sharedLayerHandle = context.RequestData.ReadInt64();
|
||||
long appletResourceUserId = context.RequestData.ReadInt64();
|
||||
|
||||
context.Device.System.ViServerS.OpenSharedLayer(sharedLayerHandle);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(8251)] // 4.0.0+
|
||||
// CloseSharedLayer(nn::vi::fbshare::SharedLayerHandle)
|
||||
public ResultCode CloseSharedLayer(ServiceCtx context)
|
||||
{
|
||||
long sharedLayerHandle = context.RequestData.ReadInt64();
|
||||
|
||||
context.Device.System.ViServerS.CloseSharedLayer(sharedLayerHandle);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(8252)] // 4.0.0+
|
||||
// ConnectSharedLayer(nn::vi::fbshare::SharedLayerHandle)
|
||||
public ResultCode ConnectSharedLayer(ServiceCtx context)
|
||||
{
|
||||
long sharedLayerHandle = context.RequestData.ReadInt64();
|
||||
|
||||
context.Device.System.ViServerS.ConnectSharedLayer(sharedLayerHandle);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(8253)] // 4.0.0+
|
||||
// DisconnectSharedLayer(nn::vi::fbshare::SharedLayerHandle)
|
||||
public ResultCode DisconnectSharedLayer(ServiceCtx context)
|
||||
{
|
||||
long sharedLayerHandle = context.RequestData.ReadInt64();
|
||||
|
||||
context.Device.System.ViServerS.DisconnectSharedLayer(sharedLayerHandle);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(8254)] // 4.0.0+
|
||||
// AcquireSharedFrameBuffer(nn::vi::fbshare::SharedLayerHandle) -> (nn::vi::native::NativeSync, nn::vi::fbshare::SharedLayerTextureIndexList, u64)
|
||||
public ResultCode AcquireSharedFrameBuffer(ServiceCtx context)
|
||||
{
|
||||
long sharedLayerHandle = context.RequestData.ReadInt64();
|
||||
|
||||
int slot = context.Device.System.ViServerS.DequeueFrameBuffer(sharedLayerHandle, out AndroidFence fence);
|
||||
|
||||
var indexList = new SharedLayerTextureIndexList();
|
||||
|
||||
for (int i = 0; i < indexList.Indices.Length; i++)
|
||||
{
|
||||
indexList.Indices[i] = context.Device.System.ViServerS.GetFrameBufferMapIndex(i);
|
||||
}
|
||||
|
||||
context.ResponseData.WriteStruct(fence);
|
||||
context.ResponseData.WriteStruct(indexList);
|
||||
context.ResponseData.Write(0); // Padding
|
||||
context.ResponseData.Write((ulong)slot);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(8255)] // 4.0.0+
|
||||
// PresentSharedFrameBuffer(nn::vi::native::NativeSync, nn::vi::CropRegion, u32, u32, nn::vi::fbshare::SharedLayerHandle, u64)
|
||||
public ResultCode PresentSharedFrameBuffer(ServiceCtx context)
|
||||
{
|
||||
AndroidFence nativeSync = context.RequestData.ReadStruct<AndroidFence>();
|
||||
Rect cropRegion = context.RequestData.ReadStruct<Rect>();
|
||||
|
||||
NativeWindowTransform transform = (NativeWindowTransform)context.RequestData.ReadUInt32();
|
||||
int swapInterval = context.RequestData.ReadInt32();
|
||||
int padding = context.RequestData.ReadInt32();
|
||||
|
||||
long sharedLayerHandle = context.RequestData.ReadInt64();
|
||||
ulong slot = context.RequestData.ReadUInt64();
|
||||
|
||||
context.Device.System.ViServerS.QueueFrameBuffer(sharedLayerHandle, (int)slot, cropRegion, transform, swapInterval, nativeSync);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(8256)] // 4.0.0+
|
||||
// GetSharedFrameBufferAcquirableEvent(nn::vi::fbshare::SharedLayerHandle) -> handle<copy>
|
||||
public ResultCode GetSharedFrameBufferAcquirableEvent(ServiceCtx context)
|
||||
{
|
||||
if (_sharedFramebufferAcquirableEventHandle == 0)
|
||||
{
|
||||
_sharedFramebufferAcquirableEvent = new KEvent(context.Device.System.KernelContext);
|
||||
_sharedFramebufferAcquirableEvent.WritableEvent.Signal();
|
||||
|
||||
if (context.Process.HandleTable.GenerateHandle(_sharedFramebufferAcquirableEvent.ReadableEvent, out _sharedFramebufferAcquirableEventHandle) != Result.Success)
|
||||
{
|
||||
throw new InvalidOperationException("Out of handles!");
|
||||
}
|
||||
}
|
||||
|
||||
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_sharedFramebufferAcquirableEventHandle);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(8258)] // 5.0.0+
|
||||
// CancelSharedFrameBuffer(nn::vi::fbshare::SharedLayerHandle, u64)
|
||||
public ResultCode CancelSharedFrameBuffer(ServiceCtx context)
|
||||
{
|
||||
long sharedLayerHandle = context.RequestData.ReadInt64();
|
||||
ulong slot = context.RequestData.ReadUInt64();
|
||||
|
||||
context.Device.System.ViServerS.CancelFrameBuffer(sharedLayerHandle, (int)slot);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService.Types.Fbshare
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 0x4)]
|
||||
struct SharedLayerTextureIndexList
|
||||
{
|
||||
public Array4<int> Indices;
|
||||
}
|
||||
}
|
||||
@@ -248,8 +248,6 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||
return result;
|
||||
}
|
||||
|
||||
context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
|
||||
|
||||
using Parcel parcel = new(0x28, 0x4);
|
||||
|
||||
parcel.WriteObject(producer, "dispdrv\0");
|
||||
@@ -285,9 +283,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||
|
||||
// TODO: support multi display.
|
||||
IBinder producer = context.Device.System.SurfaceFlinger.CreateLayer(out long layerId, 0, LayerState.Stray);
|
||||
|
||||
context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
|
||||
|
||||
|
||||
using Parcel parcel = new(0x28, 0x4);
|
||||
|
||||
parcel.WriteObject(producer, "dispdrv\0");
|
||||
|
||||
19
src/Ryujinx.HLE/HOS/Services/Vi/Types/SharedBufferMap.cs
Normal file
19
src/Ryujinx.HLE/HOS/Services/Vi/Types/SharedBufferMap.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Vi.Types
|
||||
{
|
||||
struct SharedBufferMap
|
||||
{
|
||||
public struct Entry
|
||||
{
|
||||
public ulong Offset;
|
||||
public ulong Size;
|
||||
public uint Width;
|
||||
public uint Height;
|
||||
}
|
||||
|
||||
public int Count;
|
||||
public int Padding;
|
||||
public Array16<Entry> SharedBuffers;
|
||||
}
|
||||
}
|
||||
235
src/Ryujinx.HLE/HOS/Services/Vi/ViServer.cs
Normal file
235
src/Ryujinx.HLE/HOS/Services/Vi/ViServer.cs
Normal file
@@ -0,0 +1,235 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
using Ryujinx.HLE.HOS.Kernel;
|
||||
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
|
||||
using Ryujinx.HLE.HOS.Services.SurfaceFlinger;
|
||||
using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types;
|
||||
using Ryujinx.HLE.HOS.Services.Vi.Types;
|
||||
using Ryujinx.Memory;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services
|
||||
{
|
||||
class ViServer : ServerBase
|
||||
{
|
||||
private const int TotalFramebuffers = 16;
|
||||
|
||||
private SurfaceFlinger.SurfaceFlinger _surfaceFlinger;
|
||||
|
||||
private readonly uint _fbWidth;
|
||||
private readonly uint _fbHeight;
|
||||
private readonly PixelFormat _fbFormat;
|
||||
private readonly int _fbUsage;
|
||||
private readonly uint _fbCount;
|
||||
private uint _fbSlotsRequested;
|
||||
|
||||
private ulong _pid;
|
||||
private ulong _fbsBaseAddress;
|
||||
private int _bufferNvMapId;
|
||||
private SharedBufferMap _bufferMap;
|
||||
private long _sharedLayerId;
|
||||
|
||||
public ViServer(KernelContext context, string name) : base(context, name)
|
||||
{
|
||||
_fbWidth = 1280;
|
||||
_fbHeight = 720;
|
||||
_fbFormat = PixelFormat.Rgba8888;
|
||||
_fbUsage = 0x100 | 0x200 | 0x800;
|
||||
_fbCount = 4;
|
||||
}
|
||||
|
||||
protected override ulong CalculateRequiredHeapSize()
|
||||
{
|
||||
return GetSharedBufferSize();
|
||||
}
|
||||
|
||||
protected override void CustomInit(KernelContext context, ulong pid, ulong heapAddress)
|
||||
{
|
||||
_pid = pid;
|
||||
_fbsBaseAddress = heapAddress;
|
||||
|
||||
context.Device.Gpu.RegisterProcess(pid, KernelStatic.GetCurrentProcess().CpuMemory);
|
||||
|
||||
ulong bufferSize = CalculateFramebufferSize();
|
||||
ulong totalSize = bufferSize * TotalFramebuffers;
|
||||
|
||||
KernelStatic.GetCurrentProcess().CpuMemory.Fill(heapAddress, totalSize, 0xff);
|
||||
|
||||
int mapId = NvMapDeviceFile.CreateMap(pid, heapAddress, (uint)totalSize);
|
||||
|
||||
_bufferNvMapId = mapId;
|
||||
_bufferMap.Count = TotalFramebuffers;
|
||||
|
||||
ulong offset = 0;
|
||||
|
||||
for (int i = 0; i < TotalFramebuffers; i++)
|
||||
{
|
||||
_bufferMap.SharedBuffers[i].Offset = offset;
|
||||
_bufferMap.SharedBuffers[i].Size = bufferSize;
|
||||
_bufferMap.SharedBuffers[i].Width = _fbWidth;
|
||||
_bufferMap.SharedBuffers[i].Height = _fbHeight;
|
||||
|
||||
offset += bufferSize;
|
||||
}
|
||||
|
||||
_surfaceFlinger = context.Device.System.SurfaceFlinger;
|
||||
_surfaceFlinger.CreateLayer(out _sharedLayerId, pid);
|
||||
}
|
||||
|
||||
public void OpenSharedLayer(long layerId)
|
||||
{
|
||||
_surfaceFlinger.OpenLayer(_pid, layerId, out _);
|
||||
}
|
||||
|
||||
public void CloseSharedLayer(long layerId)
|
||||
{
|
||||
_surfaceFlinger.CloseLayer(layerId);
|
||||
}
|
||||
|
||||
public void ConnectSharedLayer(long layerId)
|
||||
{
|
||||
IGraphicBufferProducer producer = _surfaceFlinger.GetProducerByLayerId(layerId);
|
||||
|
||||
producer.Connect(null, NativeWindowApi.NVN, false, out IGraphicBufferProducer.QueueBufferOutput output);
|
||||
|
||||
GraphicBuffer graphicBuffer = new GraphicBuffer();
|
||||
|
||||
int gobHeightLog2 = 4;
|
||||
int blockHeight = 8 * (1 << gobHeightLog2);
|
||||
uint widthAlignedBytes = BitUtils.AlignUp(_fbWidth * 4, 64u);
|
||||
uint widthAligned = widthAlignedBytes / 4;
|
||||
uint heightAligned = BitUtils.AlignUp(_fbHeight, (uint)blockHeight);
|
||||
uint totalSize = widthAlignedBytes * heightAligned;
|
||||
|
||||
graphicBuffer.Header.Magic = 0x47424652;
|
||||
graphicBuffer.Header.Width = (int)_fbWidth;
|
||||
graphicBuffer.Header.Height = (int)_fbHeight;
|
||||
graphicBuffer.Header.Stride = (int)widthAligned;
|
||||
graphicBuffer.Header.Format = _fbFormat;
|
||||
graphicBuffer.Header.Usage = _fbUsage;
|
||||
graphicBuffer.Header.IntsCount = (Unsafe.SizeOf<GraphicBuffer>() - Unsafe.SizeOf<GraphicBufferHeader>()) / sizeof(int);
|
||||
graphicBuffer.Buffer.NvMapId = _bufferNvMapId;
|
||||
graphicBuffer.Buffer.Magic = unchecked((int)0xDAFFCAFF);
|
||||
graphicBuffer.Buffer.Pid = 42;
|
||||
graphicBuffer.Buffer.Usage = _fbUsage;
|
||||
graphicBuffer.Buffer.PixelFormat = (int)_fbFormat;
|
||||
graphicBuffer.Buffer.ExternalPixelFormat = (int)_fbFormat;
|
||||
graphicBuffer.Buffer.Stride = (int)widthAligned;
|
||||
graphicBuffer.Buffer.FrameBufferSize = (int)totalSize;
|
||||
graphicBuffer.Buffer.PlanesCount = 1;
|
||||
graphicBuffer.Buffer.Surfaces[0].Width = _fbWidth;
|
||||
graphicBuffer.Buffer.Surfaces[0].Height = _fbHeight;
|
||||
graphicBuffer.Buffer.Surfaces[0].ColorFormat = ColorFormat.A8B8G8R8;
|
||||
graphicBuffer.Buffer.Surfaces[0].Layout = 3; // Block linear
|
||||
graphicBuffer.Buffer.Surfaces[0].Pitch = (int)widthAlignedBytes;
|
||||
graphicBuffer.Buffer.Surfaces[0].Kind = 0xfe; // Generic 16Bx2
|
||||
graphicBuffer.Buffer.Surfaces[0].BlockHeightLog2 = gobHeightLog2;
|
||||
graphicBuffer.Buffer.Surfaces[0].Size = (int)totalSize;
|
||||
|
||||
for (int slot = 0; slot < _fbCount; slot++)
|
||||
{
|
||||
graphicBuffer.Buffer.Surfaces[0].Offset = slot * (int)totalSize;
|
||||
|
||||
producer.SetPreallocatedBuffer(slot, new AndroidStrongPointer<GraphicBuffer>(graphicBuffer));
|
||||
}
|
||||
|
||||
_fbSlotsRequested = 0;
|
||||
}
|
||||
|
||||
public void DisconnectSharedLayer(long layerId)
|
||||
{
|
||||
IGraphicBufferProducer producer = _surfaceFlinger.GetProducerByLayerId(layerId);
|
||||
|
||||
producer.Disconnect(NativeWindowApi.NVN);
|
||||
}
|
||||
|
||||
public int DequeueFrameBuffer(long layerId, out AndroidFence fence)
|
||||
{
|
||||
IGraphicBufferProducer producer = _surfaceFlinger.GetProducerByLayerId(layerId);
|
||||
|
||||
Status status = producer.DequeueBuffer(out int slot, out fence, false, _fbWidth, _fbHeight, _fbFormat, (uint)_fbUsage);
|
||||
|
||||
if (status == Status.Success)
|
||||
{
|
||||
if ((_fbSlotsRequested & (1u << slot)) == 0)
|
||||
{
|
||||
status = producer.RequestBuffer(slot, out _);
|
||||
|
||||
if (status != Status.Success)
|
||||
{
|
||||
producer.CancelBuffer(slot, ref fence);
|
||||
}
|
||||
|
||||
_fbSlotsRequested |= 1u << slot;
|
||||
}
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
public void QueueFrameBuffer(long layerId, int slot, Rect crop, NativeWindowTransform transform, int swapInterval, AndroidFence fence)
|
||||
{
|
||||
IGraphicBufferProducer producer = _surfaceFlinger.GetProducerByLayerId(layerId);
|
||||
|
||||
IGraphicBufferProducer.QueueBufferInput input = new();
|
||||
|
||||
input.Crop = crop;
|
||||
input.Transform = transform;
|
||||
input.SwapInterval = swapInterval;
|
||||
input.Fence = fence;
|
||||
|
||||
Status status = producer.QueueBuffer(slot, ref input, out _);
|
||||
}
|
||||
|
||||
public void CancelFrameBuffer(long layerId, int slot)
|
||||
{
|
||||
IGraphicBufferProducer producer = _surfaceFlinger.GetProducerByLayerId(layerId);
|
||||
AndroidFence fence = default;
|
||||
|
||||
producer.CancelBuffer(slot, ref fence);
|
||||
}
|
||||
|
||||
public int GetFrameBufferMapIndex(int index)
|
||||
{
|
||||
return (uint)index < _fbCount ? index : 0;
|
||||
}
|
||||
|
||||
public int GetSharedBufferNvMapId()
|
||||
{
|
||||
return _bufferNvMapId;
|
||||
}
|
||||
|
||||
public ulong GetSharedBufferSize()
|
||||
{
|
||||
return CalculateFramebufferSize() * TotalFramebuffers;
|
||||
}
|
||||
|
||||
public long GetSharedLayerId()
|
||||
{
|
||||
return _sharedLayerId;
|
||||
}
|
||||
|
||||
private ulong CalculateFramebufferSize()
|
||||
{
|
||||
// Each GOB dimension is 512 bytes x 8 lines.
|
||||
// Assume 16 GOBs, for a total of 16 x 8 = 128 lines.
|
||||
return BitUtils.AlignUp(_fbWidth * 4, 512u) * BitUtils.AlignUp(_fbHeight, 128u);
|
||||
}
|
||||
|
||||
public SharedBufferMap GetSharedBufferMap()
|
||||
{
|
||||
return _bufferMap;
|
||||
}
|
||||
|
||||
public int GetApplicationLastPresentedFrameHandle(GpuContext gpuContext)
|
||||
{
|
||||
TextureData texture = gpuContext.Window.GetLastPresentedData();
|
||||
IVirtualMemoryManagerTracked selfAs = KernelStatic.GetProcessByPid(_pid).CpuMemory;
|
||||
int fbIndex = (int)_fbCount; // Place it after all our frame buffers.
|
||||
|
||||
selfAs.Write(_fbsBaseAddress + _bufferMap.SharedBuffers[fbIndex].Offset, texture.Data);
|
||||
|
||||
return fbIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Ns;
|
||||
using LibHac.Tools.FsSystem.NcaUtils;
|
||||
using Ryujinx.Audio.Backends.CompatLayer;
|
||||
using Ryujinx.Audio.Integration;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
using Ryujinx.HLE.Exceptions;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using Ryujinx.HLE.HOS.Services.Apm;
|
||||
@@ -158,5 +161,18 @@ namespace Ryujinx.HLE
|
||||
Shared = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool LoadSystemProgramId(ulong programId)
|
||||
{
|
||||
string contentPath = System.ContentManager.GetInstalledContentPath(programId, StorageId.BuiltInSystem, NcaContentType.Program);
|
||||
string filePath = VirtualFileSystem.SwitchPathToSystemPath(contentPath);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(filePath))
|
||||
{
|
||||
throw new InvalidSystemResourceException("Specified title ID is not installed on the system.");
|
||||
}
|
||||
|
||||
return Processes.LoadNca(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Memory.Range;
|
||||
using Ryujinx.Memory.Tracking;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -9,7 +10,7 @@ namespace Ryujinx.Memory
|
||||
/// Represents a address space manager.
|
||||
/// Supports virtual memory region mapping, address translation and read/write access to mapped regions.
|
||||
/// </summary>
|
||||
public sealed class AddressSpaceManager : VirtualMemoryManagerBase, IVirtualMemoryManager
|
||||
public sealed class AddressSpaceManager : VirtualMemoryManagerBase, IVirtualMemoryManagerTracked
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool UsesPrivateAllocations => false;
|
||||
@@ -21,6 +22,8 @@ namespace Ryujinx.Memory
|
||||
|
||||
private readonly MemoryBlock _backingMemory;
|
||||
private readonly PageTable<nuint> _pageTable;
|
||||
private readonly MemoryTracking _tracking;
|
||||
private bool _writeTracked;
|
||||
|
||||
protected override ulong AddressSpaceSize { get; }
|
||||
|
||||
@@ -44,6 +47,7 @@ namespace Ryujinx.Memory
|
||||
AddressSpaceSize = asSize;
|
||||
_backingMemory = backingMemory;
|
||||
_pageTable = new PageTable<nuint>();
|
||||
_tracking = new MemoryTracking(this, 0x1000);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -227,7 +231,7 @@ namespace Ryujinx.Memory
|
||||
/// <inheritdoc/>
|
||||
public void TrackingReprotect(ulong va, ulong size, MemoryPermission protection, bool guest = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
_writeTracked = true;
|
||||
}
|
||||
|
||||
protected unsafe override Memory<byte> GetPhysicalAddressMemory(nuint pa, int size)
|
||||
@@ -240,5 +244,29 @@ namespace Ryujinx.Memory
|
||||
|
||||
protected override nuint TranslateVirtualAddressUnchecked(ulong va)
|
||||
=> GetHostAddress(va);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false, int? exemptId = null)
|
||||
{
|
||||
if (_writeTracked)
|
||||
{
|
||||
_tracking.VirtualMemoryEvent(va, size, write, precise);
|
||||
}
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public RegionHandle BeginTracking(ulong address, ulong size, int id, RegionFlags flags = RegionFlags.None)
|
||||
{
|
||||
return _tracking.BeginTracking(address, size, id, flags);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public MultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable<IRegionHandle> handles, ulong granularity, int id, RegionFlags flags = RegionFlags.None)
|
||||
{
|
||||
return _tracking.BeginGranularTracking(address, size, handles, granularity, id, flags);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public SmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ulong granularity, int id)
|
||||
{
|
||||
return _tracking.BeginSmartGranularTracking(address, size, granularity, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using Ryujinx.Memory.Tracking;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Cpu
|
||||
namespace Ryujinx.Memory
|
||||
{
|
||||
public interface IVirtualMemoryManagerTracked : IVirtualMemoryManager
|
||||
{
|
||||
@@ -41,6 +41,7 @@ using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
using Ryujinx.HLE.Loaders.Processes;
|
||||
using Ryujinx.Input;
|
||||
using Ryujinx.Input.HLE;
|
||||
using SkiaSharp;
|
||||
@@ -672,6 +673,7 @@ namespace Ryujinx.Ava
|
||||
DiscordIntegrationModule.GuestAppStartedAt = Timestamps.Now;
|
||||
|
||||
InitEmulatedSwitch();
|
||||
Device.LoadSystemProgramId(0x010000000000100C);
|
||||
MainWindow.UpdateGraphicsConfig();
|
||||
|
||||
SystemVersion firmwareVersion = ContentManager.GetCurrentFirmwareVersion();
|
||||
|
||||
@@ -4647,56 +4647,6 @@
|
||||
"zh_TW": "正體中文 (建議)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SettingsTabSystemSystemLanguageSwedish",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Swedish",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "스웨덴어",
|
||||
"no_NO": "Svensk",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Sueco",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "Svenska",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "瑞典语",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SettingsTabSystemSystemLanguageNorwegian",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Norwegian",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "노르웨이어",
|
||||
"no_NO": "Norsk",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Norueguês",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "Norska",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "挪威语",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SettingsTabSystemSystemTimeZone",
|
||||
"Translations": {
|
||||
@@ -24123,4 +24073,4 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user