diff options
Diffstat (limited to 'Ryujinx.Graphics')
279 files changed, 0 insertions, 25143 deletions
diff --git a/Ryujinx.Graphics/CdmaProcessor.cs b/Ryujinx.Graphics/CdmaProcessor.cs deleted file mode 100644 index 4ff12fbf..00000000 --- a/Ryujinx.Graphics/CdmaProcessor.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Ryujinx.Graphics.Memory; -using System.Collections.Generic; - -namespace Ryujinx.Graphics -{ - public class CdmaProcessor - { - private const int MethSetMethod = 0x10; - private const int MethSetData = 0x11; - - private NvGpu _gpu; - - public CdmaProcessor(NvGpu gpu) - { - _gpu = gpu; - } - - public void PushCommands(NvGpuVmm vmm, int[] cmdBuffer) - { - List<ChCommand> commands = new List<ChCommand>(); - - ChClassId currentClass = 0; - - for (int index = 0; index < cmdBuffer.Length; index++) - { - int cmd = cmdBuffer[index]; - - int value = (cmd >> 0) & 0xffff; - int methodOffset = (cmd >> 16) & 0xfff; - - ChSubmissionMode submissionMode = (ChSubmissionMode)((cmd >> 28) & 0xf); - - switch (submissionMode) - { - case ChSubmissionMode.SetClass: currentClass = (ChClassId)(value >> 6); break; - - case ChSubmissionMode.Incrementing: - { - int count = value; - - for (int argIdx = 0; argIdx < count; argIdx++) - { - int argument = cmdBuffer[++index]; - - commands.Add(new ChCommand(currentClass, methodOffset + argIdx, argument)); - } - - break; - } - - case ChSubmissionMode.NonIncrementing: - { - int count = value; - - int[] arguments = new int[count]; - - for (int argIdx = 0; argIdx < count; argIdx++) - { - arguments[argIdx] = cmdBuffer[++index]; - } - - commands.Add(new ChCommand(currentClass, methodOffset, arguments)); - - break; - } - } - } - - ProcessCommands(vmm, commands.ToArray()); - } - - private void ProcessCommands(NvGpuVmm vmm, ChCommand[] commands) - { - int methodOffset = 0; - - foreach (ChCommand command in commands) - { - switch (command.MethodOffset) - { - case MethSetMethod: methodOffset = command.Arguments[0]; break; - - case MethSetData: - { - if (command.ClassId == ChClassId.NvDec) - { - _gpu.VideoDecoder.Process(vmm, methodOffset, command.Arguments); - } - else if (command.ClassId == ChClassId.GraphicsVic) - { - _gpu.VideoImageComposer.Process(vmm, methodOffset, command.Arguments); - } - - break; - } - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/ChClassId.cs b/Ryujinx.Graphics/ChClassId.cs deleted file mode 100644 index 115f0b89..00000000 --- a/Ryujinx.Graphics/ChClassId.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Ryujinx.Graphics -{ - enum ChClassId - { - Host1X = 0x1, - VideoEncodeMpeg = 0x20, - VideoEncodeNvEnc = 0x21, - VideoStreamingVi = 0x30, - VideoStreamingIsp = 0x32, - VideoStreamingIspB = 0x34, - VideoStreamingViI2c = 0x36, - GraphicsVic = 0x5d, - Graphics3D = 0x60, - GraphicsGpu = 0x61, - Tsec = 0xe0, - TsecB = 0xe1, - NvJpg = 0xc0, - NvDec = 0xf0 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/ChCommandEntry.cs b/Ryujinx.Graphics/ChCommandEntry.cs deleted file mode 100644 index b01b77ed..00000000 --- a/Ryujinx.Graphics/ChCommandEntry.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Graphics -{ - struct ChCommand - { - public ChClassId ClassId { get; private set; } - - public int MethodOffset { get; private set; } - - public int[] Arguments { get; private set; } - - public ChCommand(ChClassId classId, int methodOffset, params int[] arguments) - { - ClassId = classId; - MethodOffset = methodOffset; - Arguments = arguments; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/ChSubmissionMode.cs b/Ryujinx.Graphics/ChSubmissionMode.cs deleted file mode 100644 index 5c653019..00000000 --- a/Ryujinx.Graphics/ChSubmissionMode.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics -{ - enum ChSubmissionMode - { - SetClass = 0, - Incrementing = 1, - NonIncrementing = 2, - Mask = 3, - Immediate = 4, - Restart = 5, - Gather = 6 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/DepthCompareFunc.cs b/Ryujinx.Graphics/DepthCompareFunc.cs deleted file mode 100644 index 24c8854a..00000000 --- a/Ryujinx.Graphics/DepthCompareFunc.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.Graphics -{ - public enum DepthCompareFunc - { - Never = 0, - Less = 1, - Equal = 2, - LEqual = 3, - Greater = 4, - NotEqual = 5, - GEqual = 6, - Always = 7 - } -} diff --git a/Ryujinx.Graphics/DmaPusher.cs b/Ryujinx.Graphics/DmaPusher.cs deleted file mode 100644 index 74a32a4a..00000000 --- a/Ryujinx.Graphics/DmaPusher.cs +++ /dev/null @@ -1,190 +0,0 @@ -using Ryujinx.Graphics.Memory; -using System.Collections.Concurrent; -using System.Threading; - -namespace Ryujinx.Graphics -{ - public class DmaPusher - { - private ConcurrentQueue<(NvGpuVmm, long)> _ibBuffer; - - private long _dmaPut; - private long _dmaGet; - - private struct DmaState - { - public int Method; - public int SubChannel; - public int MethodCount; - public bool NonIncrementing; - public bool IncrementOnce; - public int LengthPending; - } - - private DmaState _state; - - private bool _sliEnable; - private bool _sliActive; - - private bool _ibEnable; - private bool _nonMain; - - private long _dmaMGet; - - private NvGpuVmm _vmm; - - private NvGpu _gpu; - - private AutoResetEvent _event; - - public DmaPusher(NvGpu gpu) - { - _gpu = gpu; - - _ibBuffer = new ConcurrentQueue<(NvGpuVmm, long)>(); - - _ibEnable = true; - - _event = new AutoResetEvent(false); - } - - public void Push(NvGpuVmm vmm, long entry) - { - _ibBuffer.Enqueue((vmm, entry)); - - _event.Set(); - } - - public bool WaitForCommands() - { - return _event.WaitOne(8); - } - - public void DispatchCalls() - { - while (Step()); - } - - private bool Step() - { - if (_dmaGet != _dmaPut) - { - int word = _vmm.ReadInt32(_dmaGet); - - _dmaGet += 4; - - if (!_nonMain) - { - _dmaMGet = _dmaGet; - } - - if (_state.LengthPending != 0) - { - _state.LengthPending = 0; - _state.MethodCount = word & 0xffffff; - } - else if (_state.MethodCount != 0) - { - if (!_sliEnable || _sliActive) - { - CallMethod(word); - } - - if (!_state.NonIncrementing) - { - _state.Method++; - } - - if (_state.IncrementOnce) - { - _state.NonIncrementing = true; - } - - _state.MethodCount--; - } - else - { - int submissionMode = (word >> 29) & 7; - - switch (submissionMode) - { - case 1: - // Incrementing. - SetNonImmediateState(word); - - _state.NonIncrementing = false; - _state.IncrementOnce = false; - - break; - - case 3: - // Non-incrementing. - SetNonImmediateState(word); - - _state.NonIncrementing = true; - _state.IncrementOnce = false; - - break; - - case 4: - // Immediate. - _state.Method = (word >> 0) & 0x1fff; - _state.SubChannel = (word >> 13) & 7; - _state.NonIncrementing = true; - _state.IncrementOnce = false; - - CallMethod((word >> 16) & 0x1fff); - - break; - - case 5: - // Increment-once. - SetNonImmediateState(word); - - _state.NonIncrementing = false; - _state.IncrementOnce = true; - - break; - } - } - } - else if (_ibEnable && _ibBuffer.TryDequeue(out (NvGpuVmm Vmm, long Entry) tuple)) - { - _vmm = tuple.Vmm; - - long entry = tuple.Entry; - - int length = (int)(entry >> 42) & 0x1fffff; - - _dmaGet = entry & 0xfffffffffc; - _dmaPut = _dmaGet + length * 4; - - _nonMain = (entry & (1L << 41)) != 0; - - _gpu.ResourceManager.ClearPbCache(); - } - else - { - return false; - } - - return true; - } - - private void SetNonImmediateState(int word) - { - _state.Method = (word >> 0) & 0x1fff; - _state.SubChannel = (word >> 13) & 7; - _state.MethodCount = (word >> 16) & 0x1fff; - } - - private void CallMethod(int argument) - { - _gpu.Fifo.CallMethod(_vmm, new GpuMethodCall( - _state.Method, - argument, - _state.SubChannel, - _state.MethodCount)); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/EmbeddedResource.cs b/Ryujinx.Graphics/Gal/EmbeddedResource.cs deleted file mode 100644 index ba662499..00000000 --- a/Ryujinx.Graphics/Gal/EmbeddedResource.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.IO; -using System.Reflection; - -namespace Ryujinx.Graphics.Gal -{ - static class EmbeddedResource - { - public static string GetString(string name) - { - Assembly asm = typeof(EmbeddedResource).Assembly; - - using (Stream resStream = asm.GetManifestResourceStream(name)) - { - StreamReader reader = new StreamReader(resStream); - - return reader.ReadToEnd(); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalBlendEquation.cs b/Ryujinx.Graphics/Gal/GalBlendEquation.cs deleted file mode 100644 index 7757faae..00000000 --- a/Ryujinx.Graphics/Gal/GalBlendEquation.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalBlendEquation - { - FuncAdd = 1, - FuncSubtract = 2, - FuncReverseSubtract = 3, - Min = 4, - Max = 5, - - FuncAddGl = 0x8006, - FuncSubtractGl = 0x8007, - FuncReverseSubtractGl = 0x8008, - MinGl = 0x800a, - MaxGl = 0x800b - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalBlendFactor.cs b/Ryujinx.Graphics/Gal/GalBlendFactor.cs deleted file mode 100644 index f70b0501..00000000 --- a/Ryujinx.Graphics/Gal/GalBlendFactor.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalBlendFactor - { - Zero = 0x1, - One = 0x2, - SrcColor = 0x3, - OneMinusSrcColor = 0x4, - SrcAlpha = 0x5, - OneMinusSrcAlpha = 0x6, - DstAlpha = 0x7, - OneMinusDstAlpha = 0x8, - DstColor = 0x9, - OneMinusDstColor = 0xa, - SrcAlphaSaturate = 0xb, - Src1Color = 0x10, - OneMinusSrc1Color = 0x11, - Src1Alpha = 0x12, - OneMinusSrc1Alpha = 0x13, - ConstantColor = 0x61, - OneMinusConstantColor = 0x62, - ConstantAlpha = 0x63, - OneMinusConstantAlpha = 0x64, - - ZeroGl = 0x4000, - OneGl = 0x4001, - SrcColorGl = 0x4300, - OneMinusSrcColorGl = 0x4301, - SrcAlphaGl = 0x4302, - OneMinusSrcAlphaGl = 0x4303, - DstAlphaGl = 0x4304, - OneMinusDstAlphaGl = 0x4305, - DstColorGl = 0x4306, - OneMinusDstColorGl = 0x4307, - SrcAlphaSaturateGl = 0x4308, - ConstantColorGl = 0xc001, - OneMinusConstantColorGl = 0xc002, - ConstantAlphaGl = 0xc003, - OneMinusConstantAlphaGl = 0xc004, - Src1ColorGl = 0xc900, - OneMinusSrc1ColorGl = 0xc901, - Src1AlphaGl = 0xc902, - OneMinusSrc1AlphaGl = 0xc903 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalClearBufferFlags.cs b/Ryujinx.Graphics/Gal/GalClearBufferFlags.cs deleted file mode 100644 index 8565051c..00000000 --- a/Ryujinx.Graphics/Gal/GalClearBufferFlags.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Gal -{ - [Flags] - public enum GalClearBufferFlags - { - Depth = 1 << 0, - Stencil = 1 << 1, - ColorRed = 1 << 2, - ColorGreen = 1 << 3, - ColorBlue = 1 << 4, - ColorAlpha = 1 << 5 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalColorF.cs b/Ryujinx.Graphics/Gal/GalColorF.cs deleted file mode 100644 index e915870c..00000000 --- a/Ryujinx.Graphics/Gal/GalColorF.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public struct GalColorF - { - public float Red { get; private set; } - public float Green { get; private set; } - public float Blue { get; private set; } - public float Alpha { get; private set; } - - public GalColorF( - float red, - float green, - float blue, - float alpha) - { - Red = red; - Green = green; - Blue = blue; - Alpha = alpha; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalComparisonOp.cs b/Ryujinx.Graphics/Gal/GalComparisonOp.cs deleted file mode 100644 index f26a7753..00000000 --- a/Ryujinx.Graphics/Gal/GalComparisonOp.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalComparisonOp - { - Never = 0x1, - Less = 0x2, - Equal = 0x3, - Lequal = 0x4, - Greater = 0x5, - NotEqual = 0x6, - Gequal = 0x7, - Always = 0x8 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalCullFace.cs b/Ryujinx.Graphics/Gal/GalCullFace.cs deleted file mode 100644 index 4ab3e174..00000000 --- a/Ryujinx.Graphics/Gal/GalCullFace.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalCullFace - { - Front = 0x404, - Back = 0x405, - FrontAndBack = 0x408 - } -} diff --git a/Ryujinx.Graphics/Gal/GalFrontFace.cs b/Ryujinx.Graphics/Gal/GalFrontFace.cs deleted file mode 100644 index 6cc4a802..00000000 --- a/Ryujinx.Graphics/Gal/GalFrontFace.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalFrontFace - { - Cw = 0x900, - Ccw = 0x901 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalImage.cs b/Ryujinx.Graphics/Gal/GalImage.cs deleted file mode 100644 index 1345704d..00000000 --- a/Ryujinx.Graphics/Gal/GalImage.cs +++ /dev/null @@ -1,87 +0,0 @@ -using Ryujinx.Graphics.Texture; - -namespace Ryujinx.Graphics.Gal -{ - public struct GalImage - { - public int Width; - public int Height; - - // FIXME: separate layer and depth - public int Depth; - public int LayerCount; - public int TileWidth; - public int GobBlockHeight; - public int GobBlockDepth; - public int Pitch; - public int MaxMipmapLevel; - - public GalImageFormat Format; - public GalMemoryLayout Layout; - public GalTextureSource XSource; - public GalTextureSource YSource; - public GalTextureSource ZSource; - public GalTextureSource WSource; - public GalTextureTarget TextureTarget; - - public GalImage( - int width, - int height, - int depth, - int layerCount, - int tileWidth, - int gobBlockHeight, - int gobBlockDepth, - GalMemoryLayout layout, - GalImageFormat format, - GalTextureTarget textureTarget, - int maxMipmapLevel = 1, - GalTextureSource xSource = GalTextureSource.Red, - GalTextureSource ySource = GalTextureSource.Green, - GalTextureSource zSource = GalTextureSource.Blue, - GalTextureSource wSource = GalTextureSource.Alpha) - { - Width = width; - Height = height; - LayerCount = layerCount; - Depth = depth; - TileWidth = tileWidth; - GobBlockHeight = gobBlockHeight; - GobBlockDepth = gobBlockDepth; - Layout = layout; - Format = format; - MaxMipmapLevel = maxMipmapLevel; - XSource = xSource; - YSource = ySource; - ZSource = zSource; - WSource = wSource; - TextureTarget = textureTarget; - - Pitch = ImageUtils.GetPitch(format, width); - } - - public bool SizeMatches(GalImage image, bool ignoreLayer = false) - { - if (ImageUtils.GetBytesPerPixel(Format) != - ImageUtils.GetBytesPerPixel(image.Format)) - { - return false; - } - - if (ImageUtils.GetAlignedWidth(this) != - ImageUtils.GetAlignedWidth(image)) - { - return false; - } - - bool result = Height == image.Height && Depth == image.Depth; - - if (!ignoreLayer) - { - result = result && LayerCount == image.LayerCount; - } - - return result; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalImageFormat.cs b/Ryujinx.Graphics/Gal/GalImageFormat.cs deleted file mode 100644 index 19ce6cfc..00000000 --- a/Ryujinx.Graphics/Gal/GalImageFormat.cs +++ /dev/null @@ -1,69 +0,0 @@ -// ReSharper disable InconsistentNaming -using System; - -namespace Ryujinx.Graphics.Gal -{ - [Flags] - public enum GalImageFormat - { - Astc2DStart, - Astc2D4x4, - Astc2D5x4, - Astc2D5x5, - Astc2D6x5, - Astc2D6x6, - Astc2D8x5, - Astc2D8x6, - Astc2D8x8, - Astc2D10x5, - Astc2D10x6, - Astc2D10x8, - Astc2D10x10, - Astc2D12x10, - Astc2D12x12, - Astc2DEnd, - - Rgba4, - Rgb565, - Bgr565, - Bgr5A1, - Rgb5A1, - R8, - Rg8, - Rgbx8, - Rgba8, - Bgra8, - Rgb10A2, - R16, - Rg16, - Rgba16, - R32, - Rg32, - Rgba32, - R11G11B10, - D16, - D24, - D32, - D24S8, - D32S8, - BC1, - BC2, - BC3, - BC4, - BC5, - BptcSfloat, - BptcUfloat, - BptcUnorm, - - Snorm = 1 << 26, - Unorm = 1 << 27, - Sint = 1 << 28, - Uint = 1 << 39, - Float = 1 << 30, - Srgb = 1 << 31, - - TypeMask = Snorm | Unorm | Sint | Uint | Float | Srgb, - - FormatMask = ~TypeMask - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalIndexFormat.cs b/Ryujinx.Graphics/Gal/GalIndexFormat.cs deleted file mode 100644 index 71a50cdb..00000000 --- a/Ryujinx.Graphics/Gal/GalIndexFormat.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalIndexFormat - { - Byte = 0, - Int16 = 1, - Int32 = 2 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalMemoryLayout.cs b/Ryujinx.Graphics/Gal/GalMemoryLayout.cs deleted file mode 100644 index 73fabf8c..00000000 --- a/Ryujinx.Graphics/Gal/GalMemoryLayout.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalMemoryLayout - { - BlockLinear = 0, - Pitch = 1 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalPipelineState.cs b/Ryujinx.Graphics/Gal/GalPipelineState.cs deleted file mode 100644 index c044a55f..00000000 --- a/Ryujinx.Graphics/Gal/GalPipelineState.cs +++ /dev/null @@ -1,130 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public struct ColorMaskState - { - private static readonly ColorMaskState DefaultBackingField = new ColorMaskState() - { - Red = true, - Green = true, - Blue = true, - Alpha = true - }; - - public static ColorMaskState Default => DefaultBackingField; - - public bool Red; - public bool Green; - public bool Blue; - public bool Alpha; - } - - public struct BlendState - { - private static readonly BlendState DefaultBackingField = new BlendState() - { - Enabled = false, - SeparateAlpha = false, - EquationRgb = GalBlendEquation.FuncAdd, - FuncSrcRgb = GalBlendFactor.One, - FuncDstRgb = GalBlendFactor.Zero, - EquationAlpha = GalBlendEquation.FuncAdd, - FuncSrcAlpha = GalBlendFactor.One, - FuncDstAlpha = GalBlendFactor.Zero - }; - - public static BlendState Default => DefaultBackingField; - - public bool Enabled; - public bool SeparateAlpha; - public GalBlendEquation EquationRgb; - public GalBlendFactor FuncSrcRgb; - public GalBlendFactor FuncDstRgb; - public GalBlendEquation EquationAlpha; - public GalBlendFactor FuncSrcAlpha; - public GalBlendFactor FuncDstAlpha; - } - - public class GalPipelineState - { - public const int Stages = 5; - public const int ConstBuffersPerStage = 18; - public const int RenderTargetsCount = 8; - - public long[][] ConstBufferKeys; - - public GalVertexBinding[] VertexBindings; - - public bool FramebufferSrgb; - - public float FlipX; - public float FlipY; - - public int Instance; - - public GalFrontFace FrontFace; - - public bool CullFaceEnabled; - public GalCullFace CullFace; - - public bool DepthTestEnabled; - public bool DepthWriteEnabled; - public GalComparisonOp DepthFunc; - public float DepthRangeNear; - public float DepthRangeFar; - - public bool StencilTestEnabled; - public bool StencilTwoSideEnabled; - - public GalComparisonOp StencilBackFuncFunc; - public int StencilBackFuncRef; - public uint StencilBackFuncMask; - public GalStencilOp StencilBackOpFail; - public GalStencilOp StencilBackOpZFail; - public GalStencilOp StencilBackOpZPass; - public uint StencilBackMask; - - public GalComparisonOp StencilFrontFuncFunc; - public int StencilFrontFuncRef; - public uint StencilFrontFuncMask; - public GalStencilOp StencilFrontOpFail; - public GalStencilOp StencilFrontOpZFail; - public GalStencilOp StencilFrontOpZPass; - public uint StencilFrontMask; - - public int ScissorTestCount; - public bool[] ScissorTestEnabled; - public int[] ScissorTestX; - public int[] ScissorTestY; - public int[] ScissorTestWidth; - public int[] ScissorTestHeight; - - public bool BlendIndependent; - public BlendState[] Blends; - - public bool ColorMaskCommon; - public ColorMaskState[] ColorMasks; - - public bool PrimitiveRestartEnabled; - public uint PrimitiveRestartIndex; - - public GalPipelineState() - { - ConstBufferKeys = new long[Stages][]; - - for (int stage = 0; stage < Stages; stage++) - { - ConstBufferKeys[stage] = new long[ConstBuffersPerStage]; - } - - Blends = new BlendState[RenderTargetsCount]; - - ScissorTestEnabled = new bool[RenderTargetsCount]; - ScissorTestY = new int[RenderTargetsCount]; - ScissorTestX = new int[RenderTargetsCount]; - ScissorTestWidth = new int[RenderTargetsCount]; - ScissorTestHeight = new int[RenderTargetsCount]; - - ColorMasks = new ColorMaskState[RenderTargetsCount]; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalPrimitiveType.cs b/Ryujinx.Graphics/Gal/GalPrimitiveType.cs deleted file mode 100644 index ce084149..00000000 --- a/Ryujinx.Graphics/Gal/GalPrimitiveType.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalPrimitiveType - { - Points = 0x0, - Lines = 0x1, - LineLoop = 0x2, - LineStrip = 0x3, - Triangles = 0x4, - TriangleStrip = 0x5, - TriangleFan = 0x6, - Quads = 0x7, - QuadStrip = 0x8, - Polygon = 0x9, - LinesAdjacency = 0xa, - LineStripAdjacency = 0xb, - TrianglesAdjacency = 0xc, - TriangleStripAdjacency = 0xd, - Patches = 0xe - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalShaderType.cs b/Ryujinx.Graphics/Gal/GalShaderType.cs deleted file mode 100644 index eb5aaf88..00000000 --- a/Ryujinx.Graphics/Gal/GalShaderType.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalShaderType - { - Vertex = 0, - TessControl = 1, - TessEvaluation = 2, - Geometry = 3, - Fragment = 4 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalStencilOp.cs b/Ryujinx.Graphics/Gal/GalStencilOp.cs deleted file mode 100644 index fc83ca5e..00000000 --- a/Ryujinx.Graphics/Gal/GalStencilOp.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalStencilOp - { - Keep = 0x1, - Zero = 0x2, - Replace = 0x3, - Incr = 0x4, - Decr = 0x5, - Invert = 0x6, - IncrWrap = 0x7, - DecrWrap = 0x8 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalSurfaceFormat.cs b/Ryujinx.Graphics/Gal/GalSurfaceFormat.cs deleted file mode 100644 index 9cebcc27..00000000 --- a/Ryujinx.Graphics/Gal/GalSurfaceFormat.cs +++ /dev/null @@ -1,68 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalSurfaceFormat - { - Bitmap = 0x1c, - Unknown1D = 0x1d, - Rgba32Float = 0xc0, - Rgba32Sint = 0xc1, - Rgba32Uint = 0xc2, - Rgbx32Float = 0xc3, - Rgbx32Sint = 0xc4, - Rgbx32Uint = 0xc5, - Rgba16Unorm = 0xc6, - Rgba16Snorm = 0xc7, - Rgba16Sint = 0xc8, - Rgba16Uint = 0xc9, - Rgba16Float = 0xca, - Rg32Float = 0xcb, - Rg32Sint = 0xcc, - Rg32Uint = 0xcd, - Rgbx16Float = 0xce, - Bgra8Unorm = 0xcf, - Bgra8Srgb = 0xd0, - Rgb10A2Unorm = 0xd1, - Rgb10A2Uint = 0xd2, - Rgba8Unorm = 0xd5, - Rgba8Srgb = 0xd6, - Rgba8Snorm = 0xd7, - Rgba8Sint = 0xd8, - Rgba8Uint = 0xd9, - Rg16Unorm = 0xda, - Rg16Snorm = 0xdb, - Rg16Sint = 0xdc, - Rg16Uint = 0xdd, - Rg16Float = 0xde, - Bgr10A2Unorm = 0xdf, - R11G11B10Float = 0xe0, - R32Sint = 0xe3, - R32Uint = 0xe4, - R32Float = 0xe5, - Bgrx8Unorm = 0xe6, - Bgrx8Srgb = 0xe7, - B5G6R5Unorm = 0xe8, - Bgr5A1Unorm = 0xe9, - Rg8Unorm = 0xea, - Rg8Snorm = 0xeb, - Rg8Sint = 0xec, - Rg8Uint = 0xed, - R16Unorm = 0xee, - R16Snorm = 0xef, - R16Sint = 0xf0, - R16Uint = 0xf1, - R16Float = 0xf2, - R8Unorm = 0xf3, - R8Snorm = 0xf4, - R8Sint = 0xf5, - R8Uint = 0xf6, - A8Unorm = 0xf7, - Bgr5x1Unorm = 0xf8, - Rgbx8Unorm = 0xf9, - Rgbx8Srgb = 0xfa, - Bgr5x1UnormUnknownFB = 0xfb, - Bgr5x1UnormUnknownFC = 0xfc, - Bgrx8UnormUnknownFD = 0xfd, - Bgrx8UnormUnknownFE = 0xfe, - Y32UintUnknownFF = 0xff - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalTextureFilter.cs b/Ryujinx.Graphics/Gal/GalTextureFilter.cs deleted file mode 100644 index 8e9669f0..00000000 --- a/Ryujinx.Graphics/Gal/GalTextureFilter.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalTextureFilter - { - Nearest = 1, - Linear = 2 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalTextureFormat.cs b/Ryujinx.Graphics/Gal/GalTextureFormat.cs deleted file mode 100644 index ed27180a..00000000 --- a/Ryujinx.Graphics/Gal/GalTextureFormat.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalTextureFormat - { - Rgba32 = 0x1, - Rgba16 = 0x3, - Rg32 = 0x4, - Rgba8 = 0x8, - Rgb10A2 = 0x9, - Rg16 = 0xc, - R32 = 0xf, - BptcSfloat = 0x10, - BptcUfloat = 0x11, - Rgba4 = 0x12, - Rgb5A1 = 0x14, - Rgb565 = 0x15, - BptcUnorm = 0x17, - Rg8 = 0x18, - R16 = 0x1b, - R8 = 0x1d, - R11G11B10F = 0x21, - BC1 = 0x24, - BC2 = 0x25, - BC3 = 0x26, - BC4 = 0x27, - BC5 = 0x28, - D24S8 = 0x29, - D32F = 0x2f, - D32Fx24S8 = 0x30, - D16 = 0x3a, - Astc2D4x4 = 0x40, - Astc2D5x5 = 0x41, - Astc2D6x6 = 0x42, - Astc2D8x8 = 0x44, - Astc2D10x10 = 0x45, - Astc2D12x12 = 0x46, - Astc2D5x4 = 0x50, - Astc2D6x5 = 0x51, - Astc2D8x6 = 0x52, - Astc2D10x8 = 0x53, - Astc2D12x10 = 0x54, - Astc2D8x5 = 0x55, - Astc2D10x5 = 0x56, - Astc2D10x6 = 0x57 - } -} diff --git a/Ryujinx.Graphics/Gal/GalTextureMipFilter.cs b/Ryujinx.Graphics/Gal/GalTextureMipFilter.cs deleted file mode 100644 index 2123ec7d..00000000 --- a/Ryujinx.Graphics/Gal/GalTextureMipFilter.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalTextureMipFilter - { - None = 1, - Nearest = 2, - Linear = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalTextureSampler.cs b/Ryujinx.Graphics/Gal/GalTextureSampler.cs deleted file mode 100644 index 2e57a130..00000000 --- a/Ryujinx.Graphics/Gal/GalTextureSampler.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public struct GalTextureSampler - { - public GalTextureWrap AddressU { get; private set; } - public GalTextureWrap AddressV { get; private set; } - public GalTextureWrap AddressP { get; private set; } - - public GalTextureFilter MinFilter { get; private set; } - public GalTextureFilter MagFilter { get; private set; } - public GalTextureMipFilter MipFilter { get; private set; } - - public GalColorF BorderColor { get; private set; } - - public bool DepthCompare { get; private set; } - public DepthCompareFunc DepthCompareFunc { get; private set; } - - public GalTextureSampler( - GalTextureWrap addressU, - GalTextureWrap addressV, - GalTextureWrap addressP, - GalTextureFilter minFilter, - GalTextureFilter magFilter, - GalTextureMipFilter mipFilter, - GalColorF borderColor, - bool depthCompare, - DepthCompareFunc depthCompareFunc) - { - AddressU = addressU; - AddressV = addressV; - AddressP = addressP; - MinFilter = minFilter; - MagFilter = magFilter; - MipFilter = mipFilter; - BorderColor = borderColor; - - DepthCompare = depthCompare; - DepthCompareFunc = depthCompareFunc; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalTextureSource.cs b/Ryujinx.Graphics/Gal/GalTextureSource.cs deleted file mode 100644 index 72dbec60..00000000 --- a/Ryujinx.Graphics/Gal/GalTextureSource.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalTextureSource - { - Zero = 0, - Red = 2, - Green = 3, - Blue = 4, - Alpha = 5, - OneInt = 6, - OneFloat = 7 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalTextureTarget.cs b/Ryujinx.Graphics/Gal/GalTextureTarget.cs deleted file mode 100644 index bcc0c49a..00000000 --- a/Ryujinx.Graphics/Gal/GalTextureTarget.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalTextureTarget - { - OneD = 0, - TwoD = 1, - ThreeD = 2, - CubeMap = 3, - OneDArray = 4, - TwoDArray = 5, - OneDBuffer = 6, - TwoDNoMipMap = 7, - CubeArray = 8, - } -} diff --git a/Ryujinx.Graphics/Gal/GalTextureType.cs b/Ryujinx.Graphics/Gal/GalTextureType.cs deleted file mode 100644 index b02b8b37..00000000 --- a/Ryujinx.Graphics/Gal/GalTextureType.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalTextureType - { - Snorm = 1, - Unorm = 2, - Sint = 3, - Uint = 4, - SnormForceFp16 = 5, - UnormForceFp16 = 6, - Float = 7 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalTextureWrap.cs b/Ryujinx.Graphics/Gal/GalTextureWrap.cs deleted file mode 100644 index 66e53154..00000000 --- a/Ryujinx.Graphics/Gal/GalTextureWrap.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalTextureWrap - { - Repeat = 0, - MirroredRepeat = 1, - ClampToEdge = 2, - ClampToBorder = 3, - Clamp = 4, - MirrorClampToEdge = 5, - MirrorClampToBorder = 6, - MirrorClamp = 7 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalVertexAttrib.cs b/Ryujinx.Graphics/Gal/GalVertexAttrib.cs deleted file mode 100644 index feca5aea..00000000 --- a/Ryujinx.Graphics/Gal/GalVertexAttrib.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public struct GalVertexAttrib - { - public int Index { get; private set; } - public bool IsConst { get; private set; } - public int Offset { get; private set; } - public byte[] Data { get; private set; } - - public GalVertexAttribSize Size { get; private set; } - public GalVertexAttribType Type { get; private set; } - - public bool IsBgra { get; private set; } - - public GalVertexAttrib( - int index, - bool isConst, - int offset, - byte[] data, - GalVertexAttribSize size, - GalVertexAttribType type, - bool isBgra) - { - Index = index; - IsConst = isConst; - Data = data; - Offset = offset; - Size = size; - Type = type; - IsBgra = isBgra; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalVertexAttribSize.cs b/Ryujinx.Graphics/Gal/GalVertexAttribSize.cs deleted file mode 100644 index d3ce60ac..00000000 --- a/Ryujinx.Graphics/Gal/GalVertexAttribSize.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalVertexAttribSize - { - _32_32_32_32 = 0x1, - _32_32_32 = 0x2, - _16_16_16_16 = 0x3, - _32_32 = 0x4, - _16_16_16 = 0x5, - _8_8_8_8 = 0xa, - _16_16 = 0xf, - _32 = 0x12, - _8_8_8 = 0x13, - _8_8 = 0x18, - _16 = 0x1b, - _8 = 0x1d, - _10_10_10_2 = 0x30, - _11_11_10 = 0x31 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalVertexAttribType.cs b/Ryujinx.Graphics/Gal/GalVertexAttribType.cs deleted file mode 100644 index 358836fd..00000000 --- a/Ryujinx.Graphics/Gal/GalVertexAttribType.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalVertexAttribType - { - Snorm = 1, - Unorm = 2, - Sint = 3, - Uint = 4, - Uscaled = 5, - Sscaled = 6, - Float = 7 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalVertexBinding.cs b/Ryujinx.Graphics/Gal/GalVertexBinding.cs deleted file mode 100644 index 2337c2e3..00000000 --- a/Ryujinx.Graphics/Gal/GalVertexBinding.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public struct GalVertexBinding - { - // VboKey shouldn't be here, but ARB_vertex_attrib_binding is core since 4.3 - - public bool Enabled; - public int Stride; - public long VboKey; - public bool Instanced; - public int Divisor; - public GalVertexAttrib[] Attribs; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalZetaFormat.cs b/Ryujinx.Graphics/Gal/GalZetaFormat.cs deleted file mode 100644 index 2429249e..00000000 --- a/Ryujinx.Graphics/Gal/GalZetaFormat.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public enum GalZetaFormat - { - D32Float = 0x0a, - D16Unorm = 0x13, - S8D24Unorm = 0x14, - D24X8Unorm = 0x15, - D24S8Unorm = 0x16, - D24C8Unorm = 0x18, - D32S8X24Float = 0x19, - D24X8S8C8X16Unorm = 0x1d, - D32X8C8X16Float = 0x1e, - D32S8C8X16Float = 0x1f - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalConstBuffer.cs b/Ryujinx.Graphics/Gal/IGalConstBuffer.cs deleted file mode 100644 index 8c4e6d03..00000000 --- a/Ryujinx.Graphics/Gal/IGalConstBuffer.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Gal -{ - public interface IGalConstBuffer - { - void LockCache(); - void UnlockCache(); - - void Create(long key, long size); - - bool IsCached(long key, long size); - - void SetData(long key, long size, IntPtr hostAddress); - void SetData(long key, byte[] data); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalMemory.cs b/Ryujinx.Graphics/Gal/IGalMemory.cs deleted file mode 100644 index 78eb7154..00000000 --- a/Ryujinx.Graphics/Gal/IGalMemory.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public interface IGalMemory - { - int ReadInt32(long position); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalPipeline.cs b/Ryujinx.Graphics/Gal/IGalPipeline.cs deleted file mode 100644 index 1ecb2602..00000000 --- a/Ryujinx.Graphics/Gal/IGalPipeline.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public interface IGalPipeline - { - void Bind(GalPipelineState state); - void Unbind(GalPipelineState state); - - void ResetDepthMask(); - void ResetColorMask(int index); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalRasterizer.cs b/Ryujinx.Graphics/Gal/IGalRasterizer.cs deleted file mode 100644 index 33bdeaad..00000000 --- a/Ryujinx.Graphics/Gal/IGalRasterizer.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Gal -{ - public interface IGalRasterizer - { - void LockCaches(); - void UnlockCaches(); - - void ClearBuffers( - GalClearBufferFlags flags, - int attachment, - float red, - float green, - float blue, - float alpha, - float depth, - int stencil); - - bool IsVboCached(long key, long dataSize); - - bool IsIboCached(long key, long dataSize); - - void CreateVbo(long key, int dataSize, IntPtr hostAddress); - void CreateVbo(long key, byte[] data); - - void CreateIbo(long key, int dataSize, IntPtr hostAddress); - void CreateIbo(long key, int dataSize, byte[] buffer); - - void SetIndexArray(int size, GalIndexFormat format); - - void DrawArrays(int first, int count, GalPrimitiveType primType); - - void DrawElements(long iboKey, int first, int vertexBase, GalPrimitiveType primType); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalRenderTarget.cs b/Ryujinx.Graphics/Gal/IGalRenderTarget.cs deleted file mode 100644 index c281fe06..00000000 --- a/Ryujinx.Graphics/Gal/IGalRenderTarget.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public interface IGalRenderTarget - { - void Bind(); - - void BindColor(long key, int attachment); - - void UnbindColor(int attachment); - - void BindZeta(long key); - - void UnbindZeta(); - - void Present(long key); - - void SetMap(int[] map); - - void SetTransform(bool flipX, bool flipY, int top, int left, int right, int bottom); - - void SetWindowSize(int width, int height); - - void SetViewport(int attachment, int x, int y, int width, int height); - - void Render(); - - void Copy( - GalImage srcImage, - GalImage dstImage, - long srcKey, - long dstKey, - int srcLayer, - int dstLayer, - int srcX0, - int srcY0, - int srcX1, - int srcY1, - int dstX0, - int dstY0, - int dstX1, - int dstY1); - - void Reinterpret(long key, GalImage newImage); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalRenderer.cs b/Ryujinx.Graphics/Gal/IGalRenderer.cs deleted file mode 100644 index 1acc4d03..00000000 --- a/Ryujinx.Graphics/Gal/IGalRenderer.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Gal -{ - public interface IGalRenderer - { - void QueueAction(Action actionMthd); - - void RunActions(); - - IGalConstBuffer Buffer { get; } - - IGalRenderTarget RenderTarget { get; } - - IGalRasterizer Rasterizer { get; } - - IGalShader Shader { get; } - - IGalPipeline Pipeline { get; } - - IGalTexture Texture { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalShader.cs b/Ryujinx.Graphics/Gal/IGalShader.cs deleted file mode 100644 index 6a9abe75..00000000 --- a/Ryujinx.Graphics/Gal/IGalShader.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Ryujinx.Graphics.Shader; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Gal -{ - public interface IGalShader - { - void Create(IGalMemory memory, long key, GalShaderType type); - - void Create(IGalMemory memory, long vpAPos, long key, GalShaderType type); - - IEnumerable<CBufferDescriptor> GetConstBufferUsage(long key); - IEnumerable<TextureDescriptor> GetTextureUsage(long key); - - void Bind(long key); - - void Unbind(GalShaderType type); - - void BindProgram(); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalTexture.cs b/Ryujinx.Graphics/Gal/IGalTexture.cs deleted file mode 100644 index 23ce054a..00000000 --- a/Ryujinx.Graphics/Gal/IGalTexture.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Graphics.Gal -{ - public interface IGalTexture - { - void LockCache(); - void UnlockCache(); - - void Create(long key, int size, GalImage image); - - void Create(long key, byte[] data, GalImage image); - - bool TryGetImage(long key, out GalImage image); - - void Bind(long key, int index, GalImage image); - - void SetSampler(GalImage image, GalTextureSampler sampler); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/DeleteValueCallback.cs b/Ryujinx.Graphics/Gal/OpenGL/DeleteValueCallback.cs deleted file mode 100644 index 63b626f1..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/DeleteValueCallback.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Ryujinx.Graphics.Gal.OpenGL -{ - delegate void DeleteValue<T>(T value); -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs deleted file mode 100644 index d7f6f004..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Ryujinx.Graphics.Texture; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - class ImageHandler - { - public GalImage Image { get; private set; } - - public int Width => Image.Width; - public int Height => Image.Height; - public int Depth => Image.Depth; - - public GalImageFormat Format => Image.Format; - - public int Handle { get; private set; } - - public bool HasColor => ImageUtils.HasColor(Image.Format); - public bool HasDepth => ImageUtils.HasDepth(Image.Format); - public bool HasStencil => ImageUtils.HasStencil(Image.Format); - - public ImageHandler(int handle, GalImage image) - { - Handle = handle; - Image = image; - } - } -} diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglCachedResource.cs b/Ryujinx.Graphics/Gal/OpenGL/OglCachedResource.cs deleted file mode 100644 index 91f0a7e1..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglCachedResource.cs +++ /dev/null @@ -1,191 +0,0 @@ -using Ryujinx.Common; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - class OglCachedResource<T> - { - public delegate void DeleteValue(T value); - - private const int MinTimeDelta = 5 * 60000; - private const int MaxRemovalsPerRun = 10; - - private struct CacheBucket - { - public T Value { get; private set; } - - public LinkedListNode<long> Node { get; private set; } - - public long DataSize { get; private set; } - - public long Timestamp { get; private set; } - - public CacheBucket(T value, long dataSize, LinkedListNode<long> node) - { - Value = value; - DataSize = dataSize; - Node = node; - - Timestamp = PerformanceCounter.ElapsedMilliseconds; - } - } - - private Dictionary<long, CacheBucket> _cache; - - private LinkedList<long> _sortedCache; - - private DeleteValue _deleteValueCallback; - - private Queue<T> _deletePending; - - private bool _locked; - - private long _maxSize; - private long _totalSize; - - public OglCachedResource(DeleteValue deleteValueCallback, long maxSize) - { - _maxSize = maxSize; - - if (deleteValueCallback == null) - { - throw new ArgumentNullException(nameof(deleteValueCallback)); - } - - _deleteValueCallback = deleteValueCallback; - - _cache = new Dictionary<long, CacheBucket>(); - - _sortedCache = new LinkedList<long>(); - - _deletePending = new Queue<T>(); - } - - public void Lock() - { - _locked = true; - } - - public void Unlock() - { - _locked = false; - - while (_deletePending.TryDequeue(out T value)) - { - _deleteValueCallback(value); - } - - ClearCacheIfNeeded(); - } - - public void AddOrUpdate(long key, T value, long size) - { - if (!_locked) - { - ClearCacheIfNeeded(); - } - - LinkedListNode<long> node = _sortedCache.AddLast(key); - - CacheBucket newBucket = new CacheBucket(value, size, node); - - if (_cache.TryGetValue(key, out CacheBucket bucket)) - { - if (_locked) - { - _deletePending.Enqueue(bucket.Value); - } - else - { - _deleteValueCallback(bucket.Value); - } - - _sortedCache.Remove(bucket.Node); - - _totalSize -= bucket.DataSize; - - _cache[key] = newBucket; - } - else - { - _cache.Add(key, newBucket); - } - - _totalSize += size; - } - - public bool TryGetValue(long key, out T value) - { - if (_cache.TryGetValue(key, out CacheBucket bucket)) - { - value = bucket.Value; - - _sortedCache.Remove(bucket.Node); - - LinkedListNode<long> node = _sortedCache.AddLast(key); - - _cache[key] = new CacheBucket(value, bucket.DataSize, node); - - return true; - } - - value = default(T); - - return false; - } - - public bool TryGetSize(long key, out long size) - { - if (_cache.TryGetValue(key, out CacheBucket bucket)) - { - size = bucket.DataSize; - - return true; - } - - size = 0; - - return false; - } - - private void ClearCacheIfNeeded() - { - long timestamp = PerformanceCounter.ElapsedMilliseconds; - - int count = 0; - - while (count++ < MaxRemovalsPerRun) - { - LinkedListNode<long> node = _sortedCache.First; - - if (node == null) - { - break; - } - - CacheBucket bucket = _cache[node.Value]; - - long timeDelta = timestamp - bucket.Timestamp; - - if (timeDelta <= MinTimeDelta && !UnderMemoryPressure()) - { - break; - } - - _sortedCache.Remove(node); - - _cache.Remove(node.Value); - - _deleteValueCallback(bucket.Value); - - _totalSize -= bucket.DataSize; - } - } - - private bool UnderMemoryPressure() - { - return _totalSize >= _maxSize; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglConstBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OglConstBuffer.cs deleted file mode 100644 index e076be33..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglConstBuffer.cs +++ /dev/null @@ -1,74 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using System; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - class OglConstBuffer : IGalConstBuffer - { - private const long MaxConstBufferCacheSize = 64 * 1024 * 1024; - - private OglCachedResource<OglStreamBuffer> _cache; - - public OglConstBuffer() - { - _cache = new OglCachedResource<OglStreamBuffer>(DeleteBuffer, MaxConstBufferCacheSize); - } - - public void LockCache() - { - _cache.Lock(); - } - - public void UnlockCache() - { - _cache.Unlock(); - } - - public void Create(long key, long size) - { - OglStreamBuffer buffer = new OglStreamBuffer(BufferTarget.UniformBuffer, size); - - _cache.AddOrUpdate(key, buffer, size); - } - - public bool IsCached(long key, long size) - { - return _cache.TryGetSize(key, out long cachedSize) && cachedSize == size; - } - - public void SetData(long key, long size, IntPtr hostAddress) - { - if (_cache.TryGetValue(key, out OglStreamBuffer buffer)) - { - buffer.SetData(size, hostAddress); - } - } - - public void SetData(long key, byte[] data) - { - if (_cache.TryGetValue(key, out OglStreamBuffer buffer)) - { - buffer.SetData(data); - } - } - - public bool TryGetUbo(long key, out int uboHandle) - { - if (_cache.TryGetValue(key, out OglStreamBuffer buffer)) - { - uboHandle = buffer.Handle; - - return true; - } - - uboHandle = 0; - - return false; - } - - private static void DeleteBuffer(OglStreamBuffer buffer) - { - buffer.Dispose(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OglEnumConverter.cs deleted file mode 100644 index c36d8bf9..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglEnumConverter.cs +++ /dev/null @@ -1,427 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using System; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - static class OglEnumConverter - { - public static FrontFaceDirection GetFrontFace(GalFrontFace frontFace) - { - switch (frontFace) - { - case GalFrontFace.Cw: return FrontFaceDirection.Cw; - case GalFrontFace.Ccw: return FrontFaceDirection.Ccw; - } - - throw new ArgumentException(nameof(frontFace) + " \"" + frontFace + "\" is not valid!"); - } - - public static CullFaceMode GetCullFace(GalCullFace cullFace) - { - switch (cullFace) - { - case GalCullFace.Front: return CullFaceMode.Front; - case GalCullFace.Back: return CullFaceMode.Back; - case GalCullFace.FrontAndBack: return CullFaceMode.FrontAndBack; - } - - throw new ArgumentException(nameof(cullFace) + " \"" + cullFace + "\" is not valid!"); - } - - public static StencilOp GetStencilOp(GalStencilOp op) - { - switch (op) - { - case GalStencilOp.Keep: return StencilOp.Keep; - case GalStencilOp.Zero: return StencilOp.Zero; - case GalStencilOp.Replace: return StencilOp.Replace; - case GalStencilOp.Incr: return StencilOp.Incr; - case GalStencilOp.Decr: return StencilOp.Decr; - case GalStencilOp.Invert: return StencilOp.Invert; - case GalStencilOp.IncrWrap: return StencilOp.IncrWrap; - case GalStencilOp.DecrWrap: return StencilOp.DecrWrap; - } - - throw new ArgumentException(nameof(op) + " \"" + op + "\" is not valid!"); - } - - public static DepthFunction GetDepthFunc(GalComparisonOp func) - { - return (DepthFunction)GetFunc(func); - } - - public static StencilFunction GetStencilFunc(GalComparisonOp func) - { - return (StencilFunction)GetFunc(func); - } - - private static All GetFunc(GalComparisonOp func) - { - if ((int)func >= (int)All.Never && - (int)func <= (int)All.Always) - { - return (All)func; - } - - switch (func) - { - case GalComparisonOp.Never: return All.Never; - case GalComparisonOp.Less: return All.Less; - case GalComparisonOp.Equal: return All.Equal; - case GalComparisonOp.Lequal: return All.Lequal; - case GalComparisonOp.Greater: return All.Greater; - case GalComparisonOp.NotEqual: return All.Notequal; - case GalComparisonOp.Gequal: return All.Gequal; - case GalComparisonOp.Always: return All.Always; - } - - throw new ArgumentException(nameof(func) + " \"" + func + "\" is not valid!"); - } - - public static DrawElementsType GetDrawElementsType(GalIndexFormat format) - { - switch (format) - { - case GalIndexFormat.Byte: return DrawElementsType.UnsignedByte; - case GalIndexFormat.Int16: return DrawElementsType.UnsignedShort; - case GalIndexFormat.Int32: return DrawElementsType.UnsignedInt; - } - - throw new ArgumentException(nameof(format) + " \"" + format + "\" is not valid!"); - } - - public static PrimitiveType GetPrimitiveType(GalPrimitiveType type) - { - switch (type) - { - case GalPrimitiveType.Points: return PrimitiveType.Points; - case GalPrimitiveType.Lines: return PrimitiveType.Lines; - case GalPrimitiveType.LineLoop: return PrimitiveType.LineLoop; - case GalPrimitiveType.LineStrip: return PrimitiveType.LineStrip; - case GalPrimitiveType.Triangles: return PrimitiveType.Triangles; - case GalPrimitiveType.TriangleStrip: return PrimitiveType.TriangleStrip; - case GalPrimitiveType.TriangleFan: return PrimitiveType.TriangleFan; - case GalPrimitiveType.Polygon: return PrimitiveType.Polygon; - case GalPrimitiveType.LinesAdjacency: return PrimitiveType.LinesAdjacency; - case GalPrimitiveType.LineStripAdjacency: return PrimitiveType.LineStripAdjacency; - case GalPrimitiveType.TrianglesAdjacency: return PrimitiveType.TrianglesAdjacency; - case GalPrimitiveType.TriangleStripAdjacency: return PrimitiveType.TriangleStripAdjacency; - case GalPrimitiveType.Patches: return PrimitiveType.Patches; - } - - throw new ArgumentException(nameof(type) + " \"" + type + "\" is not valid!"); - } - - public static ShaderType GetShaderType(GalShaderType type) - { - switch (type) - { - case GalShaderType.Vertex: return ShaderType.VertexShader; - case GalShaderType.TessControl: return ShaderType.TessControlShader; - case GalShaderType.TessEvaluation: return ShaderType.TessEvaluationShader; - case GalShaderType.Geometry: return ShaderType.GeometryShader; - case GalShaderType.Fragment: return ShaderType.FragmentShader; - } - - throw new ArgumentException(nameof(type) + " \"" + type + "\" is not valid!"); - } - - public static (PixelInternalFormat, PixelFormat, PixelType) GetImageFormat(GalImageFormat format) - { - switch (format) - { - case GalImageFormat.Rgba32 | GalImageFormat.Float: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); - case GalImageFormat.Rgba32 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int); - case GalImageFormat.Rgba32 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt); - case GalImageFormat.Rgba16 | GalImageFormat.Float: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat); - case GalImageFormat.Rgba16 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short); - case GalImageFormat.Rgba16 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort); - case GalImageFormat.Rgba16 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba16, PixelFormat.Rgba, PixelType.UnsignedShort); - case GalImageFormat.Rg32 | GalImageFormat.Float: return (PixelInternalFormat.Rg32f, PixelFormat.Rg, PixelType.Float); - case GalImageFormat.Rg32 | GalImageFormat.Sint: return (PixelInternalFormat.Rg32i, PixelFormat.RgInteger, PixelType.Int); - case GalImageFormat.Rg32 | GalImageFormat.Uint: return (PixelInternalFormat.Rg32ui, PixelFormat.RgInteger, PixelType.UnsignedInt); - case GalImageFormat.Rgbx8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb8, PixelFormat.Rgba, PixelType.UnsignedByte); - case GalImageFormat.Rgba8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rgba8Snorm, PixelFormat.Rgba, PixelType.Byte); - case GalImageFormat.Rgba8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); - case GalImageFormat.Rgba8 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte); - case GalImageFormat.Rgba8 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte); - case GalImageFormat.Rgba8 | GalImageFormat.Srgb: return (PixelInternalFormat.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte); - case GalImageFormat.Bgra8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba8, PixelFormat.Bgra, PixelType.UnsignedByte); - case GalImageFormat.Bgra8 | GalImageFormat.Srgb: return (PixelInternalFormat.Srgb8Alpha8, PixelFormat.Bgra, PixelType.UnsignedByte); - case GalImageFormat.Rgba4 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Reversed); - case GalImageFormat.Rgb10A2 | GalImageFormat.Uint: return (PixelInternalFormat.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed); - case GalImageFormat.Rgb10A2 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); - case GalImageFormat.R32 | GalImageFormat.Float: return (PixelInternalFormat.R32f, PixelFormat.Red, PixelType.Float); - case GalImageFormat.R32 | GalImageFormat.Sint: return (PixelInternalFormat.R32i, PixelFormat.Red, PixelType.Int); - case GalImageFormat.R32 | GalImageFormat.Uint: return (PixelInternalFormat.R32ui, PixelFormat.Red, PixelType.UnsignedInt); - case GalImageFormat.Bgr5A1 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551); - case GalImageFormat.Rgb5A1 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Reversed); - case GalImageFormat.Rgb565 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565Reversed); - case GalImageFormat.Bgr565 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565); - case GalImageFormat.Rg16 | GalImageFormat.Float: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); - case GalImageFormat.Rg16 | GalImageFormat.Sint: return (PixelInternalFormat.Rg16i, PixelFormat.RgInteger, PixelType.Short); - case GalImageFormat.Rg16 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg16Snorm, PixelFormat.Rg, PixelType.Short); - case GalImageFormat.Rg16 | GalImageFormat.Uint: return (PixelInternalFormat.Rg16ui, PixelFormat.RgInteger, PixelType.UnsignedShort); - case GalImageFormat.Rg16 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg16, PixelFormat.Rg, PixelType.UnsignedShort); - case GalImageFormat.Rg8 | GalImageFormat.Sint: return (PixelInternalFormat.Rg8i, PixelFormat.RgInteger, PixelType.Byte); - case GalImageFormat.Rg8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg8Snorm, PixelFormat.Rg, PixelType.Byte); - case GalImageFormat.Rg8 | GalImageFormat.Uint: return (PixelInternalFormat.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte); - case GalImageFormat.Rg8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); - case GalImageFormat.R16 | GalImageFormat.Float: return (PixelInternalFormat.R16f, PixelFormat.Red, PixelType.HalfFloat); - case GalImageFormat.R16 | GalImageFormat.Sint: return (PixelInternalFormat.R16i, PixelFormat.RedInteger, PixelType.Short); - case GalImageFormat.R16 | GalImageFormat.Snorm: return (PixelInternalFormat.R16Snorm, PixelFormat.Red, PixelType.Short); - case GalImageFormat.R16 | GalImageFormat.Uint: return (PixelInternalFormat.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort); - case GalImageFormat.R16 | GalImageFormat.Unorm: return (PixelInternalFormat.R16, PixelFormat.Red, PixelType.UnsignedShort); - case GalImageFormat.R8 | GalImageFormat.Sint: return (PixelInternalFormat.R8i, PixelFormat.RedInteger, PixelType.Byte); - case GalImageFormat.R8 | GalImageFormat.Snorm: return (PixelInternalFormat.R8Snorm, PixelFormat.Red, PixelType.Byte); - case GalImageFormat.R8 | GalImageFormat.Uint: return (PixelInternalFormat.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte); - case GalImageFormat.R8 | GalImageFormat.Unorm: return (PixelInternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte); - case GalImageFormat.R11G11B10 | GalImageFormat.Float: return (PixelInternalFormat.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); - - case GalImageFormat.D16 | GalImageFormat.Unorm: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort); - case GalImageFormat.D24 | GalImageFormat.Unorm: return (PixelInternalFormat.DepthComponent24, PixelFormat.DepthComponent, PixelType.UnsignedInt); - case GalImageFormat.D24S8 | GalImageFormat.Uint: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); - case GalImageFormat.D24S8 | GalImageFormat.Unorm: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); - case GalImageFormat.D32 | GalImageFormat.Float: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); - case GalImageFormat.D32S8 | GalImageFormat.Float: return (PixelInternalFormat.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev); - } - - throw new NotImplementedException($"{format & GalImageFormat.FormatMask} {format & GalImageFormat.TypeMask}"); - } - - public static All GetDepthCompareFunc(DepthCompareFunc depthCompareFunc) - { - switch (depthCompareFunc) - { - case DepthCompareFunc.LEqual: - return All.Lequal; - case DepthCompareFunc.GEqual: - return All.Gequal; - case DepthCompareFunc.Less: - return All.Less; - case DepthCompareFunc.Greater: - return All.Greater; - case DepthCompareFunc.Equal: - return All.Equal; - case DepthCompareFunc.NotEqual: - return All.Notequal; - case DepthCompareFunc.Always: - return All.Always; - case DepthCompareFunc.Never: - return All.Never; - default: - throw new ArgumentException(nameof(depthCompareFunc) + " \"" + depthCompareFunc + "\" is not valid!"); - } - } - - public static InternalFormat GetCompressedImageFormat(GalImageFormat format) - { - switch (format) - { - case GalImageFormat.BptcSfloat | GalImageFormat.Float: return InternalFormat.CompressedRgbBptcSignedFloat; - case GalImageFormat.BptcUfloat | GalImageFormat.Float: return InternalFormat.CompressedRgbBptcUnsignedFloat; - case GalImageFormat.BptcUnorm | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaBptcUnorm; - case GalImageFormat.BptcUnorm | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaBptcUnorm; - case GalImageFormat.BC1 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt1Ext; - case GalImageFormat.BC1 | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaS3tcDxt1Ext; - case GalImageFormat.BC2 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt3Ext; - case GalImageFormat.BC2 | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaS3tcDxt3Ext; - case GalImageFormat.BC3 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt5Ext; - case GalImageFormat.BC3 | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaS3tcDxt5Ext; - case GalImageFormat.BC4 | GalImageFormat.Snorm: return InternalFormat.CompressedSignedRedRgtc1; - case GalImageFormat.BC4 | GalImageFormat.Unorm: return InternalFormat.CompressedRedRgtc1; - case GalImageFormat.BC5 | GalImageFormat.Snorm: return InternalFormat.CompressedSignedRgRgtc2; - case GalImageFormat.BC5 | GalImageFormat.Unorm: return InternalFormat.CompressedRgRgtc2; - } - - throw new NotImplementedException($"{format & GalImageFormat.FormatMask} {format & GalImageFormat.TypeMask}"); - } - - public static All GetTextureSwizzle(GalTextureSource source) - { - switch (source) - { - case GalTextureSource.Zero: return All.Zero; - case GalTextureSource.Red: return All.Red; - case GalTextureSource.Green: return All.Green; - case GalTextureSource.Blue: return All.Blue; - case GalTextureSource.Alpha: return All.Alpha; - case GalTextureSource.OneInt: return All.One; - case GalTextureSource.OneFloat: return All.One; - } - - throw new ArgumentException(nameof(source) + " \"" + source + "\" is not valid!"); - } - - public static TextureWrapMode GetTextureWrapMode(GalTextureWrap wrap) - { - switch (wrap) - { - case GalTextureWrap.Repeat: return TextureWrapMode.Repeat; - case GalTextureWrap.MirroredRepeat: return TextureWrapMode.MirroredRepeat; - case GalTextureWrap.ClampToEdge: return TextureWrapMode.ClampToEdge; - case GalTextureWrap.ClampToBorder: return TextureWrapMode.ClampToBorder; - case GalTextureWrap.Clamp: return TextureWrapMode.Clamp; - } - - if (OglExtension.TextureMirrorClamp) - { - switch (wrap) - { - case GalTextureWrap.MirrorClampToEdge: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToEdgeExt; - case GalTextureWrap.MirrorClampToBorder: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToBorderExt; - case GalTextureWrap.MirrorClamp: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampExt; - } - } - else - { - // Fallback to non-mirrored clamps - switch (wrap) - { - case GalTextureWrap.MirrorClampToEdge: return TextureWrapMode.ClampToEdge; - case GalTextureWrap.MirrorClampToBorder: return TextureWrapMode.ClampToBorder; - case GalTextureWrap.MirrorClamp: return TextureWrapMode.Clamp; - } - } - - throw new ArgumentException(nameof(wrap) + " \"" + wrap + "\" is not valid!"); - } - - public static TextureMinFilter GetTextureMinFilter( - GalTextureFilter minFilter, - GalTextureMipFilter mipFilter) - { - // TODO: Mip (needs mipmap support first). - switch (minFilter) - { - case GalTextureFilter.Nearest: return TextureMinFilter.Nearest; - case GalTextureFilter.Linear: return TextureMinFilter.Linear; - } - - throw new ArgumentException(nameof(minFilter) + " \"" + minFilter + "\" is not valid!"); - } - - public static TextureMagFilter GetTextureMagFilter(GalTextureFilter filter) - { - switch (filter) - { - case GalTextureFilter.Nearest: return TextureMagFilter.Nearest; - case GalTextureFilter.Linear: return TextureMagFilter.Linear; - } - - throw new ArgumentException(nameof(filter) + " \"" + filter + "\" is not valid!"); - } - - public static BlendEquationMode GetBlendEquation(GalBlendEquation blendEquation) - { - switch (blendEquation) - { - case GalBlendEquation.FuncAdd: - case GalBlendEquation.FuncAddGl: - return BlendEquationMode.FuncAdd; - - case GalBlendEquation.FuncSubtract: - case GalBlendEquation.FuncSubtractGl: - return BlendEquationMode.FuncSubtract; - - case GalBlendEquation.FuncReverseSubtract: - case GalBlendEquation.FuncReverseSubtractGl: - return BlendEquationMode.FuncReverseSubtract; - - case GalBlendEquation.Min: - case GalBlendEquation.MinGl: - return BlendEquationMode.Min; - - case GalBlendEquation.Max: - case GalBlendEquation.MaxGl: - return BlendEquationMode.Max; - } - - throw new ArgumentException(nameof(blendEquation) + " \"" + blendEquation + "\" is not valid!"); - } - - public static BlendingFactor GetBlendFactor(GalBlendFactor blendFactor) - { - switch (blendFactor) - { - case GalBlendFactor.Zero: - case GalBlendFactor.ZeroGl: - return BlendingFactor.Zero; - - case GalBlendFactor.One: - case GalBlendFactor.OneGl: - return BlendingFactor.One; - - case GalBlendFactor.SrcColor: - case GalBlendFactor.SrcColorGl: - return BlendingFactor.SrcColor; - - case GalBlendFactor.OneMinusSrcColor: - case GalBlendFactor.OneMinusSrcColorGl: - return BlendingFactor.OneMinusSrcColor; - - case GalBlendFactor.DstColor: - case GalBlendFactor.DstColorGl: - return BlendingFactor.DstColor; - - case GalBlendFactor.OneMinusDstColor: - case GalBlendFactor.OneMinusDstColorGl: - return BlendingFactor.OneMinusDstColor; - - case GalBlendFactor.SrcAlpha: - case GalBlendFactor.SrcAlphaGl: - return BlendingFactor.SrcAlpha; - - case GalBlendFactor.OneMinusSrcAlpha: - case GalBlendFactor.OneMinusSrcAlphaGl: - return BlendingFactor.OneMinusSrcAlpha; - - case GalBlendFactor.DstAlpha: - case GalBlendFactor.DstAlphaGl: - return BlendingFactor.DstAlpha; - - case GalBlendFactor.OneMinusDstAlpha: - case GalBlendFactor.OneMinusDstAlphaGl: - return BlendingFactor.OneMinusDstAlpha; - - case GalBlendFactor.OneMinusConstantColor: - case GalBlendFactor.OneMinusConstantColorGl: - return BlendingFactor.OneMinusConstantColor; - - case GalBlendFactor.ConstantAlpha: - case GalBlendFactor.ConstantAlphaGl: - return BlendingFactor.ConstantAlpha; - - case GalBlendFactor.OneMinusConstantAlpha: - case GalBlendFactor.OneMinusConstantAlphaGl: - return BlendingFactor.OneMinusConstantAlpha; - - case GalBlendFactor.SrcAlphaSaturate: - case GalBlendFactor.SrcAlphaSaturateGl: - return BlendingFactor.SrcAlphaSaturate; - - case GalBlendFactor.Src1Color: - case GalBlendFactor.Src1ColorGl: - return BlendingFactor.Src1Color; - - case GalBlendFactor.OneMinusSrc1Color: - case GalBlendFactor.OneMinusSrc1ColorGl: - return (BlendingFactor)BlendingFactorSrc.OneMinusSrc1Color; - - case GalBlendFactor.Src1Alpha: - case GalBlendFactor.Src1AlphaGl: - return BlendingFactor.Src1Alpha; - - case GalBlendFactor.OneMinusSrc1Alpha: - case GalBlendFactor.OneMinusSrc1AlphaGl: - return (BlendingFactor)BlendingFactorSrc.OneMinusSrc1Alpha; - - case GalBlendFactor.ConstantColor: - case GalBlendFactor.ConstantColorGl: - return BlendingFactor.ConstantColor; - } - - throw new ArgumentException(nameof(blendFactor) + " \"" + blendFactor + "\" is not valid!"); - } - } -} diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglExtension.cs b/Ryujinx.Graphics/Gal/OpenGL/OglExtension.cs deleted file mode 100644 index 8a1a0510..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglExtension.cs +++ /dev/null @@ -1,70 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Common.Logging; -using System; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - static class OglExtension - { - // Private lazy backing variables - private static Lazy<bool> _enhancedLayouts = new Lazy<bool>(() => HasExtension("GL_ARB_enhanced_layouts")); - private static Lazy<bool> _textureMirrorClamp = new Lazy<bool>(() => HasExtension("GL_EXT_texture_mirror_clamp")); - private static Lazy<bool> _viewportArray = new Lazy<bool>(() => HasExtension("GL_ARB_viewport_array")); - - private static Lazy<bool> _nvidiaDriver = new Lazy<bool>(() => IsNvidiaDriver()); - - // Public accessors - public static bool EnhancedLayouts => _enhancedLayouts.Value; - public static bool TextureMirrorClamp => _textureMirrorClamp.Value; - public static bool ViewportArray => _viewportArray.Value; - - public static bool NvidiaDriver => _nvidiaDriver.Value; - - private static bool HasExtension(string name) - { - int numExtensions = GL.GetInteger(GetPName.NumExtensions); - - for (int extension = 0; extension < numExtensions; extension++) - { - if (GL.GetString(StringNameIndexed.Extensions, extension) == name) - { - return true; - } - } - - Logger.PrintInfo(LogClass.Gpu, $"OpenGL extension {name} unavailable. You may experience some performance degradation"); - - return false; - } - - private static bool IsNvidiaDriver() - { - return GL.GetString(StringName.Vendor).Equals("NVIDIA Corporation"); - } - - public static class Required - { - // Public accessors - public static bool EnhancedLayouts => _enhancedLayoutsRequired.Value; - public static bool TextureMirrorClamp => _textureMirrorClampRequired.Value; - public static bool ViewportArray => _viewportArrayRequired.Value; - - // Private lazy backing variables - private static Lazy<bool> _enhancedLayoutsRequired = new Lazy<bool>(() => HasExtensionRequired(OglExtension.EnhancedLayouts, "GL_ARB_enhanced_layouts")); - private static Lazy<bool> _textureMirrorClampRequired = new Lazy<bool>(() => HasExtensionRequired(OglExtension.TextureMirrorClamp, "GL_EXT_texture_mirror_clamp")); - private static Lazy<bool> _viewportArrayRequired = new Lazy<bool>(() => HasExtensionRequired(OglExtension.ViewportArray, "GL_ARB_viewport_array")); - - private static bool HasExtensionRequired(bool value, string name) - { - if (value) - { - return true; - } - - Logger.PrintWarning(LogClass.Gpu, $"Required OpenGL extension {name} unavailable. You may experience some rendering issues"); - - return false; - } - } - } -} diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglLimit.cs b/Ryujinx.Graphics/Gal/OpenGL/OglLimit.cs deleted file mode 100644 index 2a227a37..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglLimit.cs +++ /dev/null @@ -1,12 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using System; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - static class OglLimit - { - private static Lazy<int> _sMaxUboSize = new Lazy<int>(() => GL.GetInteger(GetPName.MaxUniformBlockSize)); - - public static int MaxUboSize => _sMaxUboSize.Value; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglPipeline.cs b/Ryujinx.Graphics/Gal/OpenGL/OglPipeline.cs deleted file mode 100644 index 8d886be4..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglPipeline.cs +++ /dev/null @@ -1,833 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.Shader; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - class OglPipeline : IGalPipeline - { - private static Dictionary<GalVertexAttribSize, int> _attribElements = - new Dictionary<GalVertexAttribSize, int>() - { - { GalVertexAttribSize._32_32_32_32, 4 }, - { GalVertexAttribSize._32_32_32, 3 }, - { GalVertexAttribSize._16_16_16_16, 4 }, - { GalVertexAttribSize._32_32, 2 }, - { GalVertexAttribSize._16_16_16, 3 }, - { GalVertexAttribSize._8_8_8_8, 4 }, - { GalVertexAttribSize._16_16, 2 }, - { GalVertexAttribSize._32, 1 }, - { GalVertexAttribSize._8_8_8, 3 }, - { GalVertexAttribSize._8_8, 2 }, - { GalVertexAttribSize._16, 1 }, - { GalVertexAttribSize._8, 1 }, - { GalVertexAttribSize._10_10_10_2, 4 }, - { GalVertexAttribSize._11_11_10, 3 } - }; - - private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> _floatAttribTypes = - new Dictionary<GalVertexAttribSize, VertexAttribPointerType>() - { - { GalVertexAttribSize._32_32_32_32, VertexAttribPointerType.Float }, - { GalVertexAttribSize._32_32_32, VertexAttribPointerType.Float }, - { GalVertexAttribSize._16_16_16_16, VertexAttribPointerType.HalfFloat }, - { GalVertexAttribSize._32_32, VertexAttribPointerType.Float }, - { GalVertexAttribSize._16_16_16, VertexAttribPointerType.HalfFloat }, - { GalVertexAttribSize._16_16, VertexAttribPointerType.HalfFloat }, - { GalVertexAttribSize._32, VertexAttribPointerType.Float }, - { GalVertexAttribSize._16, VertexAttribPointerType.HalfFloat } - }; - - private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> _signedAttribTypes = - new Dictionary<GalVertexAttribSize, VertexAttribPointerType>() - { - { GalVertexAttribSize._32_32_32_32, VertexAttribPointerType.Int }, - { GalVertexAttribSize._32_32_32, VertexAttribPointerType.Int }, - { GalVertexAttribSize._16_16_16_16, VertexAttribPointerType.Short }, - { GalVertexAttribSize._32_32, VertexAttribPointerType.Int }, - { GalVertexAttribSize._16_16_16, VertexAttribPointerType.Short }, - { GalVertexAttribSize._8_8_8_8, VertexAttribPointerType.Byte }, - { GalVertexAttribSize._16_16, VertexAttribPointerType.Short }, - { GalVertexAttribSize._32, VertexAttribPointerType.Int }, - { GalVertexAttribSize._8_8_8, VertexAttribPointerType.Byte }, - { GalVertexAttribSize._8_8, VertexAttribPointerType.Byte }, - { GalVertexAttribSize._16, VertexAttribPointerType.Short }, - { GalVertexAttribSize._8, VertexAttribPointerType.Byte }, - { GalVertexAttribSize._10_10_10_2, VertexAttribPointerType.Int2101010Rev } - }; - - private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> _unsignedAttribTypes = - new Dictionary<GalVertexAttribSize, VertexAttribPointerType>() - { - { GalVertexAttribSize._32_32_32_32, VertexAttribPointerType.UnsignedInt }, - { GalVertexAttribSize._32_32_32, VertexAttribPointerType.UnsignedInt }, - { GalVertexAttribSize._16_16_16_16, VertexAttribPointerType.UnsignedShort }, - { GalVertexAttribSize._32_32, VertexAttribPointerType.UnsignedInt }, - { GalVertexAttribSize._16_16_16, VertexAttribPointerType.UnsignedShort }, - { GalVertexAttribSize._8_8_8_8, VertexAttribPointerType.UnsignedByte }, - { GalVertexAttribSize._16_16, VertexAttribPointerType.UnsignedShort }, - { GalVertexAttribSize._32, VertexAttribPointerType.UnsignedInt }, - { GalVertexAttribSize._8_8_8, VertexAttribPointerType.UnsignedByte }, - { GalVertexAttribSize._8_8, VertexAttribPointerType.UnsignedByte }, - { GalVertexAttribSize._16, VertexAttribPointerType.UnsignedShort }, - { GalVertexAttribSize._8, VertexAttribPointerType.UnsignedByte }, - { GalVertexAttribSize._10_10_10_2, VertexAttribPointerType.UnsignedInt2101010Rev }, - { GalVertexAttribSize._11_11_10, VertexAttribPointerType.UnsignedInt10F11F11FRev } - }; - - private GalPipelineState _old; - - private OglConstBuffer _buffer; - private OglRenderTarget _renderTarget; - private OglRasterizer _rasterizer; - private OglShader _shader; - - private int _vaoHandle; - - public OglPipeline( - OglConstBuffer buffer, - OglRenderTarget renderTarget, - OglRasterizer rasterizer, - OglShader shader) - { - _buffer = buffer; - _renderTarget = renderTarget; - _rasterizer = rasterizer; - _shader = shader; - - // These values match OpenGL's defaults - _old = new GalPipelineState - { - FrontFace = GalFrontFace.Ccw, - - CullFaceEnabled = false, - CullFace = GalCullFace.Back, - - DepthTestEnabled = false, - DepthWriteEnabled = true, - DepthFunc = GalComparisonOp.Less, - DepthRangeNear = 0, - DepthRangeFar = 1, - - StencilTestEnabled = false, - - StencilBackFuncFunc = GalComparisonOp.Always, - StencilBackFuncRef = 0, - StencilBackFuncMask = UInt32.MaxValue, - StencilBackOpFail = GalStencilOp.Keep, - StencilBackOpZFail = GalStencilOp.Keep, - StencilBackOpZPass = GalStencilOp.Keep, - StencilBackMask = UInt32.MaxValue, - - StencilFrontFuncFunc = GalComparisonOp.Always, - StencilFrontFuncRef = 0, - StencilFrontFuncMask = UInt32.MaxValue, - StencilFrontOpFail = GalStencilOp.Keep, - StencilFrontOpZFail = GalStencilOp.Keep, - StencilFrontOpZPass = GalStencilOp.Keep, - StencilFrontMask = UInt32.MaxValue, - - BlendIndependent = false, - - PrimitiveRestartEnabled = false, - PrimitiveRestartIndex = 0 - }; - - for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++) - { - _old.Blends[index] = BlendState.Default; - - _old.ColorMasks[index] = ColorMaskState.Default; - } - } - - public void Bind(GalPipelineState New) - { - BindConstBuffers(New); - - BindVertexLayout(New); - - if (New.FramebufferSrgb != _old.FramebufferSrgb) - { - Enable(EnableCap.FramebufferSrgb, New.FramebufferSrgb); - - _renderTarget.FramebufferSrgb = New.FramebufferSrgb; - } - - if (New.FlipX != _old.FlipX || New.FlipY != _old.FlipY || New.Instance != _old.Instance) - { - _shader.SetExtraData(New.FlipX, New.FlipY, New.Instance); - } - - if (New.FrontFace != _old.FrontFace) - { - GL.FrontFace(OglEnumConverter.GetFrontFace(New.FrontFace)); - } - - if (New.CullFaceEnabled != _old.CullFaceEnabled) - { - Enable(EnableCap.CullFace, New.CullFaceEnabled); - } - - if (New.CullFaceEnabled) - { - if (New.CullFace != _old.CullFace) - { - GL.CullFace(OglEnumConverter.GetCullFace(New.CullFace)); - } - } - - if (New.DepthTestEnabled != _old.DepthTestEnabled) - { - Enable(EnableCap.DepthTest, New.DepthTestEnabled); - } - - if (New.DepthWriteEnabled != _old.DepthWriteEnabled) - { - GL.DepthMask(New.DepthWriteEnabled); - } - - if (New.DepthTestEnabled) - { - if (New.DepthFunc != _old.DepthFunc) - { - GL.DepthFunc(OglEnumConverter.GetDepthFunc(New.DepthFunc)); - } - } - - if (New.DepthRangeNear != _old.DepthRangeNear || - New.DepthRangeFar != _old.DepthRangeFar) - { - GL.DepthRange(New.DepthRangeNear, New.DepthRangeFar); - } - - if (New.StencilTestEnabled != _old.StencilTestEnabled) - { - Enable(EnableCap.StencilTest, New.StencilTestEnabled); - } - - if (New.StencilTwoSideEnabled != _old.StencilTwoSideEnabled) - { - Enable((EnableCap)All.StencilTestTwoSideExt, New.StencilTwoSideEnabled); - } - - if (New.StencilTestEnabled) - { - if (New.StencilBackFuncFunc != _old.StencilBackFuncFunc || - New.StencilBackFuncRef != _old.StencilBackFuncRef || - New.StencilBackFuncMask != _old.StencilBackFuncMask) - { - GL.StencilFuncSeparate( - StencilFace.Back, - OglEnumConverter.GetStencilFunc(New.StencilBackFuncFunc), - New.StencilBackFuncRef, - New.StencilBackFuncMask); - } - - if (New.StencilBackOpFail != _old.StencilBackOpFail || - New.StencilBackOpZFail != _old.StencilBackOpZFail || - New.StencilBackOpZPass != _old.StencilBackOpZPass) - { - GL.StencilOpSeparate( - StencilFace.Back, - OglEnumConverter.GetStencilOp(New.StencilBackOpFail), - OglEnumConverter.GetStencilOp(New.StencilBackOpZFail), - OglEnumConverter.GetStencilOp(New.StencilBackOpZPass)); - } - - if (New.StencilBackMask != _old.StencilBackMask) - { - GL.StencilMaskSeparate(StencilFace.Back, New.StencilBackMask); - } - - if (New.StencilFrontFuncFunc != _old.StencilFrontFuncFunc || - New.StencilFrontFuncRef != _old.StencilFrontFuncRef || - New.StencilFrontFuncMask != _old.StencilFrontFuncMask) - { - GL.StencilFuncSeparate( - StencilFace.Front, - OglEnumConverter.GetStencilFunc(New.StencilFrontFuncFunc), - New.StencilFrontFuncRef, - New.StencilFrontFuncMask); - } - - if (New.StencilFrontOpFail != _old.StencilFrontOpFail || - New.StencilFrontOpZFail != _old.StencilFrontOpZFail || - New.StencilFrontOpZPass != _old.StencilFrontOpZPass) - { - GL.StencilOpSeparate( - StencilFace.Front, - OglEnumConverter.GetStencilOp(New.StencilFrontOpFail), - OglEnumConverter.GetStencilOp(New.StencilFrontOpZFail), - OglEnumConverter.GetStencilOp(New.StencilFrontOpZPass)); - } - - if (New.StencilFrontMask != _old.StencilFrontMask) - { - GL.StencilMaskSeparate(StencilFace.Front, New.StencilFrontMask); - } - } - - - // Scissor Test - // All scissor test are disabled before drawing final framebuffer to screen so we don't need to handle disabling - // Skip if there are no scissor tests to enable - if (New.ScissorTestCount != 0) - { - int scissorsApplied = 0; - bool applyToAll = false; - - for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++) - { - if (New.ScissorTestEnabled[index]) - { - // If viewport arrays are unavailable apply first scissor test to all or - // there is only 1 scissor test and it's the first, the scissor test applies to all viewports - if (!OglExtension.Required.ViewportArray || (index == 0 && New.ScissorTestCount == 1)) - { - GL.Enable(EnableCap.ScissorTest); - applyToAll = true; - } - else - { - GL.Enable(IndexedEnableCap.ScissorTest, index); - } - - if (New.ScissorTestEnabled[index] != _old.ScissorTestEnabled[index] || - New.ScissorTestX[index] != _old.ScissorTestX[index] || - New.ScissorTestY[index] != _old.ScissorTestY[index] || - New.ScissorTestWidth[index] != _old.ScissorTestWidth[index] || - New.ScissorTestHeight[index] != _old.ScissorTestHeight[index]) - { - if (applyToAll) - { - GL.Scissor(New.ScissorTestX[index], New.ScissorTestY[index], - New.ScissorTestWidth[index], New.ScissorTestHeight[index]); - } - else - { - GL.ScissorIndexed(index, New.ScissorTestX[index], New.ScissorTestY[index], - New.ScissorTestWidth[index], New.ScissorTestHeight[index]); - } - } - - // If all scissor tests have been applied, or viewport arrays are unavailable we can skip remaining iterations - if (!OglExtension.Required.ViewportArray || ++scissorsApplied == New.ScissorTestCount) - { - break; - } - } - } - } - - - if (New.BlendIndependent) - { - for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++) - { - SetBlendState(index, New.Blends[index], _old.Blends[index]); - } - } - else - { - if (New.BlendIndependent != _old.BlendIndependent) - { - SetAllBlendState(New.Blends[0]); - } - else - { - SetBlendState(New.Blends[0], _old.Blends[0]); - } - } - - if (New.ColorMaskCommon) - { - if (New.ColorMaskCommon != _old.ColorMaskCommon || !New.ColorMasks[0].Equals(_old.ColorMasks[0])) - { - GL.ColorMask( - New.ColorMasks[0].Red, - New.ColorMasks[0].Green, - New.ColorMasks[0].Blue, - New.ColorMasks[0].Alpha); - } - } - else - { - for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++) - { - if (!New.ColorMasks[index].Equals(_old.ColorMasks[index])) - { - GL.ColorMask( - index, - New.ColorMasks[index].Red, - New.ColorMasks[index].Green, - New.ColorMasks[index].Blue, - New.ColorMasks[index].Alpha); - } - } - } - - if (New.PrimitiveRestartEnabled != _old.PrimitiveRestartEnabled) - { - Enable(EnableCap.PrimitiveRestart, New.PrimitiveRestartEnabled); - } - - if (New.PrimitiveRestartEnabled) - { - if (New.PrimitiveRestartIndex != _old.PrimitiveRestartIndex) - { - GL.PrimitiveRestartIndex(New.PrimitiveRestartIndex); - } - } - - _old = New; - } - - public void Unbind(GalPipelineState state) - { - if (state.ScissorTestCount > 0) - { - GL.Disable(EnableCap.ScissorTest); - } - } - - private void SetAllBlendState(BlendState New) - { - Enable(EnableCap.Blend, New.Enabled); - - if (New.Enabled) - { - if (New.SeparateAlpha) - { - GL.BlendEquationSeparate( - OglEnumConverter.GetBlendEquation(New.EquationRgb), - OglEnumConverter.GetBlendEquation(New.EquationAlpha)); - - GL.BlendFuncSeparate( - (BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcRgb), - (BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstRgb), - (BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcAlpha), - (BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstAlpha)); - } - else - { - GL.BlendEquation(OglEnumConverter.GetBlendEquation(New.EquationRgb)); - - GL.BlendFunc( - OglEnumConverter.GetBlendFactor(New.FuncSrcRgb), - OglEnumConverter.GetBlendFactor(New.FuncDstRgb)); - } - } - } - - private void SetBlendState(BlendState New, BlendState old) - { - if (New.Enabled != old.Enabled) - { - Enable(EnableCap.Blend, New.Enabled); - } - - if (New.Enabled) - { - if (New.SeparateAlpha) - { - if (New.EquationRgb != old.EquationRgb || - New.EquationAlpha != old.EquationAlpha) - { - GL.BlendEquationSeparate( - OglEnumConverter.GetBlendEquation(New.EquationRgb), - OglEnumConverter.GetBlendEquation(New.EquationAlpha)); - } - - if (New.FuncSrcRgb != old.FuncSrcRgb || - New.FuncDstRgb != old.FuncDstRgb || - New.FuncSrcAlpha != old.FuncSrcAlpha || - New.FuncDstAlpha != old.FuncDstAlpha) - { - GL.BlendFuncSeparate( - (BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcRgb), - (BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstRgb), - (BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcAlpha), - (BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstAlpha)); - } - } - else - { - if (New.EquationRgb != old.EquationRgb) - { - GL.BlendEquation(OglEnumConverter.GetBlendEquation(New.EquationRgb)); - } - - if (New.FuncSrcRgb != old.FuncSrcRgb || - New.FuncDstRgb != old.FuncDstRgb) - { - GL.BlendFunc( - OglEnumConverter.GetBlendFactor(New.FuncSrcRgb), - OglEnumConverter.GetBlendFactor(New.FuncDstRgb)); - } - } - } - } - - private void SetBlendState(int index, BlendState New, BlendState old) - { - if (New.Enabled != old.Enabled) - { - Enable(IndexedEnableCap.Blend, index, New.Enabled); - } - - if (New.Enabled) - { - if (New.SeparateAlpha) - { - if (New.EquationRgb != old.EquationRgb || - New.EquationAlpha != old.EquationAlpha) - { - GL.BlendEquationSeparate( - index, - OglEnumConverter.GetBlendEquation(New.EquationRgb), - OglEnumConverter.GetBlendEquation(New.EquationAlpha)); - } - - if (New.FuncSrcRgb != old.FuncSrcRgb || - New.FuncDstRgb != old.FuncDstRgb || - New.FuncSrcAlpha != old.FuncSrcAlpha || - New.FuncDstAlpha != old.FuncDstAlpha) - { - GL.BlendFuncSeparate( - index, - (BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcRgb), - (BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstRgb), - (BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcAlpha), - (BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstAlpha)); - } - } - else - { - if (New.EquationRgb != old.EquationRgb) - { - GL.BlendEquation(index, OglEnumConverter.GetBlendEquation(New.EquationRgb)); - } - - if (New.FuncSrcRgb != old.FuncSrcRgb || - New.FuncDstRgb != old.FuncDstRgb) - { - GL.BlendFunc( - index, - (BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcRgb), - (BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstRgb)); - } - } - } - } - - private void BindConstBuffers(GalPipelineState New) - { - int freeBinding = OglShader.ReservedCbufCount; - - void BindIfNotNull(OglShaderStage stage) - { - if (stage != null) - { - foreach (CBufferDescriptor desc in stage.ConstBufferUsage) - { - long key = New.ConstBufferKeys[(int)stage.Type][desc.Slot]; - - if (key != 0 && _buffer.TryGetUbo(key, out int uboHandle)) - { - GL.BindBufferBase(BufferRangeTarget.UniformBuffer, freeBinding, uboHandle); - } - - freeBinding++; - } - } - } - - BindIfNotNull(_shader.Current.Vertex); - BindIfNotNull(_shader.Current.TessControl); - BindIfNotNull(_shader.Current.TessEvaluation); - BindIfNotNull(_shader.Current.Geometry); - BindIfNotNull(_shader.Current.Fragment); - } - - private void BindVertexLayout(GalPipelineState New) - { - foreach (GalVertexBinding binding in New.VertexBindings) - { - if (!binding.Enabled || !_rasterizer.TryGetVbo(binding.VboKey, out int vboHandle)) - { - continue; - } - - if (_vaoHandle == 0) - { - _vaoHandle = GL.GenVertexArray(); - - // Vertex arrays shouldn't be used anywhere else in OpenGL's backend - // if you want to use it, move this line out of the if - GL.BindVertexArray(_vaoHandle); - } - - foreach (GalVertexAttrib attrib in binding.Attribs) - { - // Skip uninitialized attributes. - if (attrib.Size == 0) - { - continue; - } - - GL.BindBuffer(BufferTarget.ArrayBuffer, vboHandle); - - bool unsigned = - attrib.Type == GalVertexAttribType.Unorm || - attrib.Type == GalVertexAttribType.Uint || - attrib.Type == GalVertexAttribType.Uscaled; - - bool normalize = - attrib.Type == GalVertexAttribType.Snorm || - attrib.Type == GalVertexAttribType.Unorm; - - VertexAttribPointerType type = 0; - - if (attrib.Type == GalVertexAttribType.Float) - { - type = GetType(_floatAttribTypes, attrib); - } - else - { - if (unsigned) - { - type = GetType(_unsignedAttribTypes, attrib); - } - else - { - type = GetType(_signedAttribTypes, attrib); - } - } - - if (!_attribElements.TryGetValue(attrib.Size, out int size)) - { - throw new InvalidOperationException("Invalid attribute size \"" + attrib.Size + "\"!"); - } - - int offset = attrib.Offset; - - if (binding.Stride != 0) - { - GL.EnableVertexAttribArray(attrib.Index); - - if (attrib.Type == GalVertexAttribType.Sint || - attrib.Type == GalVertexAttribType.Uint) - { - IntPtr pointer = new IntPtr(offset); - - VertexAttribIntegerType iType = (VertexAttribIntegerType)type; - - GL.VertexAttribIPointer(attrib.Index, size, iType, binding.Stride, pointer); - } - else - { - GL.VertexAttribPointer(attrib.Index, size, type, normalize, binding.Stride, offset); - } - } - else - { - GL.DisableVertexAttribArray(attrib.Index); - - SetConstAttrib(attrib); - } - - if (binding.Instanced && binding.Divisor != 0) - { - GL.VertexAttribDivisor(attrib.Index, 1); - } - else - { - GL.VertexAttribDivisor(attrib.Index, 0); - } - } - } - } - - private static VertexAttribPointerType GetType(Dictionary<GalVertexAttribSize, VertexAttribPointerType> dict, GalVertexAttrib attrib) - { - if (!dict.TryGetValue(attrib.Size, out VertexAttribPointerType type)) - { - ThrowUnsupportedAttrib(attrib); - } - - return type; - } - - private static unsafe void SetConstAttrib(GalVertexAttrib attrib) - { - if (attrib.Size == GalVertexAttribSize._10_10_10_2 || - attrib.Size == GalVertexAttribSize._11_11_10) - { - ThrowUnsupportedAttrib(attrib); - } - - fixed (byte* ptr = attrib.Data) - { - if (attrib.Type == GalVertexAttribType.Unorm) - { - switch (attrib.Size) - { - case GalVertexAttribSize._8: - case GalVertexAttribSize._8_8: - case GalVertexAttribSize._8_8_8: - case GalVertexAttribSize._8_8_8_8: - GL.VertexAttrib4N((uint)attrib.Index, ptr); - break; - - case GalVertexAttribSize._16: - case GalVertexAttribSize._16_16: - case GalVertexAttribSize._16_16_16: - case GalVertexAttribSize._16_16_16_16: - GL.VertexAttrib4N((uint)attrib.Index, (ushort*)ptr); - break; - - case GalVertexAttribSize._32: - case GalVertexAttribSize._32_32: - case GalVertexAttribSize._32_32_32: - case GalVertexAttribSize._32_32_32_32: - GL.VertexAttrib4N((uint)attrib.Index, (uint*)ptr); - break; - } - } - else if (attrib.Type == GalVertexAttribType.Snorm) - { - switch (attrib.Size) - { - case GalVertexAttribSize._8: - case GalVertexAttribSize._8_8: - case GalVertexAttribSize._8_8_8: - case GalVertexAttribSize._8_8_8_8: - GL.VertexAttrib4N((uint)attrib.Index, (sbyte*)ptr); - break; - - case GalVertexAttribSize._16: - case GalVertexAttribSize._16_16: - case GalVertexAttribSize._16_16_16: - case GalVertexAttribSize._16_16_16_16: - GL.VertexAttrib4N((uint)attrib.Index, (short*)ptr); - break; - - case GalVertexAttribSize._32: - case GalVertexAttribSize._32_32: - case GalVertexAttribSize._32_32_32: - case GalVertexAttribSize._32_32_32_32: - GL.VertexAttrib4N((uint)attrib.Index, (int*)ptr); - break; - } - } - else if (attrib.Type == GalVertexAttribType.Uint) - { - switch (attrib.Size) - { - case GalVertexAttribSize._8: - case GalVertexAttribSize._8_8: - case GalVertexAttribSize._8_8_8: - case GalVertexAttribSize._8_8_8_8: - GL.VertexAttribI4((uint)attrib.Index, ptr); - break; - - case GalVertexAttribSize._16: - case GalVertexAttribSize._16_16: - case GalVertexAttribSize._16_16_16: - case GalVertexAttribSize._16_16_16_16: - GL.VertexAttribI4((uint)attrib.Index, (ushort*)ptr); - break; - - case GalVertexAttribSize._32: - case GalVertexAttribSize._32_32: - case GalVertexAttribSize._32_32_32: - case GalVertexAttribSize._32_32_32_32: - GL.VertexAttribI4((uint)attrib.Index, (uint*)ptr); - break; - } - } - else if (attrib.Type == GalVertexAttribType.Sint) - { - switch (attrib.Size) - { - case GalVertexAttribSize._8: - case GalVertexAttribSize._8_8: - case GalVertexAttribSize._8_8_8: - case GalVertexAttribSize._8_8_8_8: - GL.VertexAttribI4((uint)attrib.Index, (sbyte*)ptr); - break; - - case GalVertexAttribSize._16: - case GalVertexAttribSize._16_16: - case GalVertexAttribSize._16_16_16: - case GalVertexAttribSize._16_16_16_16: - GL.VertexAttribI4((uint)attrib.Index, (short*)ptr); - break; - - case GalVertexAttribSize._32: - case GalVertexAttribSize._32_32: - case GalVertexAttribSize._32_32_32: - case GalVertexAttribSize._32_32_32_32: - GL.VertexAttribI4((uint)attrib.Index, (int*)ptr); - break; - } - } - else if (attrib.Type == GalVertexAttribType.Float) - { - switch (attrib.Size) - { - case GalVertexAttribSize._32: - case GalVertexAttribSize._32_32: - case GalVertexAttribSize._32_32_32: - case GalVertexAttribSize._32_32_32_32: - GL.VertexAttrib4(attrib.Index, (float*)ptr); - break; - - default: ThrowUnsupportedAttrib(attrib); break; - } - } - } - } - - private static void ThrowUnsupportedAttrib(GalVertexAttrib attrib) - { - throw new NotImplementedException("Unsupported size \"" + attrib.Size + "\" on type \"" + attrib.Type + "\"!"); - } - - private void Enable(EnableCap cap, bool enabled) - { - if (enabled) - { - GL.Enable(cap); - } - else - { - GL.Disable(cap); - } - } - - private void Enable(IndexedEnableCap cap, int index, bool enabled) - { - if (enabled) - { - GL.Enable(cap, index); - } - else - { - GL.Disable(cap, index); - } - } - - public void ResetDepthMask() - { - _old.DepthWriteEnabled = true; - } - - public void ResetColorMask(int index) - { - _old.ColorMasks[index] = ColorMaskState.Default; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OglRasterizer.cs deleted file mode 100644 index c19911c5..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglRasterizer.cs +++ /dev/null @@ -1,207 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using System; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - class OglRasterizer : IGalRasterizer - { - private const long MaxVertexBufferCacheSize = 128 * 1024 * 1024; - private const long MaxIndexBufferCacheSize = 64 * 1024 * 1024; - - private int[] _vertexBuffers; - - private OglCachedResource<int> _vboCache; - private OglCachedResource<int> _iboCache; - - private struct IbInfo - { - public int Count; - public int ElemSizeLog2; - - public DrawElementsType Type; - } - - private IbInfo _indexBuffer; - - public OglRasterizer() - { - _vertexBuffers = new int[32]; - - _vboCache = new OglCachedResource<int>(GL.DeleteBuffer, MaxVertexBufferCacheSize); - _iboCache = new OglCachedResource<int>(GL.DeleteBuffer, MaxIndexBufferCacheSize); - - _indexBuffer = new IbInfo(); - } - - public void LockCaches() - { - _vboCache.Lock(); - _iboCache.Lock(); - } - - public void UnlockCaches() - { - _vboCache.Unlock(); - _iboCache.Unlock(); - } - - public void ClearBuffers( - GalClearBufferFlags flags, - int attachment, - float red, - float green, - float blue, - float alpha, - float depth, - int stencil) - { - GL.ColorMask( - attachment, - flags.HasFlag(GalClearBufferFlags.ColorRed), - flags.HasFlag(GalClearBufferFlags.ColorGreen), - flags.HasFlag(GalClearBufferFlags.ColorBlue), - flags.HasFlag(GalClearBufferFlags.ColorAlpha)); - - GL.ClearBuffer(ClearBuffer.Color, attachment, new float[] { red, green, blue, alpha }); - - GL.ColorMask(attachment, true, true, true, true); - GL.DepthMask(true); - - if (flags.HasFlag(GalClearBufferFlags.Depth)) - { - GL.ClearBuffer(ClearBuffer.Depth, 0, ref depth); - } - - if (flags.HasFlag(GalClearBufferFlags.Stencil)) - { - GL.ClearBuffer(ClearBuffer.Stencil, 0, ref stencil); - } - } - - public bool IsVboCached(long key, long dataSize) - { - return _vboCache.TryGetSize(key, out long size) && size == dataSize; - } - - public bool IsIboCached(long key, long dataSize) - { - return _iboCache.TryGetSize(key, out long size) && size == dataSize; - } - - public void CreateVbo(long key, int dataSize, IntPtr hostAddress) - { - int handle = GL.GenBuffer(); - - _vboCache.AddOrUpdate(key, handle, dataSize); - - IntPtr length = new IntPtr(dataSize); - - GL.BindBuffer(BufferTarget.ArrayBuffer, handle); - GL.BufferData(BufferTarget.ArrayBuffer, length, hostAddress, BufferUsageHint.StreamDraw); - } - - public void CreateVbo(long key, byte[] data) - { - int handle = GL.GenBuffer(); - - _vboCache.AddOrUpdate(key, handle, data.Length); - - IntPtr length = new IntPtr(data.Length); - - GL.BindBuffer(BufferTarget.ArrayBuffer, handle); - GL.BufferData(BufferTarget.ArrayBuffer, length, data, BufferUsageHint.StreamDraw); - } - - public void CreateIbo(long key, int dataSize, IntPtr hostAddress) - { - int handle = GL.GenBuffer(); - - _iboCache.AddOrUpdate(key, handle, (uint)dataSize); - - IntPtr length = new IntPtr(dataSize); - - GL.BindBuffer(BufferTarget.ElementArrayBuffer, handle); - GL.BufferData(BufferTarget.ElementArrayBuffer, length, hostAddress, BufferUsageHint.StreamDraw); - } - - public void CreateIbo(long key, int dataSize, byte[] buffer) - { - int handle = GL.GenBuffer(); - - _iboCache.AddOrUpdate(key, handle, dataSize); - - IntPtr length = new IntPtr(buffer.Length); - - GL.BindBuffer(BufferTarget.ElementArrayBuffer, handle); - GL.BufferData(BufferTarget.ElementArrayBuffer, length, buffer, BufferUsageHint.StreamDraw); - } - - public void SetIndexArray(int size, GalIndexFormat format) - { - _indexBuffer.Type = OglEnumConverter.GetDrawElementsType(format); - - _indexBuffer.Count = size >> (int)format; - - _indexBuffer.ElemSizeLog2 = (int)format; - } - - public void DrawArrays(int first, int count, GalPrimitiveType primType) - { - if (count == 0) - { - return; - } - - if (primType == GalPrimitiveType.Quads) - { - for (int offset = 0; offset < count; offset += 4) - { - GL.DrawArrays(PrimitiveType.TriangleFan, first + offset, 4); - } - } - else if (primType == GalPrimitiveType.QuadStrip) - { - GL.DrawArrays(PrimitiveType.TriangleFan, first, 4); - - for (int offset = 2; offset < count; offset += 2) - { - GL.DrawArrays(PrimitiveType.TriangleFan, first + offset, 4); - } - } - else - { - GL.DrawArrays(OglEnumConverter.GetPrimitiveType(primType), first, count); - } - } - - public void DrawElements(long iboKey, int first, int vertexBase, GalPrimitiveType primType) - { - if (!_iboCache.TryGetValue(iboKey, out int iboHandle)) - { - return; - } - - PrimitiveType mode = OglEnumConverter.GetPrimitiveType(primType); - - GL.BindBuffer(BufferTarget.ElementArrayBuffer, iboHandle); - - first <<= _indexBuffer.ElemSizeLog2; - - if (vertexBase != 0) - { - IntPtr indices = new IntPtr(first); - - GL.DrawElementsBaseVertex(mode, _indexBuffer.Count, _indexBuffer.Type, indices, vertexBase); - } - else - { - GL.DrawElements(mode, _indexBuffer.Count, _indexBuffer.Type, first); - } - } - - public bool TryGetVbo(long vboKey, out int vboHandle) - { - return _vboCache.TryGetValue(vboKey, out vboHandle); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglRenderTarget.cs b/Ryujinx.Graphics/Gal/OpenGL/OglRenderTarget.cs deleted file mode 100644 index 11fc98cb..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglRenderTarget.cs +++ /dev/null @@ -1,549 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.Texture; -using System; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - class OglRenderTarget : IGalRenderTarget - { - private const int NativeWidth = 1280; - private const int NativeHeight = 720; - - private const int RenderTargetsCount = GalPipelineState.RenderTargetsCount; - - private struct Rect - { - public int X { get; private set; } - public int Y { get; private set; } - public int Width { get; private set; } - public int Height { get; private set; } - - public Rect(int x, int y, int width, int height) - { - X = x; - Y = y; - Width = width; - Height = height; - } - } - - private class FrameBufferAttachments - { - public int MapCount { get; set; } - - public DrawBuffersEnum[] Map { get; private set; } - - public long[] Colors { get; private set; } - - public long Zeta { get; set; } - - public FrameBufferAttachments() - { - Colors = new long[RenderTargetsCount]; - - Map = new DrawBuffersEnum[RenderTargetsCount]; - } - - public void Update(FrameBufferAttachments source) - { - for (int index = 0; index < RenderTargetsCount; index++) - { - Map[index] = source.Map[index]; - - Colors[index] = source.Colors[index]; - } - - MapCount = source.MapCount; - Zeta = source.Zeta; - } - } - - private int[] _colorHandles; - private int _zetaHandle; - - private OglTexture _texture; - - private ImageHandler _readTex; - - private Rect _window; - - private float[] _viewports; - - private bool _flipX; - private bool _flipY; - - private int _cropTop; - private int _cropLeft; - private int _cropRight; - private int _cropBottom; - - // This framebuffer is used to attach guest rendertargets, - // think of it as a dummy OpenGL VAO - private int _dummyFrameBuffer; - - // These framebuffers are used to blit images - private int _srcFb; - private int _dstFb; - - private FrameBufferAttachments _attachments; - private FrameBufferAttachments _oldAttachments; - - private int _copyPbo; - - public bool FramebufferSrgb { get; set; } - - public OglRenderTarget(OglTexture texture) - { - _attachments = new FrameBufferAttachments(); - - _oldAttachments = new FrameBufferAttachments(); - - _colorHandles = new int[RenderTargetsCount]; - - _viewports = new float[RenderTargetsCount * 4]; - - _texture = texture; - - texture.TextureDeleted += TextureDeletionHandler; - } - - private void TextureDeletionHandler(object sender, int handle) - { - // Texture was deleted, the handle is no longer valid, so - // reset all uses of this handle on a render target. - for (int attachment = 0; attachment < RenderTargetsCount; attachment++) - { - if (_colorHandles[attachment] == handle) - { - _colorHandles[attachment] = 0; - } - } - - if (_zetaHandle == handle) - { - _zetaHandle = 0; - } - } - - public void Bind() - { - if (_dummyFrameBuffer == 0) - { - _dummyFrameBuffer = GL.GenFramebuffer(); - } - - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, _dummyFrameBuffer); - - ImageHandler cachedImage; - - for (int attachment = 0; attachment < RenderTargetsCount; attachment++) - { - long key = _attachments.Colors[attachment]; - - int handle = 0; - - if (key != 0 && _texture.TryGetImageHandler(key, out cachedImage)) - { - handle = cachedImage.Handle; - } - - if (handle == _colorHandles[attachment]) - { - continue; - } - - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.ColorAttachment0 + attachment, - handle, - 0); - - _colorHandles[attachment] = handle; - } - - if (_attachments.Zeta != 0 && _texture.TryGetImageHandler(_attachments.Zeta, out cachedImage)) - { - if (cachedImage.Handle != _zetaHandle) - { - if (cachedImage.HasDepth && cachedImage.HasStencil) - { - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.DepthStencilAttachment, - cachedImage.Handle, - 0); - } - else if (cachedImage.HasDepth) - { - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.DepthAttachment, - cachedImage.Handle, - 0); - - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.StencilAttachment, - 0, - 0); - } - else - { - throw new InvalidOperationException("Invalid image format \"" + cachedImage.Format + "\" used as Zeta!"); - } - - _zetaHandle = cachedImage.Handle; - } - } - else if (_zetaHandle != 0) - { - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.DepthStencilAttachment, - 0, - 0); - - _zetaHandle = 0; - } - - if (OglExtension.ViewportArray) - { - GL.ViewportArray(0, RenderTargetsCount, _viewports); - } - else - { - GL.Viewport( - (int)_viewports[0], - (int)_viewports[1], - (int)_viewports[2], - (int)_viewports[3]); - } - - if (_attachments.MapCount > 1) - { - GL.DrawBuffers(_attachments.MapCount, _attachments.Map); - } - else if (_attachments.MapCount == 1) - { - GL.DrawBuffer((DrawBufferMode)_attachments.Map[0]); - } - else - { - GL.DrawBuffer(DrawBufferMode.None); - } - - _oldAttachments.Update(_attachments); - } - - public void BindColor(long key, int attachment) - { - _attachments.Colors[attachment] = key; - } - - public void UnbindColor(int attachment) - { - _attachments.Colors[attachment] = 0; - } - - public void BindZeta(long key) - { - _attachments.Zeta = key; - } - - public void UnbindZeta() - { - _attachments.Zeta = 0; - } - - public void Present(long key) - { - _texture.TryGetImageHandler(key, out _readTex); - } - - public void SetMap(int[] map) - { - if (map != null) - { - _attachments.MapCount = map.Length; - - for (int attachment = 0; attachment < _attachments.MapCount; attachment++) - { - _attachments.Map[attachment] = DrawBuffersEnum.ColorAttachment0 + map[attachment]; - } - } - else - { - _attachments.MapCount = 0; - } - } - - public void SetTransform(bool flipX, bool flipY, int top, int left, int right, int bottom) - { - _flipX = flipX; - _flipY = flipY; - - _cropTop = top; - _cropLeft = left; - _cropRight = right; - _cropBottom = bottom; - } - - public void SetWindowSize(int width, int height) - { - _window = new Rect(0, 0, width, height); - } - - public void SetViewport(int attachment, int x, int y, int width, int height) - { - int offset = attachment * 4; - - _viewports[offset + 0] = x; - _viewports[offset + 1] = y; - _viewports[offset + 2] = width; - _viewports[offset + 3] = height; - } - - public void Render() - { - if (_readTex == null) - { - return; - } - - int srcX0, srcX1, srcY0, srcY1; - - if (_cropLeft == 0 && _cropRight == 0) - { - srcX0 = 0; - srcX1 = _readTex.Width; - } - else - { - srcX0 = _cropLeft; - srcX1 = _cropRight; - } - - if (_cropTop == 0 && _cropBottom == 0) - { - srcY0 = 0; - srcY1 = _readTex.Height; - } - else - { - srcY0 = _cropTop; - srcY1 = _cropBottom; - } - - float ratioX = MathF.Min(1f, (_window.Height * (float)NativeWidth) / ((float)NativeHeight * _window.Width)); - float ratioY = MathF.Min(1f, (_window.Width * (float)NativeHeight) / ((float)NativeWidth * _window.Height)); - - int dstWidth = (int)(_window.Width * ratioX); - int dstHeight = (int)(_window.Height * ratioY); - - int dstPaddingX = (_window.Width - dstWidth) / 2; - int dstPaddingY = (_window.Height - dstHeight) / 2; - - int dstX0 = _flipX ? _window.Width - dstPaddingX : dstPaddingX; - int dstX1 = _flipX ? dstPaddingX : _window.Width - dstPaddingX; - - int dstY0 = _flipY ? dstPaddingY : _window.Height - dstPaddingY; - int dstY1 = _flipY ? _window.Height - dstPaddingY : dstPaddingY; - - GL.Viewport(0, 0, _window.Width, _window.Height); - - if (_srcFb == 0) - { - _srcFb = GL.GenFramebuffer(); - } - - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, _srcFb); - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0); - - GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, _readTex.Handle, 0); - - GL.ReadBuffer(ReadBufferMode.ColorAttachment0); - - GL.Clear(ClearBufferMask.ColorBufferBit); - - GL.Disable(EnableCap.FramebufferSrgb); - - GL.BlitFramebuffer( - srcX0, - srcY0, - srcX1, - srcY1, - dstX0, - dstY0, - dstX1, - dstY1, - ClearBufferMask.ColorBufferBit, - BlitFramebufferFilter.Linear); - - if (FramebufferSrgb) - { - GL.Enable(EnableCap.FramebufferSrgb); - } - } - - public void Copy( - GalImage srcImage, - GalImage dstImage, - long srcKey, - long dstKey, - int srcLayer, - int dstLayer, - int srcX0, - int srcY0, - int srcX1, - int srcY1, - int dstX0, - int dstY0, - int dstX1, - int dstY1) - { - if (_texture.TryGetImageHandler(srcKey, out ImageHandler srcTex) && - _texture.TryGetImageHandler(dstKey, out ImageHandler dstTex)) - { - if (srcTex.HasColor != dstTex.HasColor || - srcTex.HasDepth != dstTex.HasDepth || - srcTex.HasStencil != dstTex.HasStencil) - { - throw new NotImplementedException(); - } - - if (_srcFb == 0) - { - _srcFb = GL.GenFramebuffer(); - } - - if (_dstFb == 0) - { - _dstFb = GL.GenFramebuffer(); - } - - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, _srcFb); - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, _dstFb); - - FramebufferAttachment attachment = GetAttachment(srcTex); - - if (ImageUtils.IsArray(srcImage.TextureTarget) && srcLayer > 0) - { - GL.FramebufferTextureLayer(FramebufferTarget.ReadFramebuffer, attachment, srcTex.Handle, 0, srcLayer); - } - else - { - GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, attachment, srcTex.Handle, 0); - } - - if (ImageUtils.IsArray(dstImage.TextureTarget) && dstLayer > 0) - { - GL.FramebufferTextureLayer(FramebufferTarget.DrawFramebuffer, attachment, dstTex.Handle, 0, dstLayer); - } - else - { - GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, attachment, dstTex.Handle, 0); - } - - - BlitFramebufferFilter filter = BlitFramebufferFilter.Nearest; - - if (srcTex.HasColor) - { - GL.DrawBuffer(DrawBufferMode.ColorAttachment0); - - filter = BlitFramebufferFilter.Linear; - } - - ClearBufferMask mask = GetClearMask(srcTex); - - GL.BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - } - } - - public void Reinterpret(long key, GalImage newImage) - { - if (!_texture.TryGetImage(key, out GalImage oldImage)) - { - return; - } - - if (newImage.Format == oldImage.Format && - newImage.Width == oldImage.Width && - newImage.Height == oldImage.Height && - newImage.Depth == oldImage.Depth && - newImage.LayerCount == oldImage.LayerCount && - newImage.TextureTarget == oldImage.TextureTarget) - { - return; - } - - if (_copyPbo == 0) - { - _copyPbo = GL.GenBuffer(); - } - - GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyPbo); - - // The buffer should be large enough to hold the largest texture. - int bufferSize = Math.Max(ImageUtils.GetSize(oldImage), - ImageUtils.GetSize(newImage)); - - GL.BufferData(BufferTarget.PixelPackBuffer, bufferSize, IntPtr.Zero, BufferUsageHint.StreamCopy); - - if (!_texture.TryGetImageHandler(key, out ImageHandler cachedImage)) - { - throw new InvalidOperationException(); - } - - (_, PixelFormat format, PixelType type) = OglEnumConverter.GetImageFormat(cachedImage.Format); - - TextureTarget target = ImageUtils.GetTextureTarget(newImage.TextureTarget); - - GL.BindTexture(target, cachedImage.Handle); - - GL.GetTexImage(target, 0, format, type, IntPtr.Zero); - - GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, _copyPbo); - - GL.PixelStore(PixelStoreParameter.UnpackRowLength, oldImage.Width); - - _texture.Create(key, ImageUtils.GetSize(newImage), newImage); - - GL.PixelStore(PixelStoreParameter.UnpackRowLength, 0); - - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); - } - - private static FramebufferAttachment GetAttachment(ImageHandler cachedImage) - { - if (cachedImage.HasColor) - { - return FramebufferAttachment.ColorAttachment0; - } - else if (cachedImage.HasDepth && cachedImage.HasStencil) - { - return FramebufferAttachment.DepthStencilAttachment; - } - else if (cachedImage.HasDepth) - { - return FramebufferAttachment.DepthAttachment; - } - else if (cachedImage.HasStencil) - { - return FramebufferAttachment.StencilAttachment; - } - else - { - throw new InvalidOperationException(); - } - } - - private static ClearBufferMask GetClearMask(ImageHandler cachedImage) - { - return (cachedImage.HasColor ? ClearBufferMask.ColorBufferBit : 0) | - (cachedImage.HasDepth ? ClearBufferMask.DepthBufferBit : 0) | - (cachedImage.HasStencil ? ClearBufferMask.StencilBufferBit : 0); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglRenderer.cs b/Ryujinx.Graphics/Gal/OpenGL/OglRenderer.cs deleted file mode 100644 index 1ff8c7ad..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglRenderer.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Concurrent; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - public class OglRenderer : IGalRenderer - { - public IGalConstBuffer Buffer { get; private set; } - - public IGalRenderTarget RenderTarget { get; private set; } - - public IGalRasterizer Rasterizer { get; private set; } - - public IGalShader Shader { get; private set; } - - public IGalPipeline Pipeline { get; private set; } - - public IGalTexture Texture { get; private set; } - - private ConcurrentQueue<Action> _actionsQueue; - - public OglRenderer() - { - Buffer = new OglConstBuffer(); - - Texture = new OglTexture(); - - RenderTarget = new OglRenderTarget(Texture as OglTexture); - - Rasterizer = new OglRasterizer(); - - Shader = new OglShader(Buffer as OglConstBuffer); - - Pipeline = new OglPipeline( - Buffer as OglConstBuffer, - RenderTarget as OglRenderTarget, - Rasterizer as OglRasterizer, - Shader as OglShader); - - _actionsQueue = new ConcurrentQueue<Action>(); - } - - public void QueueAction(Action actionMthd) - { - _actionsQueue.Enqueue(actionMthd); - } - - public void RunActions() - { - int count = _actionsQueue.Count; - - while (count-- > 0 && _actionsQueue.TryDequeue(out Action renderAction)) - { - renderAction(); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs b/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs deleted file mode 100644 index 8da0104e..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs +++ /dev/null @@ -1,291 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.Shader; -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - class OglShader : IGalShader - { - public const int ReservedCbufCount = 1; - - private const int ExtraDataSize = 4; - - public OglShaderProgram Current; - - private ConcurrentDictionary<long, OglShaderStage> _stages; - - private Dictionary<OglShaderProgram, int> _programs; - - public int CurrentProgramHandle { get; private set; } - - private OglConstBuffer _buffer; - - private int _extraUboHandle; - - public OglShader(OglConstBuffer buffer) - { - _buffer = buffer; - - _stages = new ConcurrentDictionary<long, OglShaderStage>(); - - _programs = new Dictionary<OglShaderProgram, int>(); - } - - public void Create(IGalMemory memory, long key, GalShaderType type) - { - _stages.GetOrAdd(key, (stage) => ShaderStageFactory(memory, key, 0, false, type)); - } - - public void Create(IGalMemory memory, long vpAPos, long key, GalShaderType type) - { - _stages.GetOrAdd(key, (stage) => ShaderStageFactory(memory, vpAPos, key, true, type)); - } - - private OglShaderStage ShaderStageFactory( - IGalMemory memory, - long position, - long positionB, - bool isDualVp, - GalShaderType type) - { - ShaderConfig config = new ShaderConfig(type, OglLimit.MaxUboSize); - - ShaderProgram program; - - if (isDualVp) - { - ShaderDumper.Dump(memory, position, type, "a"); - ShaderDumper.Dump(memory, positionB, type, "b"); - - program = Translator.Translate(memory, (ulong)position, (ulong)positionB, config); - } - else - { - ShaderDumper.Dump(memory, position, type); - - program = Translator.Translate(memory, (ulong)position, config); - } - - string code = program.Code; - - if (ShaderDumper.IsDumpEnabled()) - { - int shaderDumpIndex = ShaderDumper.DumpIndex; - - code = "//Shader " + shaderDumpIndex + Environment.NewLine + code; - } - - return new OglShaderStage(type, code, program.Info.CBuffers, program.Info.Textures); - } - - public IEnumerable<CBufferDescriptor> GetConstBufferUsage(long key) - { - if (_stages.TryGetValue(key, out OglShaderStage stage)) - { - return stage.ConstBufferUsage; - } - - return Enumerable.Empty<CBufferDescriptor>(); - } - - public IEnumerable<TextureDescriptor> GetTextureUsage(long key) - { - if (_stages.TryGetValue(key, out OglShaderStage stage)) - { - return stage.TextureUsage; - } - - return Enumerable.Empty<TextureDescriptor>(); - } - - public unsafe void SetExtraData(float flipX, float flipY, int instance) - { - BindProgram(); - - EnsureExtraBlock(); - - GL.BindBuffer(BufferTarget.UniformBuffer, _extraUboHandle); - - float* data = stackalloc float[ExtraDataSize]; - data[0] = flipX; - data[1] = flipY; - data[2] = BitConverter.Int32BitsToSingle(instance); - - // Invalidate buffer - GL.BufferData(BufferTarget.UniformBuffer, ExtraDataSize * sizeof(float), IntPtr.Zero, BufferUsageHint.StreamDraw); - - GL.BufferSubData(BufferTarget.UniformBuffer, IntPtr.Zero, ExtraDataSize * sizeof(float), (IntPtr)data); - } - - public void Bind(long key) - { - if (_stages.TryGetValue(key, out OglShaderStage stage)) - { - Bind(stage); - } - } - - private void Bind(OglShaderStage stage) - { - switch (stage.Type) - { - case GalShaderType.Vertex: Current.Vertex = stage; break; - case GalShaderType.TessControl: Current.TessControl = stage; break; - case GalShaderType.TessEvaluation: Current.TessEvaluation = stage; break; - case GalShaderType.Geometry: Current.Geometry = stage; break; - case GalShaderType.Fragment: Current.Fragment = stage; break; - } - } - - public void Unbind(GalShaderType type) - { - switch (type) - { - case GalShaderType.Vertex: Current.Vertex = null; break; - case GalShaderType.TessControl: Current.TessControl = null; break; - case GalShaderType.TessEvaluation: Current.TessEvaluation = null; break; - case GalShaderType.Geometry: Current.Geometry = null; break; - case GalShaderType.Fragment: Current.Fragment = null; break; - } - } - - public void BindProgram() - { - if (Current.Vertex == null || - Current.Fragment == null) - { - return; - } - - if (!_programs.TryGetValue(Current, out int handle)) - { - handle = GL.CreateProgram(); - - AttachIfNotNull(handle, Current.Vertex); - AttachIfNotNull(handle, Current.TessControl); - AttachIfNotNull(handle, Current.TessEvaluation); - AttachIfNotNull(handle, Current.Geometry); - AttachIfNotNull(handle, Current.Fragment); - - GL.LinkProgram(handle); - - CheckProgramLink(handle); - - BindUniformBlocks(handle); - BindTextureLocations(handle); - - _programs.Add(Current, handle); - } - - GL.UseProgram(handle); - - CurrentProgramHandle = handle; - } - - private void EnsureExtraBlock() - { - if (_extraUboHandle == 0) - { - _extraUboHandle = GL.GenBuffer(); - - GL.BindBuffer(BufferTarget.UniformBuffer, _extraUboHandle); - - GL.BufferData(BufferTarget.UniformBuffer, ExtraDataSize * sizeof(float), IntPtr.Zero, BufferUsageHint.StreamDraw); - - GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, _extraUboHandle); - } - } - - private void AttachIfNotNull(int programHandle, OglShaderStage stage) - { - if (stage != null) - { - stage.Compile(); - - GL.AttachShader(programHandle, stage.Handle); - } - } - - private void BindUniformBlocks(int programHandle) - { - int extraBlockindex = GL.GetUniformBlockIndex(programHandle, "Extra"); - - GL.UniformBlockBinding(programHandle, extraBlockindex, 0); - - int freeBinding = ReservedCbufCount; - - void BindUniformBlocksIfNotNull(OglShaderStage stage) - { - if (stage != null) - { - foreach (CBufferDescriptor desc in stage.ConstBufferUsage) - { - int blockIndex = GL.GetUniformBlockIndex(programHandle, desc.Name); - - if (blockIndex < 0) - { - // This may be fine, the compiler may optimize away unused uniform buffers, - // and in this case the above call would return -1 as the buffer has been - // optimized away. - continue; - } - - GL.UniformBlockBinding(programHandle, blockIndex, freeBinding); - - freeBinding++; - } - } - } - - BindUniformBlocksIfNotNull(Current.Vertex); - BindUniformBlocksIfNotNull(Current.TessControl); - BindUniformBlocksIfNotNull(Current.TessEvaluation); - BindUniformBlocksIfNotNull(Current.Geometry); - BindUniformBlocksIfNotNull(Current.Fragment); - } - - private void BindTextureLocations(int programHandle) - { - int index = 0; - - void BindTexturesIfNotNull(OglShaderStage stage) - { - if (stage != null) - { - foreach (TextureDescriptor desc in stage.TextureUsage) - { - int location = GL.GetUniformLocation(programHandle, desc.Name); - - GL.Uniform1(location, index); - - index++; - } - } - } - - GL.UseProgram(programHandle); - - BindTexturesIfNotNull(Current.Vertex); - BindTexturesIfNotNull(Current.TessControl); - BindTexturesIfNotNull(Current.TessEvaluation); - BindTexturesIfNotNull(Current.Geometry); - BindTexturesIfNotNull(Current.Fragment); - } - - private static void CheckProgramLink(int handle) - { - int status = 0; - - GL.GetProgram(handle, GetProgramParameterName.LinkStatus, out status); - - if (status == 0) - { - throw new ShaderException(GL.GetProgramInfoLog(handle)); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglShaderProgram.cs b/Ryujinx.Graphics/Gal/OpenGL/OglShaderProgram.cs deleted file mode 100644 index 86126bca..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglShaderProgram.cs +++ /dev/null @@ -1,87 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.Shader; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - struct OglShaderProgram - { - public OglShaderStage Vertex; - public OglShaderStage TessControl; - public OglShaderStage TessEvaluation; - public OglShaderStage Geometry; - public OglShaderStage Fragment; - } - - class OglShaderStage : IDisposable - { - public int Handle { get; private set; } - - public bool IsCompiled { get; private set; } - - public GalShaderType Type { get; private set; } - - public string Code { get; private set; } - - public IEnumerable<CBufferDescriptor> ConstBufferUsage { get; private set; } - public IEnumerable<TextureDescriptor> TextureUsage { get; private set; } - - public OglShaderStage( - GalShaderType type, - string code, - IEnumerable<CBufferDescriptor> constBufferUsage, - IEnumerable<TextureDescriptor> textureUsage) - { - Type = type; - Code = code; - ConstBufferUsage = constBufferUsage; - TextureUsage = textureUsage; - } - - public void Compile() - { - if (Handle == 0) - { - Handle = GL.CreateShader(OglEnumConverter.GetShaderType(Type)); - - CompileAndCheck(Handle, Code); - } - } - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing && Handle != 0) - { - GL.DeleteShader(Handle); - - Handle = 0; - } - } - - public static void CompileAndCheck(int handle, string code) - { - GL.ShaderSource(handle, code); - GL.CompileShader(handle); - - CheckCompilation(handle); - } - - private static void CheckCompilation(int handle) - { - int status = 0; - - GL.GetShader(handle, ShaderParameter.CompileStatus, out status); - - if (status == 0) - { - throw new ShaderException(GL.GetShaderInfoLog(handle)); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglStreamBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OglStreamBuffer.cs deleted file mode 100644 index 58b3ace5..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglStreamBuffer.cs +++ /dev/null @@ -1,55 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using System; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - class OglStreamBuffer : IDisposable - { - public int Handle { get; protected set; } - - public long Size { get; protected set; } - - protected BufferTarget Target { get; private set; } - - public OglStreamBuffer(BufferTarget target, long size) - { - Target = target; - Size = size; - - Handle = GL.GenBuffer(); - - GL.BindBuffer(target, Handle); - - GL.BufferData(target, (IntPtr)size, IntPtr.Zero, BufferUsageHint.StreamDraw); - } - - public void SetData(long size, IntPtr hostAddress) - { - GL.BindBuffer(Target, Handle); - - GL.BufferSubData(Target, IntPtr.Zero, (IntPtr)size, hostAddress); - } - - public void SetData(byte[] data) - { - GL.BindBuffer(Target, Handle); - - GL.BufferSubData(Target, IntPtr.Zero, (IntPtr)data.Length, data); - } - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing && Handle != 0) - { - GL.DeleteBuffer(Handle); - - Handle = 0; - } - } - } -} diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OglTexture.cs deleted file mode 100644 index b5ac6692..00000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OglTexture.cs +++ /dev/null @@ -1,408 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.Texture; -using System; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - class OglTexture : IGalTexture - { - private const long MaxTextureCacheSize = 768 * 1024 * 1024; - - private OglCachedResource<ImageHandler> _textureCache; - - public EventHandler<int> TextureDeleted { get; set; } - - public OglTexture() - { - _textureCache = new OglCachedResource<ImageHandler>(DeleteTexture, MaxTextureCacheSize); - } - - public void LockCache() - { - _textureCache.Lock(); - } - - public void UnlockCache() - { - _textureCache.Unlock(); - } - - private void DeleteTexture(ImageHandler cachedImage) - { - TextureDeleted?.Invoke(this, cachedImage.Handle); - - GL.DeleteTexture(cachedImage.Handle); - } - - public void Create(long key, int size, GalImage image) - { - int handle = GL.GenTexture(); - - TextureTarget target = ImageUtils.GetTextureTarget(image.TextureTarget); - - GL.BindTexture(target, handle); - - const int level = 0; //TODO: Support mipmap textures. - const int border = 0; - - _textureCache.AddOrUpdate(key, new ImageHandler(handle, image), (uint)size); - - if (ImageUtils.IsCompressed(image.Format)) - { - throw new InvalidOperationException("Surfaces with compressed formats are not supported!"); - } - - (PixelInternalFormat internalFmt, - PixelFormat format, - PixelType type) = OglEnumConverter.GetImageFormat(image.Format); - - switch (target) - { - case TextureTarget.Texture1D: - GL.TexImage1D( - target, - level, - internalFmt, - image.Width, - border, - format, - type, - IntPtr.Zero); - break; - - case TextureTarget.Texture2D: - GL.TexImage2D( - target, - level, - internalFmt, - image.Width, - image.Height, - border, - format, - type, - IntPtr.Zero); - break; - case TextureTarget.Texture3D: - GL.TexImage3D( - target, - level, - internalFmt, - image.Width, - image.Height, - image.Depth, - border, - format, - type, - IntPtr.Zero); - break; - // Cube map arrays are just 2D texture arrays with 6 entries - // per cube map so we can handle them in the same way - case TextureTarget.TextureCubeMapArray: - case TextureTarget.Texture2DArray: - GL.TexImage3D( - target, - level, - internalFmt, - image.Width, - image.Height, - image.LayerCount, - border, - format, - type, - IntPtr.Zero); - break; - default: - throw new NotImplementedException($"Unsupported texture target type: {target}"); - } - } - - public void Create(long key, byte[] data, GalImage image) - { - int handle = GL.GenTexture(); - - TextureTarget target = ImageUtils.GetTextureTarget(image.TextureTarget); - - GL.BindTexture(target, handle); - - const int level = 0; //TODO: Support mipmap textures. - const int border = 0; - - _textureCache.AddOrUpdate(key, new ImageHandler(handle, image), (uint)data.Length); - - if (ImageUtils.IsCompressed(image.Format) && !IsAstc(image.Format)) - { - InternalFormat internalFmt = OglEnumConverter.GetCompressedImageFormat(image.Format); - - switch (target) - { - case TextureTarget.Texture1D: - GL.CompressedTexImage1D( - target, - level, - internalFmt, - image.Width, - border, - data.Length, - data); - break; - case TextureTarget.Texture2D: - GL.CompressedTexImage2D( - target, - level, - internalFmt, - image.Width, - image.Height, - border, - data.Length, - data); - break; - case TextureTarget.Texture3D: - GL.CompressedTexImage3D( - target, - level, - internalFmt, - image.Width, - image.Height, - image.Depth, - border, - data.Length, - data); - break; - // Cube map arrays are just 2D texture arrays with 6 entries - // per cube map so we can handle them in the same way - case TextureTarget.TextureCubeMapArray: - case TextureTarget.Texture2DArray: - GL.CompressedTexImage3D( - target, - level, - internalFmt, - image.Width, - image.Height, - image.LayerCount, - border, - data.Length, - data); - break; - case TextureTarget.TextureCubeMap: - Span<byte> array = new Span<byte>(data); - - int faceSize = ImageUtils.GetSize(image) / 6; - - for (int Face = 0; Face < 6; Face++) - { - GL.CompressedTexImage2D( - TextureTarget.TextureCubeMapPositiveX + Face, - level, - internalFmt, - image.Width, - image.Height, - border, - faceSize, - array.Slice(Face * faceSize, faceSize).ToArray()); - } - break; - default: - throw new NotImplementedException($"Unsupported texture target type: {target}"); - } - } - else - { - // TODO: Use KHR_texture_compression_astc_hdr when available - if (IsAstc(image.Format)) - { - int textureBlockWidth = ImageUtils.GetBlockWidth(image.Format); - int textureBlockHeight = ImageUtils.GetBlockHeight(image.Format); - int textureBlockDepth = ImageUtils.GetBlockDepth(image.Format); - - data = AstcDecoder.DecodeToRgba8888( - data, - textureBlockWidth, - textureBlockHeight, - textureBlockDepth, - image.Width, - image.Height, - image.Depth); - - image.Format = GalImageFormat.Rgba8 | (image.Format & GalImageFormat.TypeMask); - } - - (PixelInternalFormat internalFmt, - PixelFormat format, - PixelType type) = OglEnumConverter.GetImageFormat(image.Format); - - - switch (target) - { - case TextureTarget.Texture1D: - GL.TexImage1D( - target, - level, - internalFmt, - image.Width, - border, - format, - type, - data); - break; - case TextureTarget.Texture2D: - GL.TexImage2D( - target, - level, - internalFmt, - image.Width, - image.Height, - border, - format, - type, - data); - break; - case TextureTarget.Texture3D: - GL.TexImage3D( - target, - level, - internalFmt, - image.Width, - image.Height, - image.Depth, - border, - format, - type, - data); - break; - // Cube map arrays are just 2D texture arrays with 6 entries - // per cube map so we can handle them in the same way - case TextureTarget.TextureCubeMapArray: - case TextureTarget.Texture2DArray: - GL.TexImage3D( - target, - level, - internalFmt, - image.Width, - image.Height, - image.LayerCount, - border, - format, - type, - data); - break; - case TextureTarget.TextureCubeMap: - Span<byte> array = new Span<byte>(data); - - int faceSize = ImageUtils.GetSize(image) / 6; - - for (int face = 0; face < 6; face++) - { - GL.TexImage2D( - TextureTarget.TextureCubeMapPositiveX + face, - level, - internalFmt, - image.Width, - image.Height, - border, - format, - type, - array.Slice(face * faceSize, faceSize).ToArray()); - } - break; - default: - throw new NotImplementedException($"Unsupported texture target type: {target}"); - } - } - } - - private static bool IsAstc(GalImageFormat format) - { - format &= GalImageFormat.FormatMask; - - return format > GalImageFormat.Astc2DStart && format < GalImageFormat.Astc2DEnd; - } - - public bool TryGetImage(long key, out GalImage image) - { - if (_textureCache.TryGetValue(key, out ImageHandler cachedImage)) - { - image = cachedImage.Image; - - return true; - } - - image = default(GalImage); - - return false; - } - - public bool TryGetImageHandler(long key, out ImageHandler cachedImage) - { - if (_textureCache.TryGetValue(key, out cachedImage)) - { - return true; - } - - cachedImage = null; - - return false; - } - - public void Bind(long key, int index, GalImage image) - { - if (_textureCache.TryGetValue(key, out ImageHandler cachedImage)) - { - GL.ActiveTexture(TextureUnit.Texture0 + index); - - TextureTarget target = ImageUtils.GetTextureTarget(image.TextureTarget); - - GL.BindTexture(target, cachedImage.Handle); - - int[] swizzleRgba = new int[] - { - (int)OglEnumConverter.GetTextureSwizzle(image.XSource), - (int)OglEnumConverter.GetTextureSwizzle(image.YSource), - (int)OglEnumConverter.GetTextureSwizzle(image.ZSource), - (int)OglEnumConverter.GetTextureSwizzle(image.WSource) - }; - - GL.TexParameter(target, TextureParameterName.TextureSwizzleRgba, swizzleRgba); - } - } - - public void SetSampler(GalImage image, GalTextureSampler sampler) - { - int wrapS = (int)OglEnumConverter.GetTextureWrapMode(sampler.AddressU); - int wrapT = (int)OglEnumConverter.GetTextureWrapMode(sampler.AddressV); - int wrapR = (int)OglEnumConverter.GetTextureWrapMode(sampler.AddressP); - - int minFilter = (int)OglEnumConverter.GetTextureMinFilter(sampler.MinFilter, sampler.MipFilter); - int magFilter = (int)OglEnumConverter.GetTextureMagFilter(sampler.MagFilter); - - TextureTarget target = ImageUtils.GetTextureTarget(image.TextureTarget); - - GL.TexParameter(target, TextureParameterName.TextureWrapS, wrapS); - GL.TexParameter(target, TextureParameterName.TextureWrapT, wrapT); - GL.TexParameter(target, TextureParameterName.TextureWrapR, wrapR); - - GL.TexParameter(target, TextureParameterName.TextureMinFilter, minFilter); - GL.TexParameter(target, TextureParameterName.TextureMagFilter, magFilter); - - float[] color = new float[] - { - sampler.BorderColor.Red, - sampler.BorderColor.Green, - sampler.BorderColor.Blue, - sampler.BorderColor.Alpha - }; - - GL.TexParameter(target, TextureParameterName.TextureBorderColor, color); - - if (sampler.DepthCompare) - { - GL.TexParameter(target, TextureParameterName.TextureCompareMode, (int)All.CompareRToTexture); - GL.TexParameter(target, TextureParameterName.TextureCompareFunc, (int)OglEnumConverter.GetDepthCompareFunc(sampler.DepthCompareFunc)); - } - else - { - GL.TexParameter(target, TextureParameterName.TextureCompareMode, (int)All.None); - GL.TexParameter(target, TextureParameterName.TextureCompareFunc, (int)All.Never); - } - } - } -} diff --git a/Ryujinx.Graphics/Gal/ShaderDumper.cs b/Ryujinx.Graphics/Gal/ShaderDumper.cs deleted file mode 100644 index e25127de..00000000 --- a/Ryujinx.Graphics/Gal/ShaderDumper.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.IO; - -namespace Ryujinx.Graphics.Gal -{ - static class ShaderDumper - { - private static string _runtimeDir; - - public static int DumpIndex { get; private set; } = 1; - - public static void Dump(IGalMemory memory, long position, GalShaderType type, string extSuffix = "") - { - if (!IsDumpEnabled()) - { - return; - } - - string fileName = "Shader" + DumpIndex.ToString("d4") + "." + ShaderExtension(type) + extSuffix + ".bin"; - - string fullPath = Path.Combine(FullDir(), fileName); - string codePath = Path.Combine(CodeDir(), fileName); - - DumpIndex++; - - using (FileStream fullFile = File.Create(fullPath)) - using (FileStream codeFile = File.Create(codePath)) - { - BinaryWriter fullWriter = new BinaryWriter(fullFile); - BinaryWriter codeWriter = new BinaryWriter(codeFile); - - for (long i = 0; i < 0x50; i += 4) - { - fullWriter.Write(memory.ReadInt32(position + i)); - } - - long offset = 0; - - ulong instruction = 0; - - // Dump until a NOP instruction is found - while ((instruction >> 48 & 0xfff8) != 0x50b0) - { - uint word0 = (uint)memory.ReadInt32(position + 0x50 + offset + 0); - uint word1 = (uint)memory.ReadInt32(position + 0x50 + offset + 4); - - instruction = word0 | (ulong)word1 << 32; - - // Zero instructions (other kind of NOP) stop immediately, - // this is to avoid two rows of zeroes - if (instruction == 0) - { - break; - } - - fullWriter.Write(instruction); - codeWriter.Write(instruction); - - offset += 8; - } - - // Align to meet nvdisasm requirements - while (offset % 0x20 != 0) - { - fullWriter.Write(0); - codeWriter.Write(0); - - offset += 4; - } - } - } - - public static bool IsDumpEnabled() - { - return !string.IsNullOrWhiteSpace(GraphicsConfig.ShadersDumpPath); - } - - private static string FullDir() - { - return CreateAndReturn(Path.Combine(DumpDir(), "Full")); - } - - private static string CodeDir() - { - return CreateAndReturn(Path.Combine(DumpDir(), "Code")); - } - - private static string DumpDir() - { - if (string.IsNullOrEmpty(_runtimeDir)) - { - int index = 1; - - do - { - _runtimeDir = Path.Combine(GraphicsConfig.ShadersDumpPath, "Dumps" + index.ToString("d2")); - - index++; - } - while (Directory.Exists(_runtimeDir)); - - Directory.CreateDirectory(_runtimeDir); - } - - return _runtimeDir; - } - - private static string CreateAndReturn(string dir) - { - if (!Directory.Exists(dir)) - { - Directory.CreateDirectory(dir); - } - - return dir; - } - - private static string ShaderExtension(GalShaderType type) - { - switch (type) - { - case GalShaderType.Vertex: return "vert"; - case GalShaderType.TessControl: return "tesc"; - case GalShaderType.TessEvaluation: return "tese"; - case GalShaderType.Geometry: return "geom"; - case GalShaderType.Fragment: return "frag"; - - default: throw new ArgumentException(nameof(type)); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/ShaderException.cs b/Ryujinx.Graphics/Gal/ShaderException.cs deleted file mode 100644 index b0aff42b..00000000 --- a/Ryujinx.Graphics/Gal/ShaderException.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Gal -{ - class ShaderException : Exception - { - public ShaderException() : base() { } - - public ShaderException(string message) : base(message) { } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/GpuMethodCall.cs b/Ryujinx.Graphics/GpuMethodCall.cs deleted file mode 100644 index 4a310b07..00000000 --- a/Ryujinx.Graphics/GpuMethodCall.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Ryujinx.Graphics -{ - struct GpuMethodCall - { - public int Method { get; private set; } - public int Argument { get; private set; } - public int SubChannel { get; private set; } - public int MethodCount { get; private set; } - - public bool IsLastCall => MethodCount <= 1; - - public GpuMethodCall( - int method, - int argument, - int subChannel = 0, - int methodCount = 0) - { - Method = method; - Argument = argument; - SubChannel = subChannel; - MethodCount = methodCount; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/GpuResourceManager.cs b/Ryujinx.Graphics/GpuResourceManager.cs deleted file mode 100644 index 16e9f579..00000000 --- a/Ryujinx.Graphics/GpuResourceManager.cs +++ /dev/null @@ -1,169 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Memory; -using Ryujinx.Graphics.Texture; -using System.Collections.Generic; - -namespace Ryujinx.Graphics -{ - public class GpuResourceManager - { - private enum ImageType - { - None, - Texture, - TextureArrayLayer, - ColorBuffer, - ZetaBuffer - } - - private NvGpu _gpu; - - private HashSet<long>[] _uploadedKeys; - - private Dictionary<long, ImageType> _imageTypes; - private Dictionary<long, int> _mirroredTextures; - - public GpuResourceManager(NvGpu gpu) - { - _gpu = gpu; - - _uploadedKeys = new HashSet<long>[(int)NvGpuBufferType.Count]; - - for (int index = 0; index < _uploadedKeys.Length; index++) - { - _uploadedKeys[index] = new HashSet<long>(); - } - - _imageTypes = new Dictionary<long, ImageType>(); - _mirroredTextures = new Dictionary<long, int>(); - } - - public void SendColorBuffer(NvGpuVmm vmm, long position, int attachment, GalImage newImage) - { - long size = (uint)ImageUtils.GetSize(newImage); - - _imageTypes[position] = ImageType.ColorBuffer; - - if (!TryReuse(vmm, position, newImage)) - { - _gpu.Renderer.Texture.Create(position, (int)size, newImage); - } - - _gpu.Renderer.RenderTarget.BindColor(position, attachment); - } - - public void SendZetaBuffer(NvGpuVmm vmm, long position, GalImage newImage) - { - long size = (uint)ImageUtils.GetSize(newImage); - - _imageTypes[position] = ImageType.ZetaBuffer; - - if (!TryReuse(vmm, position, newImage)) - { - _gpu.Renderer.Texture.Create(position, (int)size, newImage); - } - - _gpu.Renderer.RenderTarget.BindZeta(position); - } - - public void SendTexture(NvGpuVmm vmm, long position, GalImage newImage) - { - PrepareSendTexture(vmm, position, newImage); - - _imageTypes[position] = ImageType.Texture; - } - - public bool TryGetTextureLayer(long position, out int layerIndex) - { - if (_mirroredTextures.TryGetValue(position, out layerIndex)) - { - ImageType type = _imageTypes[position]; - - // FIXME(thog): I'm actually unsure if we should deny all other image type, gpu testing needs to be done here. - if (type != ImageType.Texture && type != ImageType.TextureArrayLayer) - { - layerIndex = -1; - return false; - } - - return true; - } - - layerIndex = -1; - return false; - } - - public void SetTextureArrayLayer(long position, int layerIndex) - { - _imageTypes[position] = ImageType.TextureArrayLayer; - _mirroredTextures[position] = layerIndex; - } - - private void PrepareSendTexture(NvGpuVmm vmm, long position, GalImage newImage) - { - long size = ImageUtils.GetSize(newImage); - - bool skipCheck = false; - - if (_imageTypes.TryGetValue(position, out ImageType oldType)) - { - if (oldType == ImageType.ColorBuffer || oldType == ImageType.ZetaBuffer) - { - // Avoid data destruction - MemoryRegionModified(vmm, position, size, NvGpuBufferType.Texture); - - skipCheck = true; - } - } - - if (skipCheck || !MemoryRegionModified(vmm, position, size, NvGpuBufferType.Texture)) - { - if (TryReuse(vmm, position, newImage)) - { - return; - } - } - - byte[] data = ImageUtils.ReadTexture(vmm, newImage, position); - - _gpu.Renderer.Texture.Create(position, data, newImage); - } - - private bool TryReuse(NvGpuVmm vmm, long position, GalImage newImage) - { - if (_gpu.Renderer.Texture.TryGetImage(position, out GalImage cachedImage) && cachedImage.TextureTarget == newImage.TextureTarget && cachedImage.SizeMatches(newImage)) - { - _gpu.Renderer.RenderTarget.Reinterpret(position, newImage); - - return true; - } - - return false; - } - - public bool MemoryRegionModified(NvGpuVmm vmm, long position, long size, NvGpuBufferType type) - { - HashSet<long> uploaded = _uploadedKeys[(int)type]; - - if (!uploaded.Add(position)) - { - return false; - } - - return vmm.IsRegionModified(position, size, type); - } - - public void ClearPbCache() - { - for (int index = 0; index < _uploadedKeys.Length; index++) - { - _uploadedKeys[index].Clear(); - } - } - - public void ClearPbCache(NvGpuBufferType type) - { - _uploadedKeys[(int)type].Clear(); - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/INvGpuEngine.cs b/Ryujinx.Graphics/Graphics3d/INvGpuEngine.cs deleted file mode 100644 index aa0db682..00000000 --- a/Ryujinx.Graphics/Graphics3d/INvGpuEngine.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Ryujinx.Graphics.Memory; - -namespace Ryujinx.Graphics.Graphics3d -{ - interface INvGpuEngine - { - int[] Registers { get; } - - void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/MacroInterpreter.cs b/Ryujinx.Graphics/Graphics3d/MacroInterpreter.cs deleted file mode 100644 index 9a6206fa..00000000 --- a/Ryujinx.Graphics/Graphics3d/MacroInterpreter.cs +++ /dev/null @@ -1,416 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.Memory; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Graphics3d -{ - class MacroInterpreter - { - private enum AssignmentOperation - { - IgnoreAndFetch = 0, - Move = 1, - MoveAndSetMaddr = 2, - FetchAndSend = 3, - MoveAndSend = 4, - FetchAndSetMaddr = 5, - MoveAndSetMaddrThenFetchAndSend = 6, - MoveAndSetMaddrThenSendHigh = 7 - } - - private enum AluOperation - { - AluReg = 0, - AddImmediate = 1, - BitfieldReplace = 2, - BitfieldExtractLslImm = 3, - BitfieldExtractLslReg = 4, - ReadImmediate = 5 - } - - private enum AluRegOperation - { - Add = 0, - AddWithCarry = 1, - Subtract = 2, - SubtractWithBorrow = 3, - BitwiseExclusiveOr = 8, - BitwiseOr = 9, - BitwiseAnd = 10, - BitwiseAndNot = 11, - BitwiseNotAnd = 12 - } - - private NvGpuFifo _pFifo; - private INvGpuEngine _engine; - - public Queue<int> Fifo { get; private set; } - - private int[] _gprs; - - private int _methAddr; - private int _methIncr; - - private bool _carry; - - private int _opCode; - - private int _pipeOp; - - private int _pc; - - public MacroInterpreter(NvGpuFifo pFifo, INvGpuEngine engine) - { - _pFifo = pFifo; - _engine = engine; - - Fifo = new Queue<int>(); - - _gprs = new int[8]; - } - - public void Execute(NvGpuVmm vmm, int[] mme, int position, int param) - { - Reset(); - - _gprs[1] = param; - - _pc = position; - - FetchOpCode(mme); - - while (Step(vmm, mme)); - - // Due to the delay slot, we still need to execute - // one more instruction before we actually exit. - Step(vmm, mme); - } - - private void Reset() - { - for (int index = 0; index < _gprs.Length; index++) - { - _gprs[index] = 0; - } - - _methAddr = 0; - _methIncr = 0; - - _carry = false; - } - - private bool Step(NvGpuVmm vmm, int[] mme) - { - int baseAddr = _pc - 1; - - FetchOpCode(mme); - - if ((_opCode & 7) < 7) - { - // Operation produces a value. - AssignmentOperation asgOp = (AssignmentOperation)((_opCode >> 4) & 7); - - int result = GetAluResult(); - - switch (asgOp) - { - // Fetch parameter and ignore result. - case AssignmentOperation.IgnoreAndFetch: - { - SetDstGpr(FetchParam()); - - break; - } - - // Move result. - case AssignmentOperation.Move: - { - SetDstGpr(result); - - break; - } - - // Move result and use as Method Address. - case AssignmentOperation.MoveAndSetMaddr: - { - SetDstGpr(result); - - SetMethAddr(result); - - break; - } - - // Fetch parameter and send result. - case AssignmentOperation.FetchAndSend: - { - SetDstGpr(FetchParam()); - - Send(vmm, result); - - break; - } - - // Move and send result. - case AssignmentOperation.MoveAndSend: - { - SetDstGpr(result); - - Send(vmm, result); - - break; - } - - // Fetch parameter and use result as Method Address. - case AssignmentOperation.FetchAndSetMaddr: - { - SetDstGpr(FetchParam()); - - SetMethAddr(result); - - break; - } - - // Move result and use as Method Address, then fetch and send parameter. - case AssignmentOperation.MoveAndSetMaddrThenFetchAndSend: - { - SetDstGpr(result); - - SetMethAddr(result); - - Send(vmm, FetchParam()); - - break; - } - - // Move result and use as Method Address, then send bits 17:12 of result. - case AssignmentOperation.MoveAndSetMaddrThenSendHigh: - { - SetDstGpr(result); - - SetMethAddr(result); - - Send(vmm, (result >> 12) & 0x3f); - - break; - } - } - } - else - { - // Branch. - bool onNotZero = ((_opCode >> 4) & 1) != 0; - - bool taken = onNotZero - ? GetGprA() != 0 - : GetGprA() == 0; - - if (taken) - { - _pc = baseAddr + GetImm(); - - bool noDelays = (_opCode & 0x20) != 0; - - if (noDelays) - { - FetchOpCode(mme); - } - - return true; - } - } - - bool exit = (_opCode & 0x80) != 0; - - return !exit; - } - - private void FetchOpCode(int[] mme) - { - _opCode = _pipeOp; - - _pipeOp = mme[_pc++]; - } - - private int GetAluResult() - { - AluOperation op = (AluOperation)(_opCode & 7); - - switch (op) - { - case AluOperation.AluReg: - { - AluRegOperation aluOp = (AluRegOperation)((_opCode >> 17) & 0x1f); - - return GetAluResult(aluOp, GetGprA(), GetGprB()); - } - - case AluOperation.AddImmediate: - { - return GetGprA() + GetImm(); - } - - case AluOperation.BitfieldReplace: - case AluOperation.BitfieldExtractLslImm: - case AluOperation.BitfieldExtractLslReg: - { - int bfSrcBit = (_opCode >> 17) & 0x1f; - int bfSize = (_opCode >> 22) & 0x1f; - int bfDstBit = (_opCode >> 27) & 0x1f; - - int bfMask = (1 << bfSize) - 1; - - int dst = GetGprA(); - int src = GetGprB(); - - switch (op) - { - case AluOperation.BitfieldReplace: - { - src = (int)((uint)src >> bfSrcBit) & bfMask; - - dst &= ~(bfMask << bfDstBit); - - dst |= src << bfDstBit; - - return dst; - } - - case AluOperation.BitfieldExtractLslImm: - { - src = (int)((uint)src >> dst) & bfMask; - - return src << bfDstBit; - } - - case AluOperation.BitfieldExtractLslReg: - { - src = (int)((uint)src >> bfSrcBit) & bfMask; - - return src << dst; - } - } - - break; - } - - case AluOperation.ReadImmediate: - { - return Read(GetGprA() + GetImm()); - } - } - - throw new ArgumentException(nameof(_opCode)); - } - - private int GetAluResult(AluRegOperation aluOp, int a, int b) - { - switch (aluOp) - { - case AluRegOperation.Add: - { - ulong result = (ulong)a + (ulong)b; - - _carry = result > 0xffffffff; - - return (int)result; - } - - case AluRegOperation.AddWithCarry: - { - ulong result = (ulong)a + (ulong)b + (_carry ? 1UL : 0UL); - - _carry = result > 0xffffffff; - - return (int)result; - } - - case AluRegOperation.Subtract: - { - ulong result = (ulong)a - (ulong)b; - - _carry = result < 0x100000000; - - return (int)result; - } - - case AluRegOperation.SubtractWithBorrow: - { - ulong result = (ulong)a - (ulong)b - (_carry ? 0UL : 1UL); - - _carry = result < 0x100000000; - - return (int)result; - } - - case AluRegOperation.BitwiseExclusiveOr: return a ^ b; - case AluRegOperation.BitwiseOr: return a | b; - case AluRegOperation.BitwiseAnd: return a & b; - case AluRegOperation.BitwiseAndNot: return a & ~b; - case AluRegOperation.BitwiseNotAnd: return ~(a & b); - } - - throw new ArgumentOutOfRangeException(nameof(aluOp)); - } - - private int GetImm() - { - // Note: The immediate is signed, the sign-extension is intended here. - return _opCode >> 14; - } - - private void SetMethAddr(int value) - { - _methAddr = (value >> 0) & 0xfff; - _methIncr = (value >> 12) & 0x3f; - } - - private void SetDstGpr(int value) - { - _gprs[(_opCode >> 8) & 7] = value; - } - - private int GetGprA() - { - return GetGprValue((_opCode >> 11) & 7); - } - - private int GetGprB() - { - return GetGprValue((_opCode >> 14) & 7); - } - - private int GetGprValue(int index) - { - return index != 0 ? _gprs[index] : 0; - } - - private int FetchParam() - { - int value; - - if (!Fifo.TryDequeue(out value)) - { - Logger.PrintWarning(LogClass.Gpu, "Macro attempted to fetch an inexistent argument."); - - return 0; - } - - return value; - } - - private int Read(int reg) - { - return _engine.Registers[reg]; - } - - private void Send(NvGpuVmm vmm, int value) - { - GpuMethodCall methCall = new GpuMethodCall(_methAddr, value); - - _engine.CallMethod(vmm, methCall); - - _methAddr += _methIncr; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngine.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngine.cs deleted file mode 100644 index 20c36fda..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngine.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Graphics.Graphics3d -{ - enum NvGpuEngine - { - _2d = 0x902d, - _3d = 0xb197, - Compute = 0xb1c0, - P2mf = 0xa140, - M2mf = 0xb0b5 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs deleted file mode 100644 index b6dae2a3..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngine2d.cs +++ /dev/null @@ -1,263 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Memory; -using Ryujinx.Graphics.Texture; -using Ryujinx.Profiler; - -namespace Ryujinx.Graphics.Graphics3d -{ - class NvGpuEngine2d : INvGpuEngine - { - private enum CopyOperation - { - SrcCopyAnd, - RopAnd, - Blend, - SrcCopy, - Rop, - SrcCopyPremult, - BlendPremult - } - - public int[] Registers { get; private set; } - - private NvGpu _gpu; - - public NvGpuEngine2d(NvGpu gpu) - { - _gpu = gpu; - - Registers = new int[0x238]; - } - - public void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall) - { - WriteRegister(methCall); - - if ((NvGpuEngine2dReg)methCall.Method == NvGpuEngine2dReg.BlitSrcYInt) - { - TextureCopy(vmm); - } - } - - private void TextureCopy(NvGpuVmm vmm) - { - Profile.Begin(Profiles.GPU.Engine2d.TextureCopy); - - CopyOperation operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation); - - int dstFormat = ReadRegister(NvGpuEngine2dReg.DstFormat); - bool dstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0; - int dstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth); - int dstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight); - int dstDepth = ReadRegister(NvGpuEngine2dReg.DstDepth); - int dstLayer = ReadRegister(NvGpuEngine2dReg.DstLayer); - int dstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch); - int dstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions); - - int srcFormat = ReadRegister(NvGpuEngine2dReg.SrcFormat); - bool srcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0; - int srcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth); - int srcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight); - int srcDepth = ReadRegister(NvGpuEngine2dReg.SrcDepth); - int srcLayer = ReadRegister(NvGpuEngine2dReg.SrcLayer); - int srcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch); - int srcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions); - - int dstBlitX = ReadRegister(NvGpuEngine2dReg.BlitDstX); - int dstBlitY = ReadRegister(NvGpuEngine2dReg.BlitDstY); - int dstBlitW = ReadRegister(NvGpuEngine2dReg.BlitDstW); - int dstBlitH = ReadRegister(NvGpuEngine2dReg.BlitDstH); - - long blitDuDx = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDuDxFract); - long blitDvDy = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDvDyFract); - - long srcBlitX = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcXFract); - long srcBlitY = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcYFract); - - GalImageFormat srcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)srcFormat); - GalImageFormat dstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)dstFormat); - - GalMemoryLayout srcLayout = GetLayout(srcLinear); - GalMemoryLayout dstLayout = GetLayout(dstLinear); - - int srcBlockHeight = 1 << ((srcBlkDim >> 4) & 0xf); - int dstBlockHeight = 1 << ((dstBlkDim >> 4) & 0xf); - - long srcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress); - long dstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress); - - long srcKey = vmm.GetPhysicalAddress(srcAddress); - long dstKey = vmm.GetPhysicalAddress(dstAddress); - - bool isSrcLayered = false; - bool isDstLayered = false; - - GalTextureTarget srcTarget = GalTextureTarget.TwoD; - - if (srcDepth != 0) - { - srcTarget = GalTextureTarget.TwoDArray; - srcDepth++; - isSrcLayered = true; - } - else - { - srcDepth = 1; - } - - GalTextureTarget dstTarget = GalTextureTarget.TwoD; - - if (dstDepth != 0) - { - dstTarget = GalTextureTarget.TwoDArray; - dstDepth++; - isDstLayered = true; - } - else - { - dstDepth = 1; - } - - GalImage srcTexture = new GalImage( - srcWidth, - srcHeight, - 1, srcDepth, 1, - srcBlockHeight, 1, - srcLayout, - srcImgFormat, - srcTarget); - - GalImage dstTexture = new GalImage( - dstWidth, - dstHeight, - 1, dstDepth, 1, - dstBlockHeight, 1, - dstLayout, - dstImgFormat, - dstTarget); - - srcTexture.Pitch = srcPitch; - dstTexture.Pitch = dstPitch; - - long GetLayerOffset(GalImage image, int layer) - { - int targetMipLevel = image.MaxMipmapLevel <= 1 ? 1 : image.MaxMipmapLevel - 1; - return ImageUtils.GetLayerOffset(image, targetMipLevel) * layer; - } - - int srcLayerIndex = -1; - - if (isSrcLayered && _gpu.ResourceManager.TryGetTextureLayer(srcKey, out srcLayerIndex) && srcLayerIndex != 0) - { - srcKey = srcKey - GetLayerOffset(srcTexture, srcLayerIndex); - } - - int dstLayerIndex = -1; - - if (isDstLayered && _gpu.ResourceManager.TryGetTextureLayer(dstKey, out dstLayerIndex) && dstLayerIndex != 0) - { - dstKey = dstKey - GetLayerOffset(dstTexture, dstLayerIndex); - } - - _gpu.ResourceManager.SendTexture(vmm, srcKey, srcTexture); - _gpu.ResourceManager.SendTexture(vmm, dstKey, dstTexture); - - if (isSrcLayered && srcLayerIndex == -1) - { - for (int layer = 0; layer < srcTexture.LayerCount; layer++) - { - _gpu.ResourceManager.SetTextureArrayLayer(srcKey + GetLayerOffset(srcTexture, layer), layer); - } - - srcLayerIndex = 0; - } - - if (isDstLayered && dstLayerIndex == -1) - { - for (int layer = 0; layer < dstTexture.LayerCount; layer++) - { - _gpu.ResourceManager.SetTextureArrayLayer(dstKey + GetLayerOffset(dstTexture, layer), layer); - } - - dstLayerIndex = 0; - } - - int srcBlitX1 = (int)(srcBlitX >> 32); - int srcBlitY1 = (int)(srcBlitY >> 32); - - int srcBlitX2 = (int)(srcBlitX + dstBlitW * blitDuDx >> 32); - int srcBlitY2 = (int)(srcBlitY + dstBlitH * blitDvDy >> 32); - - _gpu.Renderer.RenderTarget.Copy( - srcTexture, - dstTexture, - srcKey, - dstKey, - srcLayerIndex, - dstLayerIndex, - srcBlitX1, - srcBlitY1, - srcBlitX2, - srcBlitY2, - dstBlitX, - dstBlitY, - dstBlitX + dstBlitW, - dstBlitY + dstBlitH); - - // Do a guest side copy as well. This is necessary when - // the texture is modified by the guest, however it doesn't - // work when resources that the gpu can write to are copied, - // like framebuffers. - - // FIXME: SUPPORT MULTILAYER CORRECTLY HERE (this will cause weird stuffs on the first layer) - ImageUtils.CopyTexture( - vmm, - srcTexture, - dstTexture, - srcAddress, - dstAddress, - srcBlitX1, - srcBlitY1, - dstBlitX, - dstBlitY, - dstBlitW, - dstBlitH); - - vmm.IsRegionModified(dstKey, ImageUtils.GetSize(dstTexture), NvGpuBufferType.Texture); - - Profile.End(Profiles.GPU.Engine2d.TextureCopy); - } - - private static GalMemoryLayout GetLayout(bool linear) - { - return linear - ? GalMemoryLayout.Pitch - : GalMemoryLayout.BlockLinear; - } - - private long MakeInt64From2xInt32(NvGpuEngine2dReg reg) - { - return - (long)Registers[(int)reg + 0] << 32 | - (uint)Registers[(int)reg + 1]; - } - - private void WriteRegister(GpuMethodCall methCall) - { - Registers[methCall.Method] = methCall.Argument; - } - - private long ReadRegisterFixed1_31_32(NvGpuEngine2dReg reg) - { - long low = (uint)ReadRegister(reg + 0); - long high = (uint)ReadRegister(reg + 1); - - return low | (high << 32); - } - - private int ReadRegister(NvGpuEngine2dReg reg) - { - return Registers[(int)reg]; - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngine2dReg.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngine2dReg.cs deleted file mode 100644 index 7747b5a3..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngine2dReg.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace Ryujinx.Graphics.Graphics3d -{ - enum NvGpuEngine2dReg - { - DstFormat = 0x80, - DstLinear = 0x81, - DstBlockDimensions = 0x82, - DstDepth = 0x83, - DstLayer = 0x84, - DstPitch = 0x85, - DstWidth = 0x86, - DstHeight = 0x87, - DstAddress = 0x88, - DstAddressLow = 0x89, - SrcFormat = 0x8c, - SrcLinear = 0x8d, - SrcBlockDimensions = 0x8e, - SrcDepth = 0x8f, - SrcLayer = 0x90, - SrcPitch = 0x91, - SrcWidth = 0x92, - SrcHeight = 0x93, - SrcAddress = 0x94, - SrcAddressLow = 0x95, - ClipEnable = 0xa4, - CopyOperation = 0xab, - BlitControl = 0x223, - BlitDstX = 0x22c, - BlitDstY = 0x22d, - BlitDstW = 0x22e, - BlitDstH = 0x22f, - BlitDuDxFract = 0x230, - BlitDuDxInt = 0x231, - BlitDvDyFract = 0x232, - BlitDvDyInt = 0x233, - BlitSrcXFract = 0x234, - BlitSrcXInt = 0x235, - BlitSrcYFract = 0x236, - BlitSrcYInt = 0x237 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs deleted file mode 100644 index e475a964..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngine3d.cs +++ /dev/null @@ -1,1237 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Memory; -using Ryujinx.Graphics.Shader; -using Ryujinx.Graphics.Texture; -using System; -using System.Collections.Generic; -using Ryujinx.Profiler; - -namespace Ryujinx.Graphics.Graphics3d -{ - class NvGpuEngine3d : INvGpuEngine - { - public int[] Registers { get; private set; } - - private NvGpu _gpu; - - private Dictionary<int, NvGpuMethod> _methods; - - private struct ConstBuffer - { - public bool Enabled; - public long Position; - public int Size; - } - - private ConstBuffer[][] _constBuffers; - - // Viewport dimensions kept for scissor test limits - private int _viewportX0 = 0; - private int _viewportY0 = 0; - private int _viewportX1 = 0; - private int _viewportY1 = 0; - private int _viewportWidth = 0; - private int _viewportHeight = 0; - - private int _currentInstance = 0; - - public NvGpuEngine3d(NvGpu gpu) - { - _gpu = gpu; - - Registers = new int[0xe00]; - - _methods = new Dictionary<int, NvGpuMethod>(); - - void AddMethod(int meth, int count, int stride, NvGpuMethod method) - { - while (count-- > 0) - { - _methods.Add(meth, method); - - meth += stride; - } - } - - AddMethod(0x585, 1, 1, VertexEndGl); - AddMethod(0x674, 1, 1, ClearBuffers); - AddMethod(0x6c3, 1, 1, QueryControl); - AddMethod(0x8e4, 16, 1, CbData); - AddMethod(0x904, 5, 8, CbBind); - - _constBuffers = new ConstBuffer[6][]; - - for (int index = 0; index < _constBuffers.Length; index++) - { - _constBuffers[index] = new ConstBuffer[18]; - } - - // Ensure that all components are enabled by default. - // FIXME: Is this correct? - WriteRegister(NvGpuEngine3dReg.ColorMaskN, 0x1111); - - WriteRegister(NvGpuEngine3dReg.FrameBufferSrgb, 1); - - WriteRegister(NvGpuEngine3dReg.FrontFace, (int)GalFrontFace.Cw); - - for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++) - { - WriteRegister(NvGpuEngine3dReg.IBlendNEquationRgb + index * 8, (int)GalBlendEquation.FuncAdd); - WriteRegister(NvGpuEngine3dReg.IBlendNFuncSrcRgb + index * 8, (int)GalBlendFactor.One); - WriteRegister(NvGpuEngine3dReg.IBlendNFuncDstRgb + index * 8, (int)GalBlendFactor.Zero); - WriteRegister(NvGpuEngine3dReg.IBlendNEquationAlpha + index * 8, (int)GalBlendEquation.FuncAdd); - WriteRegister(NvGpuEngine3dReg.IBlendNFuncSrcAlpha + index * 8, (int)GalBlendFactor.One); - WriteRegister(NvGpuEngine3dReg.IBlendNFuncDstAlpha + index * 8, (int)GalBlendFactor.Zero); - } - } - - public void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall) - { - if (_methods.TryGetValue(methCall.Method, out NvGpuMethod method)) - { - ProfileConfig profile = Profiles.GPU.Engine3d.CallMethod; - - profile.SessionItem = method.Method.Name; - - Profile.Begin(profile); - - method(vmm, methCall); - - Profile.End(profile); - } - else - { - WriteRegister(methCall); - } - } - - private void VertexEndGl(NvGpuVmm vmm, GpuMethodCall methCall) - { - Profile.Begin(Profiles.GPU.Engine3d.VertexEnd); - - LockCaches(); - - Profile.Begin(Profiles.GPU.Engine3d.ConfigureState); - - GalPipelineState state = new GalPipelineState(); - - // Framebuffer must be run configured because viewport dimensions may be used in other methods - SetFrameBuffer(state); - - Profile.End(Profiles.GPU.Engine3d.ConfigureState); - - for (int fbIndex = 0; fbIndex < 8; fbIndex++) - { - SetFrameBuffer(vmm, fbIndex); - } - - SetFrontFace(state); - SetCullFace(state); - SetDepth(state); - SetStencil(state); - SetScissor(state); - SetBlending(state); - SetColorMask(state); - SetPrimitiveRestart(state); - - SetZeta(vmm); - - SetRenderTargets(); - - long[] keys = UploadShaders(vmm); - - _gpu.Renderer.Shader.BindProgram(); - - UploadTextures(vmm, state, keys); - UploadConstBuffers(vmm, state, keys); - UploadVertexArrays(vmm, state); - - DispatchRender(vmm, state); - - UnlockCaches(); - - Profile.End(Profiles.GPU.Engine3d.VertexEnd); - } - - private void LockCaches() - { - _gpu.Renderer.Buffer.LockCache(); - _gpu.Renderer.Rasterizer.LockCaches(); - _gpu.Renderer.Texture.LockCache(); - } - - private void UnlockCaches() - { - _gpu.Renderer.Buffer.UnlockCache(); - _gpu.Renderer.Rasterizer.UnlockCaches(); - _gpu.Renderer.Texture.UnlockCache(); - } - - private void ClearBuffers(NvGpuVmm vmm, GpuMethodCall methCall) - { - Profile.Begin(Profiles.GPU.Engine3d.ClearBuffers); - - int attachment = (methCall.Argument >> 6) & 0xf; - - GalClearBufferFlags flags = (GalClearBufferFlags)(methCall.Argument & 0x3f); - - float red = ReadRegisterFloat(NvGpuEngine3dReg.ClearNColor + 0); - float green = ReadRegisterFloat(NvGpuEngine3dReg.ClearNColor + 1); - float blue = ReadRegisterFloat(NvGpuEngine3dReg.ClearNColor + 2); - float alpha = ReadRegisterFloat(NvGpuEngine3dReg.ClearNColor + 3); - - float depth = ReadRegisterFloat(NvGpuEngine3dReg.ClearDepth); - - int stencil = ReadRegister(NvGpuEngine3dReg.ClearStencil); - - SetFrameBuffer(vmm, attachment); - - SetZeta(vmm); - - SetRenderTargets(); - - _gpu.Renderer.RenderTarget.Bind(); - - _gpu.Renderer.Rasterizer.ClearBuffers(flags, attachment, red, green, blue, alpha, depth, stencil); - - _gpu.Renderer.Pipeline.ResetDepthMask(); - _gpu.Renderer.Pipeline.ResetColorMask(attachment); - - Profile.End(Profiles.GPU.Engine3d.ClearBuffers); - } - - private void SetFrameBuffer(NvGpuVmm vmm, int fbIndex) - { - ProfileConfig profile = Profiles.GPU.Engine3d.SetFrameBuffer; - - profile.SessionItem = fbIndex.ToString(); - - Profile.Begin(profile); - - long va = MakeInt64From2xInt32(NvGpuEngine3dReg.FrameBufferNAddress + fbIndex * 0x10); - - int surfFormat = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + fbIndex * 0x10); - - if (va == 0 || surfFormat == 0) - { - _gpu.Renderer.RenderTarget.UnbindColor(fbIndex); - - Profile.End(profile); - - return; - } - - long key = vmm.GetPhysicalAddress(va); - - int width = ReadRegister(NvGpuEngine3dReg.FrameBufferNWidth + fbIndex * 0x10); - int height = ReadRegister(NvGpuEngine3dReg.FrameBufferNHeight + fbIndex * 0x10); - - int arrayMode = ReadRegister(NvGpuEngine3dReg.FrameBufferNArrayMode + fbIndex * 0x10); - int layerCount = arrayMode & 0xFFFF; - int layerStride = ReadRegister(NvGpuEngine3dReg.FrameBufferNLayerStride + fbIndex * 0x10); - int baseLayer = ReadRegister(NvGpuEngine3dReg.FrameBufferNBaseLayer + fbIndex * 0x10); - int blockDim = ReadRegister(NvGpuEngine3dReg.FrameBufferNBlockDim + fbIndex * 0x10); - - int gobBlockHeight = 1 << ((blockDim >> 4) & 7); - - GalMemoryLayout layout = (GalMemoryLayout)((blockDim >> 12) & 1); - - float tx = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateX + fbIndex * 8); - float ty = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateY + fbIndex * 8); - - float sx = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNScaleX + fbIndex * 8); - float sy = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNScaleY + fbIndex * 8); - - _viewportX0 = (int)MathF.Max(0, tx - MathF.Abs(sx)); - _viewportY0 = (int)MathF.Max(0, ty - MathF.Abs(sy)); - - _viewportX1 = (int)(tx + MathF.Abs(sx)); - _viewportY1 = (int)(ty + MathF.Abs(sy)); - - GalImageFormat format = ImageUtils.ConvertSurface((GalSurfaceFormat)surfFormat); - - GalImage image = new GalImage(width, height, 1, 1, 1, gobBlockHeight, 1, layout, format, GalTextureTarget.TwoD); - - _gpu.ResourceManager.SendColorBuffer(vmm, key, fbIndex, image); - - _gpu.Renderer.RenderTarget.SetViewport(fbIndex, _viewportX0, _viewportY0, _viewportX1 - _viewportX0, _viewportY1 - _viewportY0); - - Profile.End(profile); - } - - private void SetFrameBuffer(GalPipelineState state) - { - state.FramebufferSrgb = ReadRegisterBool(NvGpuEngine3dReg.FrameBufferSrgb); - - state.FlipX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX); - state.FlipY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY); - - int screenYControl = ReadRegister(NvGpuEngine3dReg.ScreenYControl); - - bool negateY = (screenYControl & 1) != 0; - - if (negateY) - { - state.FlipY = -state.FlipY; - } - } - - private void SetZeta(NvGpuVmm vmm) - { - Profile.Begin(Profiles.GPU.Engine3d.SetZeta); - - long va = MakeInt64From2xInt32(NvGpuEngine3dReg.ZetaAddress); - - int zetaFormat = ReadRegister(NvGpuEngine3dReg.ZetaFormat); - - int blockDim = ReadRegister(NvGpuEngine3dReg.ZetaBlockDimensions); - - int gobBlockHeight = 1 << ((blockDim >> 4) & 7); - - GalMemoryLayout layout = (GalMemoryLayout)((blockDim >> 12) & 1); //? - - bool zetaEnable = ReadRegisterBool(NvGpuEngine3dReg.ZetaEnable); - - if (va == 0 || zetaFormat == 0 || !zetaEnable) - { - _gpu.Renderer.RenderTarget.UnbindZeta(); - - Profile.End(Profiles.GPU.Engine3d.SetZeta); - - return; - } - - long key = vmm.GetPhysicalAddress(va); - - int width = ReadRegister(NvGpuEngine3dReg.ZetaHoriz); - int height = ReadRegister(NvGpuEngine3dReg.ZetaVert); - - GalImageFormat format = ImageUtils.ConvertZeta((GalZetaFormat)zetaFormat); - - // TODO: Support non 2D? - GalImage image = new GalImage(width, height, 1, 1, 1, gobBlockHeight, 1, layout, format, GalTextureTarget.TwoD); - - _gpu.ResourceManager.SendZetaBuffer(vmm, key, image); - - Profile.End(Profiles.GPU.Engine3d.SetZeta); - } - - private long[] UploadShaders(NvGpuVmm vmm) - { - Profile.Begin(Profiles.GPU.Engine3d.UploadShaders); - - long[] keys = new long[5]; - - long basePosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); - - int index = 1; - - int vpAControl = ReadRegister(NvGpuEngine3dReg.ShaderNControl); - - bool vpAEnable = (vpAControl & 1) != 0; - - if (vpAEnable) - { - // Note: The maxwell supports 2 vertex programs, usually - // only VP B is used, but in some cases VP A is also used. - // In this case, it seems to function as an extra vertex - // shader stage. - // The graphics abstraction layer has a special overload for this - // case, which should merge the two shaders into one vertex shader. - int vpAOffset = ReadRegister(NvGpuEngine3dReg.ShaderNOffset); - int vpBOffset = ReadRegister(NvGpuEngine3dReg.ShaderNOffset + 0x10); - - long vpAPos = basePosition + (uint)vpAOffset; - long vpBPos = basePosition + (uint)vpBOffset; - - keys[(int)GalShaderType.Vertex] = vpBPos; - - _gpu.Renderer.Shader.Create(vmm, vpAPos, vpBPos, GalShaderType.Vertex); - _gpu.Renderer.Shader.Bind(vpBPos); - - index = 2; - } - - for (; index < 6; index++) - { - GalShaderType type = GetTypeFromProgram(index); - - int control = ReadRegister(NvGpuEngine3dReg.ShaderNControl + index * 0x10); - int offset = ReadRegister(NvGpuEngine3dReg.ShaderNOffset + index * 0x10); - - // Note: Vertex Program (B) is always enabled. - bool enable = (control & 1) != 0 || index == 1; - - if (!enable) - { - _gpu.Renderer.Shader.Unbind(type); - - continue; - } - - long key = basePosition + (uint)offset; - - keys[(int)type] = key; - - _gpu.Renderer.Shader.Create(vmm, key, type); - _gpu.Renderer.Shader.Bind(key); - } - - Profile.End(Profiles.GPU.Engine3d.UploadShaders); - - return keys; - } - - private static GalShaderType GetTypeFromProgram(int program) - { - switch (program) - { - case 0: - case 1: return GalShaderType.Vertex; - case 2: return GalShaderType.TessControl; - case 3: return GalShaderType.TessEvaluation; - case 4: return GalShaderType.Geometry; - case 5: return GalShaderType.Fragment; - } - - throw new ArgumentOutOfRangeException(nameof(program)); - } - - private void SetFrontFace(GalPipelineState state) - { - float signX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX); - float signY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY); - - GalFrontFace frontFace = (GalFrontFace)ReadRegister(NvGpuEngine3dReg.FrontFace); - - // Flipping breaks facing. Flipping front facing too fixes it - if (signX != signY) - { - switch (frontFace) - { - case GalFrontFace.Cw: frontFace = GalFrontFace.Ccw; break; - case GalFrontFace.Ccw: frontFace = GalFrontFace.Cw; break; - } - } - - state.FrontFace = frontFace; - } - - private void SetCullFace(GalPipelineState state) - { - state.CullFaceEnabled = ReadRegisterBool(NvGpuEngine3dReg.CullFaceEnable); - - if (state.CullFaceEnabled) - { - state.CullFace = (GalCullFace)ReadRegister(NvGpuEngine3dReg.CullFace); - } - } - - private void SetDepth(GalPipelineState state) - { - state.DepthTestEnabled = ReadRegisterBool(NvGpuEngine3dReg.DepthTestEnable); - - state.DepthWriteEnabled = ReadRegisterBool(NvGpuEngine3dReg.DepthWriteEnable); - - if (state.DepthTestEnabled) - { - state.DepthFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.DepthTestFunction); - } - - state.DepthRangeNear = ReadRegisterFloat(NvGpuEngine3dReg.DepthRangeNNear); - state.DepthRangeFar = ReadRegisterFloat(NvGpuEngine3dReg.DepthRangeNFar); - } - - private void SetStencil(GalPipelineState state) - { - state.StencilTestEnabled = ReadRegisterBool(NvGpuEngine3dReg.StencilEnable); - - if (state.StencilTestEnabled) - { - state.StencilBackFuncFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.StencilBackFuncFunc); - state.StencilBackFuncRef = ReadRegister(NvGpuEngine3dReg.StencilBackFuncRef); - state.StencilBackFuncMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilBackFuncMask); - state.StencilBackOpFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilBackOpFail); - state.StencilBackOpZFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilBackOpZFail); - state.StencilBackOpZPass = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilBackOpZPass); - state.StencilBackMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilBackMask); - - state.StencilFrontFuncFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.StencilFrontFuncFunc); - state.StencilFrontFuncRef = ReadRegister(NvGpuEngine3dReg.StencilFrontFuncRef); - state.StencilFrontFuncMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilFrontFuncMask); - state.StencilFrontOpFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilFrontOpFail); - state.StencilFrontOpZFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilFrontOpZFail); - state.StencilFrontOpZPass = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilFrontOpZPass); - state.StencilFrontMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilFrontMask); - } - } - - private void SetScissor(GalPipelineState state) - { - int count = 0; - - for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++) - { - state.ScissorTestEnabled[index] = ReadRegisterBool(NvGpuEngine3dReg.ScissorEnable + index * 4); - - if (state.ScissorTestEnabled[index]) - { - uint scissorHorizontal = (uint)ReadRegister(NvGpuEngine3dReg.ScissorHorizontal + index * 4); - uint scissorVertical = (uint)ReadRegister(NvGpuEngine3dReg.ScissorVertical + index * 4); - - int left = (int)(scissorHorizontal & 0xFFFF); // Left, lower 16 bits - int right = (int)(scissorHorizontal >> 16); // Right, upper 16 bits - - int bottom = (int)(scissorVertical & 0xFFFF); // Bottom, lower 16 bits - int top = (int)(scissorVertical >> 16); // Top, upper 16 bits - - int width = Math.Abs(right - left); - int height = Math.Abs(top - bottom); - - // If the scissor test covers the whole possible viewport, i.e. uninitialized, disable scissor test - if ((width > NvGpu.MaxViewportSize && height > NvGpu.MaxViewportSize) || width <= 0 || height <= 0) - { - state.ScissorTestEnabled[index] = false; - continue; - } - - // Keep track of how many scissor tests are active. - // If only 1, and it's the first user should apply to all viewports - count++; - - // Flip X - if (state.FlipX == -1) - { - left = _viewportX1 - (left - _viewportX0); - right = _viewportX1 - (right - _viewportX0); - } - - // Ensure X is in the right order - if (left > right) - { - int temp = left; - left = right; - right = temp; - } - - // Flip Y - if (state.FlipY == -1) - { - bottom = _viewportY1 - (bottom - _viewportY0); - top = _viewportY1 - (top - _viewportY0); - } - - // Ensure Y is in the right order - if (bottom > top) - { - int temp = top; - top = bottom; - bottom = temp; - } - - // Handle out of active viewport dimensions - left = Math.Clamp(left, _viewportX0, _viewportX1); - right = Math.Clamp(right, _viewportX0, _viewportX1); - top = Math.Clamp(top, _viewportY0, _viewportY1); - bottom = Math.Clamp(bottom, _viewportY0, _viewportY1); - - // Save values to state - state.ScissorTestX[index] = left; - state.ScissorTestY[index] = bottom; - - state.ScissorTestWidth[index] = right - left; - state.ScissorTestHeight[index] = top - bottom; - } - } - - state.ScissorTestCount = count; - } - - private void SetBlending(GalPipelineState state) - { - bool blendIndependent = ReadRegisterBool(NvGpuEngine3dReg.BlendIndependent); - - state.BlendIndependent = blendIndependent; - - for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++) - { - if (blendIndependent) - { - state.Blends[index].Enabled = ReadRegisterBool(NvGpuEngine3dReg.IBlendNEnable + index); - - if (state.Blends[index].Enabled) - { - state.Blends[index].SeparateAlpha = ReadRegisterBool(NvGpuEngine3dReg.IBlendNSeparateAlpha + index * 8); - - state.Blends[index].EquationRgb = ReadBlendEquation(NvGpuEngine3dReg.IBlendNEquationRgb + index * 8); - state.Blends[index].FuncSrcRgb = ReadBlendFactor (NvGpuEngine3dReg.IBlendNFuncSrcRgb + index * 8); - state.Blends[index].FuncDstRgb = ReadBlendFactor (NvGpuEngine3dReg.IBlendNFuncDstRgb + index * 8); - state.Blends[index].EquationAlpha = ReadBlendEquation(NvGpuEngine3dReg.IBlendNEquationAlpha + index * 8); - state.Blends[index].FuncSrcAlpha = ReadBlendFactor (NvGpuEngine3dReg.IBlendNFuncSrcAlpha + index * 8); - state.Blends[index].FuncDstAlpha = ReadBlendFactor (NvGpuEngine3dReg.IBlendNFuncDstAlpha + index * 8); - } - } - else - { - // It seems that even when independent blend is disabled, the first IBlend enable - // register is still set to indicate whenever blend is enabled or not (?). - state.Blends[index].Enabled = ReadRegisterBool(NvGpuEngine3dReg.IBlendNEnable); - - if (state.Blends[index].Enabled) - { - state.Blends[index].SeparateAlpha = ReadRegisterBool(NvGpuEngine3dReg.BlendSeparateAlpha); - - state.Blends[index].EquationRgb = ReadBlendEquation(NvGpuEngine3dReg.BlendEquationRgb); - state.Blends[index].FuncSrcRgb = ReadBlendFactor (NvGpuEngine3dReg.BlendFuncSrcRgb); - state.Blends[index].FuncDstRgb = ReadBlendFactor (NvGpuEngine3dReg.BlendFuncDstRgb); - state.Blends[index].EquationAlpha = ReadBlendEquation(NvGpuEngine3dReg.BlendEquationAlpha); - state.Blends[index].FuncSrcAlpha = ReadBlendFactor (NvGpuEngine3dReg.BlendFuncSrcAlpha); - state.Blends[index].FuncDstAlpha = ReadBlendFactor (NvGpuEngine3dReg.BlendFuncDstAlpha); - } - } - } - } - - private GalBlendEquation ReadBlendEquation(NvGpuEngine3dReg register) - { - return (GalBlendEquation)ReadRegister(register); - } - - private GalBlendFactor ReadBlendFactor(NvGpuEngine3dReg register) - { - return (GalBlendFactor)ReadRegister(register); - } - - private void SetColorMask(GalPipelineState state) - { - bool colorMaskCommon = ReadRegisterBool(NvGpuEngine3dReg.ColorMaskCommon); - - state.ColorMaskCommon = colorMaskCommon; - - for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++) - { - int colorMask = ReadRegister(NvGpuEngine3dReg.ColorMaskN + (colorMaskCommon ? 0 : index)); - - state.ColorMasks[index].Red = ((colorMask >> 0) & 0xf) != 0; - state.ColorMasks[index].Green = ((colorMask >> 4) & 0xf) != 0; - state.ColorMasks[index].Blue = ((colorMask >> 8) & 0xf) != 0; - state.ColorMasks[index].Alpha = ((colorMask >> 12) & 0xf) != 0; - } - } - - private void SetPrimitiveRestart(GalPipelineState state) - { - state.PrimitiveRestartEnabled = ReadRegisterBool(NvGpuEngine3dReg.PrimRestartEnable); - - if (state.PrimitiveRestartEnabled) - { - state.PrimitiveRestartIndex = (uint)ReadRegister(NvGpuEngine3dReg.PrimRestartIndex); - } - } - - private void SetRenderTargets() - { - // Commercial games do not seem to - // bool SeparateFragData = ReadRegisterBool(NvGpuEngine3dReg.RTSeparateFragData); - - uint control = (uint)(ReadRegister(NvGpuEngine3dReg.RtControl)); - - uint count = control & 0xf; - - if (count > 0) - { - int[] map = new int[count]; - - for (int index = 0; index < count; index++) - { - int shift = 4 + index * 3; - - map[index] = (int)((control >> shift) & 7); - } - - _gpu.Renderer.RenderTarget.SetMap(map); - } - else - { - _gpu.Renderer.RenderTarget.SetMap(null); - } - } - - private void UploadTextures(NvGpuVmm vmm, GalPipelineState state, long[] keys) - { - Profile.Begin(Profiles.GPU.Engine3d.UploadTextures); - - long baseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); - - int textureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex); - - List<(long, GalImage, GalTextureSampler)> unboundTextures = new List<(long, GalImage, GalTextureSampler)>(); - - for (int index = 0; index < keys.Length; index++) - { - foreach (TextureDescriptor desc in _gpu.Renderer.Shader.GetTextureUsage(keys[index])) - { - int textureHandle; - - if (desc.IsBindless) - { - long position = _constBuffers[index][desc.CbufSlot].Position; - - textureHandle = vmm.ReadInt32(position + desc.CbufOffset * 4); - } - else - { - long position = _constBuffers[index][textureCbIndex].Position; - - textureHandle = vmm.ReadInt32(position + desc.HandleIndex * 4); - } - - unboundTextures.Add(UploadTexture(vmm, textureHandle)); - } - } - - for (int index = 0; index < unboundTextures.Count; index++) - { - (long key, GalImage image, GalTextureSampler sampler) = unboundTextures[index]; - - if (key == 0) - { - continue; - } - - _gpu.Renderer.Texture.Bind(key, index, image); - _gpu.Renderer.Texture.SetSampler(image, sampler); - } - - Profile.End(Profiles.GPU.Engine3d.UploadTextures); - } - - private (long, GalImage, GalTextureSampler) UploadTexture(NvGpuVmm vmm, int textureHandle) - { - if (textureHandle == 0) - { - // FIXME: Some games like puyo puyo will use handles with the value 0. - // This is a bug, most likely caused by sync issues. - return (0, default(GalImage), default(GalTextureSampler)); - } - - Profile.Begin(Profiles.GPU.Engine3d.UploadTexture); - - bool linkedTsc = ReadRegisterBool(NvGpuEngine3dReg.LinkedTsc); - - int ticIndex = (textureHandle >> 0) & 0xfffff; - - int tscIndex = linkedTsc ? ticIndex : (textureHandle >> 20) & 0xfff; - - long ticPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexHeaderPoolOffset); - long tscPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexSamplerPoolOffset); - - ticPosition += ticIndex * 0x20; - tscPosition += tscIndex * 0x20; - - GalImage image = TextureFactory.MakeTexture(vmm, ticPosition); - - GalTextureSampler sampler = TextureFactory.MakeSampler(_gpu, vmm, tscPosition); - - long key = vmm.ReadInt64(ticPosition + 4) & 0xffffffffffff; - - if (image.Layout == GalMemoryLayout.BlockLinear) - { - key &= ~0x1ffL; - } - else if (image.Layout == GalMemoryLayout.Pitch) - { - key &= ~0x1fL; - } - - key = vmm.GetPhysicalAddress(key); - - if (key == -1) - { - Profile.End(Profiles.GPU.Engine3d.UploadTexture); - - // FIXME: Shouldn't ignore invalid addresses. - return (0, default(GalImage), default(GalTextureSampler)); - } - - _gpu.ResourceManager.SendTexture(vmm, key, image); - - Profile.End(Profiles.GPU.Engine3d.UploadTexture); - - return (key, image, sampler); - } - - private void UploadConstBuffers(NvGpuVmm vmm, GalPipelineState state, long[] keys) - { - Profile.Begin(Profiles.GPU.Engine3d.UploadConstBuffers); - - for (int stage = 0; stage < keys.Length; stage++) - { - foreach (CBufferDescriptor desc in _gpu.Renderer.Shader.GetConstBufferUsage(keys[stage])) - { - ConstBuffer cb = _constBuffers[stage][desc.Slot]; - - if (!cb.Enabled) - { - continue; - } - - long key = vmm.GetPhysicalAddress(cb.Position); - - if (_gpu.ResourceManager.MemoryRegionModified(vmm, key, cb.Size, NvGpuBufferType.ConstBuffer)) - { - if (vmm.TryGetHostAddress(cb.Position, cb.Size, out IntPtr cbPtr)) - { - _gpu.Renderer.Buffer.SetData(key, cb.Size, cbPtr); - } - else - { - _gpu.Renderer.Buffer.SetData(key, vmm.ReadBytes(cb.Position, cb.Size)); - } - } - - state.ConstBufferKeys[stage][desc.Slot] = key; - } - } - - Profile.End(Profiles.GPU.Engine3d.UploadConstBuffers); - } - - private void UploadVertexArrays(NvGpuVmm vmm, GalPipelineState state) - { - Profile.Begin(Profiles.GPU.Engine3d.UploadVertexArrays); - - long ibPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.IndexArrayAddress); - - long iboKey = vmm.GetPhysicalAddress(ibPosition); - - int indexEntryFmt = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat); - int indexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount); - int primCtrl = ReadRegister(NvGpuEngine3dReg.VertexBeginGl); - - GalPrimitiveType primType = (GalPrimitiveType)(primCtrl & 0xffff); - - GalIndexFormat indexFormat = (GalIndexFormat)indexEntryFmt; - - int indexEntrySize = 1 << indexEntryFmt; - - if (indexEntrySize > 4) - { - throw new InvalidOperationException("Invalid index entry size \"" + indexEntrySize + "\"!"); - } - - if (indexCount != 0) - { - int ibSize = indexCount * indexEntrySize; - - bool iboCached = _gpu.Renderer.Rasterizer.IsIboCached(iboKey, (uint)ibSize); - - bool usesLegacyQuads = - primType == GalPrimitiveType.Quads || - primType == GalPrimitiveType.QuadStrip; - - if (!iboCached || _gpu.ResourceManager.MemoryRegionModified(vmm, iboKey, (uint)ibSize, NvGpuBufferType.Index)) - { - if (!usesLegacyQuads) - { - if (vmm.TryGetHostAddress(ibPosition, ibSize, out IntPtr ibPtr)) - { - _gpu.Renderer.Rasterizer.CreateIbo(iboKey, ibSize, ibPtr); - } - else - { - _gpu.Renderer.Rasterizer.CreateIbo(iboKey, ibSize, vmm.ReadBytes(ibPosition, ibSize)); - } - } - else - { - byte[] buffer = vmm.ReadBytes(ibPosition, ibSize); - - if (primType == GalPrimitiveType.Quads) - { - buffer = QuadHelper.ConvertQuadsToTris(buffer, indexEntrySize, indexCount); - } - else /* if (PrimType == GalPrimitiveType.QuadStrip) */ - { - buffer = QuadHelper.ConvertQuadStripToTris(buffer, indexEntrySize, indexCount); - } - - _gpu.Renderer.Rasterizer.CreateIbo(iboKey, ibSize, buffer); - } - } - - if (!usesLegacyQuads) - { - _gpu.Renderer.Rasterizer.SetIndexArray(ibSize, indexFormat); - } - else - { - if (primType == GalPrimitiveType.Quads) - { - _gpu.Renderer.Rasterizer.SetIndexArray(QuadHelper.ConvertSizeQuadsToTris(ibSize), indexFormat); - } - else /* if (PrimType == GalPrimitiveType.QuadStrip) */ - { - _gpu.Renderer.Rasterizer.SetIndexArray(QuadHelper.ConvertSizeQuadStripToTris(ibSize), indexFormat); - } - } - } - - List<GalVertexAttrib>[] attribs = new List<GalVertexAttrib>[32]; - - for (int attr = 0; attr < 16; attr++) - { - int packed = ReadRegister(NvGpuEngine3dReg.VertexAttribNFormat + attr); - - int arrayIndex = packed & 0x1f; - - if (attribs[arrayIndex] == null) - { - attribs[arrayIndex] = new List<GalVertexAttrib>(); - } - - long vbPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.VertexArrayNAddress + arrayIndex * 4); - - if (vbPosition == 0) - { - continue; - } - - bool isConst = ((packed >> 6) & 1) != 0; - - int offset = (packed >> 7) & 0x3fff; - - GalVertexAttribSize size = (GalVertexAttribSize)((packed >> 21) & 0x3f); - GalVertexAttribType type = (GalVertexAttribType)((packed >> 27) & 0x7); - - bool isRgba = ((packed >> 31) & 1) != 0; - - // Check vertex array is enabled to avoid out of bounds exception when reading bytes - bool enable = (ReadRegister(NvGpuEngine3dReg.VertexArrayNControl + arrayIndex * 4) & 0x1000) != 0; - - // Note: 16 is the maximum size of an attribute, - // having a component size of 32-bits with 4 elements (a vec4). - if (enable) - { - byte[] data = vmm.ReadBytes(vbPosition + offset, 16); - - attribs[arrayIndex].Add(new GalVertexAttrib(attr, isConst, offset, data, size, type, isRgba)); - } - } - - state.VertexBindings = new GalVertexBinding[32]; - - for (int index = 0; index < 32; index++) - { - if (attribs[index] == null) - { - continue; - } - - int control = ReadRegister(NvGpuEngine3dReg.VertexArrayNControl + index * 4); - - bool enable = (control & 0x1000) != 0; - - if (!enable) - { - continue; - } - - long vbPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.VertexArrayNAddress + index * 4); - long vbEndPos = MakeInt64From2xInt32(NvGpuEngine3dReg.VertexArrayNEndAddr + index * 2); - - int vertexDivisor = ReadRegister(NvGpuEngine3dReg.VertexArrayNDivisor + index * 4); - - bool instanced = ReadRegisterBool(NvGpuEngine3dReg.VertexArrayNInstance + index); - - int stride = control & 0xfff; - - if (instanced && vertexDivisor != 0) - { - vbPosition += stride * (_currentInstance / vertexDivisor); - } - - if (vbPosition > vbEndPos) - { - // Instance is invalid, ignore the draw call - continue; - } - - long vboKey = vmm.GetPhysicalAddress(vbPosition); - - long vbSize = (vbEndPos - vbPosition) + 1; - int modifiedVbSize = (int)vbSize; - - - // If quads convert size to triangle length - if (stride == 0) - { - if (primType == GalPrimitiveType.Quads) - { - modifiedVbSize = QuadHelper.ConvertSizeQuadsToTris(modifiedVbSize); - } - else if (primType == GalPrimitiveType.QuadStrip) - { - modifiedVbSize = QuadHelper.ConvertSizeQuadStripToTris(modifiedVbSize); - } - } - - bool vboCached = _gpu.Renderer.Rasterizer.IsVboCached(vboKey, modifiedVbSize); - - if (!vboCached || _gpu.ResourceManager.MemoryRegionModified(vmm, vboKey, vbSize, NvGpuBufferType.Vertex)) - { - if ((primType == GalPrimitiveType.Quads | primType == GalPrimitiveType.QuadStrip) && stride != 0) - { - // Convert quad buffer to triangles - byte[] data = vmm.ReadBytes(vbPosition, vbSize); - - if (primType == GalPrimitiveType.Quads) - { - data = QuadHelper.ConvertQuadsToTris(data, stride, (int)(vbSize / stride)); - } - else - { - data = QuadHelper.ConvertQuadStripToTris(data, stride, (int)(vbSize / stride)); - } - _gpu.Renderer.Rasterizer.CreateVbo(vboKey, data); - } - else if (vmm.TryGetHostAddress(vbPosition, vbSize, out IntPtr vbPtr)) - { - _gpu.Renderer.Rasterizer.CreateVbo(vboKey, (int)vbSize, vbPtr); - } - else - { - _gpu.Renderer.Rasterizer.CreateVbo(vboKey, vmm.ReadBytes(vbPosition, vbSize)); - } - } - - state.VertexBindings[index].Enabled = true; - state.VertexBindings[index].Stride = stride; - state.VertexBindings[index].VboKey = vboKey; - state.VertexBindings[index].Instanced = instanced; - state.VertexBindings[index].Divisor = vertexDivisor; - state.VertexBindings[index].Attribs = attribs[index].ToArray(); - } - - Profile.End(Profiles.GPU.Engine3d.UploadVertexArrays); - } - - private void DispatchRender(NvGpuVmm vmm, GalPipelineState state) - { - int indexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount); - int primCtrl = ReadRegister(NvGpuEngine3dReg.VertexBeginGl); - - GalPrimitiveType primType = (GalPrimitiveType)(primCtrl & 0xffff); - - bool instanceNext = ((primCtrl >> 26) & 1) != 0; - bool instanceCont = ((primCtrl >> 27) & 1) != 0; - - if (instanceNext && instanceCont) - { - throw new InvalidOperationException("GPU tried to increase and reset instance count at the same time"); - } - - if (instanceNext) - { - _currentInstance++; - } - else if (!instanceCont) - { - _currentInstance = 0; - } - - state.Instance = _currentInstance; - - _gpu.Renderer.Pipeline.Bind(state); - - _gpu.Renderer.RenderTarget.Bind(); - - if (indexCount != 0) - { - int indexEntryFmt = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat); - int indexFirst = ReadRegister(NvGpuEngine3dReg.IndexBatchFirst); - int vertexBase = ReadRegister(NvGpuEngine3dReg.VertexArrayElemBase); - - long indexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.IndexArrayAddress); - - long iboKey = vmm.GetPhysicalAddress(indexPosition); - - // Quad primitive types were deprecated on OpenGL 3.x, - // they are converted to a triangles index buffer on IB creation, - // so we should use the triangles type here too. - if (primType == GalPrimitiveType.Quads || primType == GalPrimitiveType.QuadStrip) - { - // Note: We assume that index first points to the first - // vertex of a quad, if it points to the middle of a - // quad (First % 4 != 0 for Quads) then it will not work properly. - if (primType == GalPrimitiveType.Quads) - { - indexFirst = QuadHelper.ConvertSizeQuadsToTris(indexFirst); - } - else // QuadStrip - { - indexFirst = QuadHelper.ConvertSizeQuadStripToTris(indexFirst); - } - - primType = GalPrimitiveType.Triangles; - } - - _gpu.Renderer.Rasterizer.DrawElements(iboKey, indexFirst, vertexBase, primType); - } - else - { - int vertexFirst = ReadRegister(NvGpuEngine3dReg.VertexArrayFirst); - int vertexCount = ReadRegister(NvGpuEngine3dReg.VertexArrayCount); - - // Quad primitive types were deprecated on OpenGL 3.x, - // they are converted to a triangles index buffer on IB creation, - // so we should use the triangles type here too. - if (primType == GalPrimitiveType.Quads || primType == GalPrimitiveType.QuadStrip) - { - // Note: We assume that index first points to the first - // vertex of a quad, if it points to the middle of a - // quad (First % 4 != 0 for Quads) then it will not work properly. - if (primType == GalPrimitiveType.Quads) - { - vertexFirst = QuadHelper.ConvertSizeQuadsToTris(vertexFirst); - } - else // QuadStrip - { - vertexFirst = QuadHelper.ConvertSizeQuadStripToTris(vertexFirst); - } - - primType = GalPrimitiveType.Triangles; - vertexCount = QuadHelper.ConvertSizeQuadsToTris(vertexCount); - } - - _gpu.Renderer.Rasterizer.DrawArrays(vertexFirst, vertexCount, primType); - } - - // Reset pipeline for host OpenGL calls - _gpu.Renderer.Pipeline.Unbind(state); - - // Is the GPU really clearing those registers after draw? - WriteRegister(NvGpuEngine3dReg.IndexBatchFirst, 0); - WriteRegister(NvGpuEngine3dReg.IndexBatchCount, 0); - } - - private enum QueryMode - { - WriteSeq, - Sync, - WriteCounterAndTimestamp - } - - private void QueryControl(NvGpuVmm vmm, GpuMethodCall methCall) - { - WriteRegister(methCall); - - long position = MakeInt64From2xInt32(NvGpuEngine3dReg.QueryAddress); - - int seq = Registers[(int)NvGpuEngine3dReg.QuerySequence]; - int ctrl = Registers[(int)NvGpuEngine3dReg.QueryControl]; - - QueryMode mode = (QueryMode)(ctrl & 3); - - switch (mode) - { - case QueryMode.WriteSeq: vmm.WriteInt32(position, seq); break; - - case QueryMode.WriteCounterAndTimestamp: - { - // TODO: Implement counters. - long counter = 1; - - long timestamp = PerformanceCounter.ElapsedMilliseconds; - - vmm.WriteInt64(position + 0, counter); - vmm.WriteInt64(position + 8, timestamp); - - break; - } - } - } - - private void CbData(NvGpuVmm vmm, GpuMethodCall methCall) - { - long position = MakeInt64From2xInt32(NvGpuEngine3dReg.ConstBufferAddress); - - int offset = ReadRegister(NvGpuEngine3dReg.ConstBufferOffset); - - vmm.WriteInt32(position + offset, methCall.Argument); - - WriteRegister(NvGpuEngine3dReg.ConstBufferOffset, offset + 4); - - _gpu.ResourceManager.ClearPbCache(NvGpuBufferType.ConstBuffer); - } - - private void CbBind(NvGpuVmm vmm, GpuMethodCall methCall) - { - int stage = (methCall.Method - 0x904) >> 3; - - int index = methCall.Argument; - - bool enabled = (index & 1) != 0; - - index = (index >> 4) & 0x1f; - - long position = MakeInt64From2xInt32(NvGpuEngine3dReg.ConstBufferAddress); - - long cbKey = vmm.GetPhysicalAddress(position); - - int size = ReadRegister(NvGpuEngine3dReg.ConstBufferSize); - - if (!_gpu.Renderer.Buffer.IsCached(cbKey, size)) - { - _gpu.Renderer.Buffer.Create(cbKey, size); - } - - ConstBuffer cb = _constBuffers[stage][index]; - - if (cb.Position != position || cb.Enabled != enabled || cb.Size != size) - { - _constBuffers[stage][index].Position = position; - _constBuffers[stage][index].Enabled = enabled; - _constBuffers[stage][index].Size = size; - } - } - - private float GetFlipSign(NvGpuEngine3dReg reg) - { - return MathF.Sign(ReadRegisterFloat(reg)); - } - - private long MakeInt64From2xInt32(NvGpuEngine3dReg reg) - { - return - (long)Registers[(int)reg + 0] << 32 | - (uint)Registers[(int)reg + 1]; - } - - private void WriteRegister(GpuMethodCall methCall) - { - Registers[methCall.Method] = methCall.Argument; - } - - private int ReadRegister(NvGpuEngine3dReg reg) - { - return Registers[(int)reg]; - } - - private float ReadRegisterFloat(NvGpuEngine3dReg reg) - { - return BitConverter.Int32BitsToSingle(ReadRegister(reg)); - } - - private bool ReadRegisterBool(NvGpuEngine3dReg reg) - { - return (ReadRegister(reg) & 1) != 0; - } - - private void WriteRegister(NvGpuEngine3dReg reg, int value) - { - Registers[(int)reg] = value; - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngine3dReg.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngine3dReg.cs deleted file mode 100644 index c6596a30..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngine3dReg.cs +++ /dev/null @@ -1,116 +0,0 @@ -namespace Ryujinx.Graphics.Graphics3d -{ - enum NvGpuEngine3dReg - { - FrameBufferNAddress = 0x200, - FrameBufferNWidth = 0x202, - FrameBufferNHeight = 0x203, - FrameBufferNFormat = 0x204, - FrameBufferNBlockDim = 0x205, - FrameBufferNArrayMode = 0x206, - FrameBufferNLayerStride = 0x207, - FrameBufferNBaseLayer = 0x208, - ViewportNScaleX = 0x280, - ViewportNScaleY = 0x281, - ViewportNScaleZ = 0x282, - ViewportNTranslateX = 0x283, - ViewportNTranslateY = 0x284, - ViewportNTranslateZ = 0x285, - ViewportNHoriz = 0x300, - ViewportNVert = 0x301, - DepthRangeNNear = 0x302, - DepthRangeNFar = 0x303, - VertexArrayFirst = 0x35d, - VertexArrayCount = 0x35e, - ClearNColor = 0x360, - ClearDepth = 0x364, - ClearStencil = 0x368, - ScissorEnable = 0x380, - ScissorHorizontal = 0x381, - ScissorVertical = 0x382, - StencilBackFuncRef = 0x3d5, - StencilBackMask = 0x3d6, - StencilBackFuncMask = 0x3d7, - ColorMaskCommon = 0x3e4, - RtSeparateFragData = 0x3eb, - ZetaAddress = 0x3f8, - ZetaFormat = 0x3fa, - ZetaBlockDimensions = 0x3fb, - ZetaLayerStride = 0x3fc, - VertexAttribNFormat = 0x458, - RtControl = 0x487, - ZetaHoriz = 0x48a, - ZetaVert = 0x48b, - ZetaArrayMode = 0x48c, - LinkedTsc = 0x48d, - DepthTestEnable = 0x4b3, - BlendIndependent = 0x4b9, - DepthWriteEnable = 0x4ba, - DepthTestFunction = 0x4c3, - BlendSeparateAlpha = 0x4cf, - BlendEquationRgb = 0x4d0, - BlendFuncSrcRgb = 0x4d1, - BlendFuncDstRgb = 0x4d2, - BlendEquationAlpha = 0x4d3, - BlendFuncSrcAlpha = 0x4d4, - BlendFuncDstAlpha = 0x4d6, - BlendEnable = 0x4d7, - IBlendNEnable = 0x4d8, - StencilEnable = 0x4e0, - StencilFrontOpFail = 0x4e1, - StencilFrontOpZFail = 0x4e2, - StencilFrontOpZPass = 0x4e3, - StencilFrontFuncFunc = 0x4e4, - StencilFrontFuncRef = 0x4e5, - StencilFrontFuncMask = 0x4e6, - StencilFrontMask = 0x4e7, - ScreenYControl = 0x4eb, - VertexArrayElemBase = 0x50d, - VertexArrayInstBase = 0x50e, - ZetaEnable = 0x54e, - TexHeaderPoolOffset = 0x55d, - TexSamplerPoolOffset = 0x557, - StencilTwoSideEnable = 0x565, - StencilBackOpFail = 0x566, - StencilBackOpZFail = 0x567, - StencilBackOpZPass = 0x568, - StencilBackFuncFunc = 0x569, - FrameBufferSrgb = 0x56e, - ShaderAddress = 0x582, - VertexBeginGl = 0x586, - PrimRestartEnable = 0x591, - PrimRestartIndex = 0x592, - IndexArrayAddress = 0x5f2, - IndexArrayEndAddr = 0x5f4, - IndexArrayFormat = 0x5f6, - IndexBatchFirst = 0x5f7, - IndexBatchCount = 0x5f8, - VertexArrayNInstance = 0x620, - CullFaceEnable = 0x646, - FrontFace = 0x647, - CullFace = 0x648, - ColorMaskN = 0x680, - QueryAddress = 0x6c0, - QuerySequence = 0x6c2, - QueryControl = 0x6c3, - VertexArrayNControl = 0x700, - VertexArrayNAddress = 0x701, - VertexArrayNDivisor = 0x703, - IBlendNSeparateAlpha = 0x780, - IBlendNEquationRgb = 0x781, - IBlendNFuncSrcRgb = 0x782, - IBlendNFuncDstRgb = 0x783, - IBlendNEquationAlpha = 0x784, - IBlendNFuncSrcAlpha = 0x785, - IBlendNFuncDstAlpha = 0x786, - VertexArrayNEndAddr = 0x7c0, - ShaderNControl = 0x800, - ShaderNOffset = 0x801, - ShaderNMaxGprs = 0x803, - ShaderNType = 0x804, - ConstBufferSize = 0x8e0, - ConstBufferAddress = 0x8e1, - ConstBufferOffset = 0x8e3, - TextureCbIndex = 0x982 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngineM2mf.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngineM2mf.cs deleted file mode 100644 index fca8ae22..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngineM2mf.cs +++ /dev/null @@ -1,214 +0,0 @@ -using Ryujinx.Graphics.Memory; -using Ryujinx.Graphics.Texture; -using System.Collections.Generic; -using Ryujinx.Profiler; - -namespace Ryujinx.Graphics.Graphics3d -{ - class NvGpuEngineM2mf : INvGpuEngine - { - public int[] Registers { get; private set; } - - private NvGpu _gpu; - - private Dictionary<int, NvGpuMethod> _methods; - - public NvGpuEngineM2mf(NvGpu gpu) - { - _gpu = gpu; - - Registers = new int[0x1d6]; - - _methods = new Dictionary<int, NvGpuMethod>(); - - void AddMethod(int meth, int count, int stride, NvGpuMethod method) - { - while (count-- > 0) - { - _methods.Add(meth, method); - - meth += stride; - } - } - - AddMethod(0xc0, 1, 1, Execute); - } - - public void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall) - { - if (_methods.TryGetValue(methCall.Method, out NvGpuMethod method)) - { - ProfileConfig profile = Profiles.GPU.EngineM2mf.CallMethod; - - profile.SessionItem = method.Method.Name; - - Profile.Begin(profile); - method(vmm, methCall); - Profile.End(profile); - } - else - { - WriteRegister(methCall); - } - } - - private void Execute(NvGpuVmm vmm, GpuMethodCall methCall) - { - Profile.Begin(Profiles.GPU.EngineM2mf.Execute); - - // TODO: Some registers and copy modes are still not implemented. - int control = methCall.Argument; - - bool srcLinear = ((control >> 7) & 1) != 0; - bool dstLinear = ((control >> 8) & 1) != 0; - bool copy2D = ((control >> 9) & 1) != 0; - - long srcAddress = MakeInt64From2xInt32(NvGpuEngineM2mfReg.SrcAddress); - long dstAddress = MakeInt64From2xInt32(NvGpuEngineM2mfReg.DstAddress); - - int srcPitch = ReadRegister(NvGpuEngineM2mfReg.SrcPitch); - int dstPitch = ReadRegister(NvGpuEngineM2mfReg.DstPitch); - - int xCount = ReadRegister(NvGpuEngineM2mfReg.XCount); - int yCount = ReadRegister(NvGpuEngineM2mfReg.YCount); - - int swizzle = ReadRegister(NvGpuEngineM2mfReg.Swizzle); - - int dstBlkDim = ReadRegister(NvGpuEngineM2mfReg.DstBlkDim); - int dstSizeX = ReadRegister(NvGpuEngineM2mfReg.DstSizeX); - int dstSizeY = ReadRegister(NvGpuEngineM2mfReg.DstSizeY); - int dstSizeZ = ReadRegister(NvGpuEngineM2mfReg.DstSizeZ); - int dstPosXY = ReadRegister(NvGpuEngineM2mfReg.DstPosXY); - int dstPosZ = ReadRegister(NvGpuEngineM2mfReg.DstPosZ); - - int srcBlkDim = ReadRegister(NvGpuEngineM2mfReg.SrcBlkDim); - int srcSizeX = ReadRegister(NvGpuEngineM2mfReg.SrcSizeX); - int srcSizeY = ReadRegister(NvGpuEngineM2mfReg.SrcSizeY); - int srcSizeZ = ReadRegister(NvGpuEngineM2mfReg.SrcSizeZ); - int srcPosXY = ReadRegister(NvGpuEngineM2mfReg.SrcPosXY); - int srcPosZ = ReadRegister(NvGpuEngineM2mfReg.SrcPosZ); - - int srcCpp = ((swizzle >> 20) & 7) + 1; - int dstCpp = ((swizzle >> 24) & 7) + 1; - - int dstPosX = (dstPosXY >> 0) & 0xffff; - int dstPosY = (dstPosXY >> 16) & 0xffff; - - int srcPosX = (srcPosXY >> 0) & 0xffff; - int srcPosY = (srcPosXY >> 16) & 0xffff; - - int srcBlockHeight = 1 << ((srcBlkDim >> 4) & 0xf); - int dstBlockHeight = 1 << ((dstBlkDim >> 4) & 0xf); - - long srcPa = vmm.GetPhysicalAddress(srcAddress); - long dstPa = vmm.GetPhysicalAddress(dstAddress); - - if (copy2D) - { - if (srcLinear) - { - srcPosX = srcPosY = srcPosZ = 0; - } - - if (dstLinear) - { - dstPosX = dstPosY = dstPosZ = 0; - } - - if (srcLinear && dstLinear) - { - for (int y = 0; y < yCount; y++) - { - int srcOffset = (srcPosY + y) * srcPitch + srcPosX * srcCpp; - int dstOffset = (dstPosY + y) * dstPitch + dstPosX * dstCpp; - - long src = srcPa + (uint)srcOffset; - long dst = dstPa + (uint)dstOffset; - - vmm.Memory.CopyBytes(src, dst, xCount * srcCpp); - } - } - else - { - ISwizzle srcSwizzle; - - if (srcLinear) - { - srcSwizzle = new LinearSwizzle(srcPitch, srcCpp, srcSizeX, srcSizeY); - } - else - { - srcSwizzle = new BlockLinearSwizzle( - srcSizeX, - srcSizeY, 1, - srcBlockHeight, 1, - srcCpp); - } - - ISwizzle dstSwizzle; - - if (dstLinear) - { - dstSwizzle = new LinearSwizzle(dstPitch, dstCpp, srcSizeX, srcSizeY); - } - else - { - dstSwizzle = new BlockLinearSwizzle( - dstSizeX, - dstSizeY, 1, - dstBlockHeight, 1, - dstCpp); - } - - // Calculate the bits per pixel - int bpp = srcPitch / xCount; - - // Copying all the bits at the same time corrupts the texture, unknown why but probably because the texture isn't linear - // To avoid this we will simply loop more times to cover all the bits, - // this allows up to recalculate the memory locations for each iteration around the loop - xCount *= bpp / srcCpp; - - for (int y = 0; y < yCount; y++) - for (int x = 0; x < xCount; x++) - { - int srcOffset = srcSwizzle.GetSwizzleOffset(srcPosX + x, srcPosY + y, 0); - int dstOffset = dstSwizzle.GetSwizzleOffset(dstPosX + x, dstPosY + y, 0); - - long src = srcPa + (uint)srcOffset; - long dst = dstPa + (uint)dstOffset; - - vmm.Memory.CopyBytes(src, dst, srcCpp); - } - } - } - else - { - vmm.Memory.CopyBytes(srcPa, dstPa, xCount); - } - - Profile.End(Profiles.GPU.EngineM2mf.Execute); - } - - private long MakeInt64From2xInt32(NvGpuEngineM2mfReg reg) - { - return - (long)Registers[(int)reg + 0] << 32 | - (uint)Registers[(int)reg + 1]; - } - - private void WriteRegister(GpuMethodCall methCall) - { - Registers[methCall.Method] = methCall.Argument; - } - - private int ReadRegister(NvGpuEngineM2mfReg reg) - { - return Registers[(int)reg]; - } - - private void WriteRegister(NvGpuEngineM2mfReg reg, int value) - { - Registers[(int)reg] = value; - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngineM2mfReg.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngineM2mfReg.cs deleted file mode 100644 index 4bef8d9e..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngineM2mfReg.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Ryujinx.Graphics.Graphics3d -{ - enum NvGpuEngineM2mfReg - { - SrcAddress = 0x100, - DstAddress = 0x102, - SrcPitch = 0x104, - DstPitch = 0x105, - XCount = 0x106, - YCount = 0x107, - Swizzle = 0x1c2, - DstBlkDim = 0x1c3, - DstSizeX = 0x1c4, - DstSizeY = 0x1c5, - DstSizeZ = 0x1c6, - DstPosZ = 0x1c7, - DstPosXY = 0x1c8, - SrcBlkDim = 0x1ca, - SrcSizeX = 0x1cb, - SrcSizeY = 0x1cc, - SrcSizeZ = 0x1cd, - SrcPosZ = 0x1ce, - SrcPosXY = 0x1cf - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngineP2mf.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngineP2mf.cs deleted file mode 100644 index 2b2c7b5f..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngineP2mf.cs +++ /dev/null @@ -1,179 +0,0 @@ -using Ryujinx.Graphics.Memory; -using Ryujinx.Graphics.Texture; -using System.Collections.Generic; -using Ryujinx.Profiler; - -namespace Ryujinx.Graphics.Graphics3d -{ - class NvGpuEngineP2mf : INvGpuEngine - { - public int[] Registers { get; private set; } - - private NvGpu _gpu; - - private Dictionary<int, NvGpuMethod> _methods; - - private int _copyStartX; - private int _copyStartY; - - private int _copyWidth; - private int _copyHeight; - private int _copyGobBlockHeight; - - private long _copyAddress; - - private int _copyOffset; - private int _copySize; - - private bool _copyLinear; - - private byte[] _buffer; - - public NvGpuEngineP2mf(NvGpu gpu) - { - _gpu = gpu; - - Registers = new int[0x80]; - - _methods = new Dictionary<int, NvGpuMethod>(); - - void AddMethod(int meth, int count, int stride, NvGpuMethod method) - { - while (count-- > 0) - { - _methods.Add(meth, method); - - meth += stride; - } - } - - AddMethod(0x6c, 1, 1, Execute); - AddMethod(0x6d, 1, 1, PushData); - } - - public void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall) - { - if (_methods.TryGetValue(methCall.Method, out NvGpuMethod method)) - { - ProfileConfig profile = Profiles.GPU.EngineP2mf.PushData; - - profile.SessionItem = method.Method.Name; - - Profile.Begin(profile); - method(vmm, methCall); - Profile.End(profile); - } - else - { - WriteRegister(methCall); - } - } - - private void Execute(NvGpuVmm vmm, GpuMethodCall methCall) - { - Profile.Begin(Profiles.GPU.EngineP2mf.Execute); - - // TODO: Some registers and copy modes are still not implemented. - int control = methCall.Argument; - - long dstAddress = MakeInt64From2xInt32(NvGpuEngineP2mfReg.DstAddress); - - int dstPitch = ReadRegister(NvGpuEngineP2mfReg.DstPitch); - int dstBlkDim = ReadRegister(NvGpuEngineP2mfReg.DstBlockDim); - - int dstX = ReadRegister(NvGpuEngineP2mfReg.DstX); - int dstY = ReadRegister(NvGpuEngineP2mfReg.DstY); - - int dstWidth = ReadRegister(NvGpuEngineP2mfReg.DstWidth); - int dstHeight = ReadRegister(NvGpuEngineP2mfReg.DstHeight); - - int lineLengthIn = ReadRegister(NvGpuEngineP2mfReg.LineLengthIn); - int lineCount = ReadRegister(NvGpuEngineP2mfReg.LineCount); - - _copyLinear = (control & 1) != 0; - - _copyGobBlockHeight = 1 << ((dstBlkDim >> 4) & 0xf); - - _copyStartX = dstX; - _copyStartY = dstY; - - _copyWidth = dstWidth; - _copyHeight = dstHeight; - - _copyAddress = dstAddress; - - _copyOffset = 0; - _copySize = lineLengthIn * lineCount; - - _buffer = new byte[_copySize]; - - Profile.End(Profiles.GPU.EngineP2mf.Execute); - } - - private void PushData(NvGpuVmm vmm, GpuMethodCall methCall) - { - if (_buffer == null) - { - return; - } - - Profile.Begin(Profiles.GPU.EngineP2mf.PushData); - - for (int shift = 0; shift < 32 && _copyOffset < _copySize; shift += 8, _copyOffset++) - { - _buffer[_copyOffset] = (byte)(methCall.Argument >> shift); - } - - if (methCall.IsLastCall) - { - if (_copyLinear) - { - vmm.WriteBytes(_copyAddress, _buffer); - } - else - { - BlockLinearSwizzle swizzle = new BlockLinearSwizzle( - _copyWidth, - _copyHeight, 1, - _copyGobBlockHeight, 1, 1); - - int srcOffset = 0; - - for (int y = _copyStartY; y < _copyHeight && srcOffset < _copySize; y++) - for (int x = _copyStartX; x < _copyWidth && srcOffset < _copySize; x++) - { - int dstOffset = swizzle.GetSwizzleOffset(x, y, 0); - - vmm.WriteByte(_copyAddress + dstOffset, _buffer[srcOffset++]); - } - } - - _buffer = null; - } - - Profile.End(Profiles.GPU.EngineP2mf.PushData); - } - - private long MakeInt64From2xInt32(NvGpuEngineP2mfReg reg) - { - return - (long)Registers[(int)reg + 0] << 32 | - (uint)Registers[(int)reg + 1]; - } - - private void WriteRegister(GpuMethodCall methCall) - { - Registers[methCall.Method] = methCall.Argument; - } - - private int ReadRegister(NvGpuEngineP2mfReg reg) - { - return Registers[(int)reg]; - } - - private void WriteRegister(NvGpuEngineP2mfReg reg, int value) - { - Registers[(int)reg] = value; - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuEngineP2mfReg.cs b/Ryujinx.Graphics/Graphics3d/NvGpuEngineP2mfReg.cs deleted file mode 100644 index ab3a304d..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuEngineP2mfReg.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Ryujinx.Graphics.Graphics3d -{ - enum NvGpuEngineP2mfReg - { - LineLengthIn = 0x60, - LineCount = 0x61, - DstAddress = 0x62, - DstPitch = 0x64, - DstBlockDim = 0x65, - DstWidth = 0x66, - DstHeight = 0x67, - DstDepth = 0x68, - DstZ = 0x69, - DstX = 0x6a, - DstY = 0x6b - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuFifo.cs b/Ryujinx.Graphics/Graphics3d/NvGpuFifo.cs deleted file mode 100644 index 23bfd0b3..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuFifo.cs +++ /dev/null @@ -1,176 +0,0 @@ -using Ryujinx.Graphics.Memory; - -namespace Ryujinx.Graphics.Graphics3d -{ - class NvGpuFifo - { - private const int MacrosCount = 0x80; - private const int MacroIndexMask = MacrosCount - 1; - - // Note: The size of the macro memory is unknown, we just make - // a guess here and use 256kb as the size. Increase if needed. - private const int MmeWords = 256 * 256; - - private NvGpu _gpu; - - private NvGpuEngine[] _subChannels; - - private struct CachedMacro - { - public int Position { get; private set; } - - private bool _executionPending; - private int _argument; - - private MacroInterpreter _interpreter; - - public CachedMacro(NvGpuFifo pFifo, INvGpuEngine engine, int position) - { - Position = position; - - _executionPending = false; - _argument = 0; - - _interpreter = new MacroInterpreter(pFifo, engine); - } - - public void StartExecution(int argument) - { - _argument = argument; - - _executionPending = true; - } - - public void Execute(NvGpuVmm vmm, int[] mme) - { - if (_executionPending) - { - _executionPending = false; - - _interpreter?.Execute(vmm, mme, Position, _argument); - } - } - - public void PushArgument(int argument) - { - _interpreter?.Fifo.Enqueue(argument); - } - } - - private int _currMacroPosition; - private int _currMacroBindIndex; - - private CachedMacro[] _macros; - - private int[] _mme; - - public NvGpuFifo(NvGpu gpu) - { - _gpu = gpu; - - _subChannels = new NvGpuEngine[8]; - - _macros = new CachedMacro[MacrosCount]; - - _mme = new int[MmeWords]; - } - - public void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall) - { - if ((NvGpuFifoMeth)methCall.Method == NvGpuFifoMeth.BindChannel) - { - NvGpuEngine engine = (NvGpuEngine)methCall.Argument; - - _subChannels[methCall.SubChannel] = engine; - } - else - { - switch (_subChannels[methCall.SubChannel]) - { - case NvGpuEngine._2d: Call2dMethod (vmm, methCall); break; - case NvGpuEngine._3d: Call3dMethod (vmm, methCall); break; - case NvGpuEngine.P2mf: CallP2mfMethod(vmm, methCall); break; - case NvGpuEngine.M2mf: CallM2mfMethod(vmm, methCall); break; - } - } - } - - private void Call2dMethod(NvGpuVmm vmm, GpuMethodCall methCall) - { - _gpu.Engine2d.CallMethod(vmm, methCall); - } - - private void Call3dMethod(NvGpuVmm vmm, GpuMethodCall methCall) - { - if (methCall.Method < 0x80) - { - switch ((NvGpuFifoMeth)methCall.Method) - { - case NvGpuFifoMeth.SetMacroUploadAddress: - { - _currMacroPosition = methCall.Argument; - - break; - } - - case NvGpuFifoMeth.SendMacroCodeData: - { - _mme[_currMacroPosition++] = methCall.Argument; - - break; - } - - case NvGpuFifoMeth.SetMacroBindingIndex: - { - _currMacroBindIndex = methCall.Argument; - - break; - } - - case NvGpuFifoMeth.BindMacro: - { - int position = methCall.Argument; - - _macros[_currMacroBindIndex++] = new CachedMacro(this, _gpu.Engine3d, position); - - break; - } - - default: CallP2mfMethod(vmm, methCall); break; - } - } - else if (methCall.Method < 0xe00) - { - _gpu.Engine3d.CallMethod(vmm, methCall); - } - else - { - int macroIndex = (methCall.Method >> 1) & MacroIndexMask; - - if ((methCall.Method & 1) != 0) - { - _macros[macroIndex].PushArgument(methCall.Argument); - } - else - { - _macros[macroIndex].StartExecution(methCall.Argument); - } - - if (methCall.IsLastCall) - { - _macros[macroIndex].Execute(vmm, _mme); - } - } - } - - private void CallP2mfMethod(NvGpuVmm vmm, GpuMethodCall methCall) - { - _gpu.EngineP2mf.CallMethod(vmm, methCall); - } - - private void CallM2mfMethod(NvGpuVmm vmm, GpuMethodCall methCall) - { - _gpu.EngineM2mf.CallMethod(vmm, methCall); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuFifoMeth.cs b/Ryujinx.Graphics/Graphics3d/NvGpuFifoMeth.cs deleted file mode 100644 index 9bf528b3..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuFifoMeth.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Graphics.Graphics3d -{ - enum NvGpuFifoMeth - { - BindChannel = 0, - SetMacroUploadAddress = 0x45, - SendMacroCodeData = 0x46, - SetMacroBindingIndex = 0x47, - BindMacro = 0x48 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/NvGpuMethod.cs b/Ryujinx.Graphics/Graphics3d/NvGpuMethod.cs deleted file mode 100644 index 23185c81..00000000 --- a/Ryujinx.Graphics/Graphics3d/NvGpuMethod.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Ryujinx.Graphics.Memory; - -namespace Ryujinx.Graphics.Graphics3d -{ - delegate void NvGpuMethod(NvGpuVmm vmm, GpuMethodCall methCall); -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/Texture/AstcDecoder.cs b/Ryujinx.Graphics/Graphics3d/Texture/AstcDecoder.cs deleted file mode 100644 index 3e68be7d..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/AstcDecoder.cs +++ /dev/null @@ -1,1385 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; - -namespace Ryujinx.Graphics.Texture -{ - public class AstcDecoderException : Exception - { - public AstcDecoderException(string exMsg) : base(exMsg) { } - } - - // https://github.com/GammaUNC/FasTC/blob/master/ASTCEncoder/src/Decompressor.cpp - public static class AstcDecoder - { - struct TexelWeightParams - { - public int Width; - public int Height; - public bool DualPlane; - public int MaxWeight; - public bool Error; - public bool VoidExtentLdr; - public bool VoidExtentHdr; - - public int GetPackedBitSize() - { - // How many indices do we have? - int indices = Height * Width; - - if (DualPlane) - { - indices *= 2; - } - - IntegerEncoded intEncoded = IntegerEncoded.CreateEncoding(MaxWeight); - - return intEncoded.GetBitLength(indices); - } - - public int GetNumWeightValues() - { - int ret = Width * Height; - - if (DualPlane) - { - ret *= 2; - } - - return ret; - } - } - - public static byte[] DecodeToRgba8888( - byte[] inputBuffer, - int blockX, - int blockY, - int blockZ, - int x, - int y, - int z) - { - using (MemoryStream inputStream = new MemoryStream(inputBuffer)) - { - BinaryReader binReader = new BinaryReader(inputStream); - - if (blockX > 12 || blockY > 12) - { - throw new AstcDecoderException("Block size unsupported!"); - } - - if (blockZ != 1 || z != 1) - { - // TODO: Support 3D textures? - throw new AstcDecoderException("3D compressed textures unsupported!"); - } - - using (MemoryStream outputStream = new MemoryStream()) - { - int blockIndex = 0; - - for (int j = 0; j < y; j += blockY) - { - for (int i = 0; i < x; i += blockX) - { - int[] decompressedData = new int[144]; - - DecompressBlock(binReader.ReadBytes(0x10), decompressedData, blockX, blockY); - - int decompressedWidth = Math.Min(blockX, x - i); - int decompressedHeight = Math.Min(blockY, y - j); - int baseOffsets = (j * x + i) * 4; - - for (int jj = 0; jj < decompressedHeight; jj++) - { - outputStream.Seek(baseOffsets + jj * x * 4, SeekOrigin.Begin); - - byte[] outputBuffer = new byte[decompressedData.Length * sizeof(int)]; - Buffer.BlockCopy(decompressedData, 0, outputBuffer, 0, outputBuffer.Length); - - outputStream.Write(outputBuffer, jj * blockX * 4, decompressedWidth * 4); - } - - blockIndex++; - } - } - - return outputStream.ToArray(); - } - } - } - - public static bool DecompressBlock( - byte[] inputBuffer, - int[] outputBuffer, - int blockWidth, - int blockHeight) - { - BitArrayStream bitStream = new BitArrayStream(new BitArray(inputBuffer)); - TexelWeightParams texelParams = DecodeBlockInfo(bitStream); - - if (texelParams.Error) - { - throw new AstcDecoderException("Invalid block mode"); - } - - if (texelParams.VoidExtentLdr) - { - FillVoidExtentLdr(bitStream, outputBuffer, blockWidth, blockHeight); - - return true; - } - - if (texelParams.VoidExtentHdr) - { - throw new AstcDecoderException("HDR void extent blocks are unsupported!"); - } - - if (texelParams.Width > blockWidth) - { - throw new AstcDecoderException("Texel weight grid width should be smaller than block width"); - } - - if (texelParams.Height > blockHeight) - { - throw new AstcDecoderException("Texel weight grid height should be smaller than block height"); - } - - // Read num partitions - int numberPartitions = bitStream.ReadBits(2) + 1; - Debug.Assert(numberPartitions <= 4); - - if (numberPartitions == 4 && texelParams.DualPlane) - { - throw new AstcDecoderException("Dual plane mode is incompatible with four partition blocks"); - } - - // Based on the number of partitions, read the color endpoint mode for - // each partition. - - // Determine partitions, partition index, and color endpoint modes - int planeIndices = -1; - int partitionIndex; - uint[] colorEndpointMode = { 0, 0, 0, 0 }; - - BitArrayStream colorEndpointStream = new BitArrayStream(new BitArray(16 * 8)); - - // Read extra config data... - uint baseColorEndpointMode = 0; - - if (numberPartitions == 1) - { - colorEndpointMode[0] = (uint)bitStream.ReadBits(4); - partitionIndex = 0; - } - else - { - partitionIndex = bitStream.ReadBits(10); - baseColorEndpointMode = (uint)bitStream.ReadBits(6); - } - - uint baseMode = (baseColorEndpointMode & 3); - - // Remaining bits are color endpoint data... - int numberWeightBits = texelParams.GetPackedBitSize(); - int remainingBits = 128 - numberWeightBits - bitStream.Position; - - // Consider extra bits prior to texel data... - uint extraColorEndpointModeBits = 0; - - if (baseMode != 0) - { - switch (numberPartitions) - { - case 2: extraColorEndpointModeBits += 2; break; - case 3: extraColorEndpointModeBits += 5; break; - case 4: extraColorEndpointModeBits += 8; break; - default: Debug.Assert(false); break; - } - } - - remainingBits -= (int)extraColorEndpointModeBits; - - // Do we have a dual plane situation? - int planeSelectorBits = 0; - - if (texelParams.DualPlane) - { - planeSelectorBits = 2; - } - - remainingBits -= planeSelectorBits; - - // Read color data... - int colorDataBits = remainingBits; - - while (remainingBits > 0) - { - int numberBits = Math.Min(remainingBits, 8); - int bits = bitStream.ReadBits(numberBits); - colorEndpointStream.WriteBits(bits, numberBits); - remainingBits -= 8; - } - - // Read the plane selection bits - planeIndices = bitStream.ReadBits(planeSelectorBits); - - // Read the rest of the CEM - if (baseMode != 0) - { - uint extraColorEndpointMode = (uint)bitStream.ReadBits((int)extraColorEndpointModeBits); - uint tempColorEndpointMode = (extraColorEndpointMode << 6) | baseColorEndpointMode; - tempColorEndpointMode >>= 2; - - bool[] c = new bool[4]; - - for (int i = 0; i < numberPartitions; i++) - { - c[i] = (tempColorEndpointMode & 1) != 0; - tempColorEndpointMode >>= 1; - } - - byte[] m = new byte[4]; - - for (int i = 0; i < numberPartitions; i++) - { - m[i] = (byte)(tempColorEndpointMode & 3); - tempColorEndpointMode >>= 2; - Debug.Assert(m[i] <= 3); - } - - for (int i = 0; i < numberPartitions; i++) - { - colorEndpointMode[i] = baseMode; - if (!(c[i])) colorEndpointMode[i] -= 1; - colorEndpointMode[i] <<= 2; - colorEndpointMode[i] |= m[i]; - } - } - else if (numberPartitions > 1) - { - uint tempColorEndpointMode = baseColorEndpointMode >> 2; - - for (uint i = 0; i < numberPartitions; i++) - { - colorEndpointMode[i] = tempColorEndpointMode; - } - } - - // Make sure everything up till here is sane. - for (int i = 0; i < numberPartitions; i++) - { - Debug.Assert(colorEndpointMode[i] < 16); - } - Debug.Assert(bitStream.Position + texelParams.GetPackedBitSize() == 128); - - // Decode both color data and texel weight data - int[] colorValues = new int[32]; // Four values * two endpoints * four maximum partitions - DecodeColorValues(colorValues, colorEndpointStream.ToByteArray(), colorEndpointMode, numberPartitions, colorDataBits); - - AstcPixel[][] endPoints = new AstcPixel[4][]; - endPoints[0] = new AstcPixel[2]; - endPoints[1] = new AstcPixel[2]; - endPoints[2] = new AstcPixel[2]; - endPoints[3] = new AstcPixel[2]; - - int colorValuesPosition = 0; - - for (int i = 0; i < numberPartitions; i++) - { - ComputeEndpoints(endPoints[i], colorValues, colorEndpointMode[i], ref colorValuesPosition); - } - - // Read the texel weight data. - byte[] texelWeightData = (byte[])inputBuffer.Clone(); - - // Reverse everything - for (int i = 0; i < 8; i++) - { - byte a = ReverseByte(texelWeightData[i]); - byte b = ReverseByte(texelWeightData[15 - i]); - - texelWeightData[i] = b; - texelWeightData[15 - i] = a; - } - - // Make sure that higher non-texel bits are set to zero - int clearByteStart = (texelParams.GetPackedBitSize() >> 3) + 1; - texelWeightData[clearByteStart - 1] &= (byte)((1 << (texelParams.GetPackedBitSize() % 8)) - 1); - - int cLen = 16 - clearByteStart; - for (int i = clearByteStart; i < clearByteStart + cLen; i++) texelWeightData[i] = 0; - - List<IntegerEncoded> texelWeightValues = new List<IntegerEncoded>(); - BitArrayStream weightBitStream = new BitArrayStream(new BitArray(texelWeightData)); - - IntegerEncoded.DecodeIntegerSequence(texelWeightValues, weightBitStream, texelParams.MaxWeight, texelParams.GetNumWeightValues()); - - // Blocks can be at most 12x12, so we can have as many as 144 weights - int[][] weights = new int[2][]; - weights[0] = new int[144]; - weights[1] = new int[144]; - - UnquantizeTexelWeights(weights, texelWeightValues, texelParams, blockWidth, blockHeight); - - // Now that we have endpoints and weights, we can interpolate and generate - // the proper decoding... - for (int j = 0; j < blockHeight; j++) - { - for (int i = 0; i < blockWidth; i++) - { - int partition = Select2dPartition(partitionIndex, i, j, numberPartitions, ((blockHeight * blockWidth) < 32)); - Debug.Assert(partition < numberPartitions); - - AstcPixel pixel = new AstcPixel(0, 0, 0, 0); - for (int component = 0; component < 4; component++) - { - int component0 = endPoints[partition][0].GetComponent(component); - component0 = BitArrayStream.Replicate(component0, 8, 16); - int component1 = endPoints[partition][1].GetComponent(component); - component1 = BitArrayStream.Replicate(component1, 8, 16); - - int plane = 0; - - if (texelParams.DualPlane && (((planeIndices + 1) & 3) == component)) - { - plane = 1; - } - - int weight = weights[plane][j * blockWidth + i]; - int finalComponent = (component0 * (64 - weight) + component1 * weight + 32) / 64; - - if (finalComponent == 65535) - { - pixel.SetComponent(component, 255); - } - else - { - double finalComponentFloat = finalComponent; - pixel.SetComponent(component, (int)(255.0 * (finalComponentFloat / 65536.0) + 0.5)); - } - } - - outputBuffer[j * blockWidth + i] = pixel.Pack(); - } - } - - return true; - } - - private static int Select2dPartition(int seed, int x, int y, int partitionCount, bool isSmallBlock) - { - return SelectPartition(seed, x, y, 0, partitionCount, isSmallBlock); - } - - private static int SelectPartition(int seed, int x, int y, int z, int partitionCount, bool isSmallBlock) - { - if (partitionCount == 1) - { - return 0; - } - - if (isSmallBlock) - { - x <<= 1; - y <<= 1; - z <<= 1; - } - - seed += (partitionCount - 1) * 1024; - - int rightNum = Hash52((uint)seed); - byte seed01 = (byte)(rightNum & 0xF); - byte seed02 = (byte)((rightNum >> 4) & 0xF); - byte seed03 = (byte)((rightNum >> 8) & 0xF); - byte seed04 = (byte)((rightNum >> 12) & 0xF); - byte seed05 = (byte)((rightNum >> 16) & 0xF); - byte seed06 = (byte)((rightNum >> 20) & 0xF); - byte seed07 = (byte)((rightNum >> 24) & 0xF); - byte seed08 = (byte)((rightNum >> 28) & 0xF); - byte seed09 = (byte)((rightNum >> 18) & 0xF); - byte seed10 = (byte)((rightNum >> 22) & 0xF); - byte seed11 = (byte)((rightNum >> 26) & 0xF); - byte seed12 = (byte)(((rightNum >> 30) | (rightNum << 2)) & 0xF); - - seed01 *= seed01; seed02 *= seed02; - seed03 *= seed03; seed04 *= seed04; - seed05 *= seed05; seed06 *= seed06; - seed07 *= seed07; seed08 *= seed08; - seed09 *= seed09; seed10 *= seed10; - seed11 *= seed11; seed12 *= seed12; - - int seedHash1, seedHash2, seedHash3; - - if ((seed & 1) != 0) - { - seedHash1 = (seed & 2) != 0 ? 4 : 5; - seedHash2 = (partitionCount == 3) ? 6 : 5; - } - else - { - seedHash1 = (partitionCount == 3) ? 6 : 5; - seedHash2 = (seed & 2) != 0 ? 4 : 5; - } - - seedHash3 = (seed & 0x10) != 0 ? seedHash1 : seedHash2; - - seed01 >>= seedHash1; seed02 >>= seedHash2; seed03 >>= seedHash1; seed04 >>= seedHash2; - seed05 >>= seedHash1; seed06 >>= seedHash2; seed07 >>= seedHash1; seed08 >>= seedHash2; - seed09 >>= seedHash3; seed10 >>= seedHash3; seed11 >>= seedHash3; seed12 >>= seedHash3; - - int a = seed01 * x + seed02 * y + seed11 * z + (rightNum >> 14); - int b = seed03 * x + seed04 * y + seed12 * z + (rightNum >> 10); - int c = seed05 * x + seed06 * y + seed09 * z + (rightNum >> 6); - int d = seed07 * x + seed08 * y + seed10 * z + (rightNum >> 2); - - a &= 0x3F; b &= 0x3F; c &= 0x3F; d &= 0x3F; - - if (partitionCount < 4) d = 0; - if (partitionCount < 3) c = 0; - - if (a >= b && a >= c && a >= d) return 0; - else if (b >= c && b >= d) return 1; - else if (c >= d) return 2; - return 3; - } - - static int Hash52(uint val) - { - val ^= val >> 15; val -= val << 17; val += val << 7; val += val << 4; - val ^= val >> 5; val += val << 16; val ^= val >> 7; val ^= val >> 3; - val ^= val << 6; val ^= val >> 17; - - return (int)val; - } - - static void UnquantizeTexelWeights( - int[][] outputBuffer, - List<IntegerEncoded> weights, - TexelWeightParams texelParams, - int blockWidth, - int blockHeight) - { - int weightIndices = 0; - int[][] unquantized = new int[2][]; - unquantized[0] = new int[144]; - unquantized[1] = new int[144]; - - for (int i = 0; i < weights.Count; i++) - { - unquantized[0][weightIndices] = UnquantizeTexelWeight(weights[i]); - - if (texelParams.DualPlane) - { - i++; - unquantized[1][weightIndices] = UnquantizeTexelWeight(weights[i]); - - if (i == weights.Count) - { - break; - } - } - - if (++weightIndices >= (texelParams.Width * texelParams.Height)) break; - } - - // Do infill if necessary (Section C.2.18) ... - int ds = (1024 + (blockWidth / 2)) / (blockWidth - 1); - int dt = (1024 + (blockHeight / 2)) / (blockHeight - 1); - - int planeScale = texelParams.DualPlane ? 2 : 1; - - for (int plane = 0; plane < planeScale; plane++) - { - for (int t = 0; t < blockHeight; t++) - { - for (int s = 0; s < blockWidth; s++) - { - int cs = ds * s; - int ct = dt * t; - - int gs = (cs * (texelParams.Width - 1) + 32) >> 6; - int gt = (ct * (texelParams.Height - 1) + 32) >> 6; - - int js = gs >> 4; - int fs = gs & 0xF; - - int jt = gt >> 4; - int ft = gt & 0x0F; - - int w11 = (fs * ft + 8) >> 4; - int w10 = ft - w11; - int w01 = fs - w11; - int w00 = 16 - fs - ft + w11; - - int v0 = js + jt * texelParams.Width; - - int p00 = 0; - int p01 = 0; - int p10 = 0; - int p11 = 0; - - if (v0 < (texelParams.Width * texelParams.Height)) - { - p00 = unquantized[plane][v0]; - } - - if (v0 + 1 < (texelParams.Width * texelParams.Height)) - { - p01 = unquantized[plane][v0 + 1]; - } - - if (v0 + texelParams.Width < (texelParams.Width * texelParams.Height)) - { - p10 = unquantized[plane][v0 + texelParams.Width]; - } - - if (v0 + texelParams.Width + 1 < (texelParams.Width * texelParams.Height)) - { - p11 = unquantized[plane][v0 + texelParams.Width + 1]; - } - - outputBuffer[plane][t * blockWidth + s] = (p00 * w00 + p01 * w01 + p10 * w10 + p11 * w11 + 8) >> 4; - } - } - } - } - - static int UnquantizeTexelWeight(IntegerEncoded intEncoded) - { - int bitValue = intEncoded.BitValue; - int bitLength = intEncoded.NumberBits; - - int a = BitArrayStream.Replicate(bitValue & 1, 1, 7); - int b = 0, c = 0, d = 0; - - int result = 0; - - switch (intEncoded.GetEncoding()) - { - case IntegerEncoded.EIntegerEncoding.JustBits: - result = BitArrayStream.Replicate(bitValue, bitLength, 6); - break; - - case IntegerEncoded.EIntegerEncoding.Trit: - { - d = intEncoded.TritValue; - Debug.Assert(d < 3); - - switch (bitLength) - { - case 0: - { - int[] results = { 0, 32, 63 }; - result = results[d]; - - break; - } - - case 1: - { - c = 50; - break; - } - - case 2: - { - c = 23; - int b2 = (bitValue >> 1) & 1; - b = (b2 << 6) | (b2 << 2) | b2; - - break; - } - - case 3: - { - c = 11; - int cb = (bitValue >> 1) & 3; - b = (cb << 5) | cb; - - break; - } - - default: - throw new AstcDecoderException("Invalid trit encoding for texel weight"); - } - - break; - } - - case IntegerEncoded.EIntegerEncoding.Quint: - { - d = intEncoded.QuintValue; - Debug.Assert(d < 5); - - switch (bitLength) - { - case 0: - { - int[] results = { 0, 16, 32, 47, 63 }; - result = results[d]; - - break; - } - - case 1: - { - c = 28; - - break; - } - - case 2: - { - c = 13; - int b2 = (bitValue >> 1) & 1; - b = (b2 << 6) | (b2 << 1); - - break; - } - - default: - throw new AstcDecoderException("Invalid quint encoding for texel weight"); - } - - break; - } - } - - if (intEncoded.GetEncoding() != IntegerEncoded.EIntegerEncoding.JustBits && bitLength > 0) - { - // Decode the value... - result = d * c + b; - result ^= a; - result = (a & 0x20) | (result >> 2); - } - - Debug.Assert(result < 64); - - // Change from [0,63] to [0,64] - if (result > 32) - { - result += 1; - } - - return result; - } - - static byte ReverseByte(byte b) - { - // Taken from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits - return (byte)((((b) * 0x80200802L) & 0x0884422110L) * 0x0101010101L >> 32); - } - - static uint[] ReadUintColorValues(int number, int[] colorValues, ref int colorValuesPosition) - { - uint[] ret = new uint[number]; - - for (int i = 0; i < number; i++) - { - ret[i] = (uint)colorValues[colorValuesPosition++]; - } - - return ret; - } - - static int[] ReadIntColorValues(int number, int[] colorValues, ref int colorValuesPosition) - { - int[] ret = new int[number]; - - for (int i = 0; i < number; i++) - { - ret[i] = colorValues[colorValuesPosition++]; - } - - return ret; - } - - static void ComputeEndpoints( - AstcPixel[] endPoints, - int[] colorValues, - uint colorEndpointMode, - ref int colorValuesPosition) - { - switch (colorEndpointMode) - { - case 0: - { - uint[] val = ReadUintColorValues(2, colorValues, ref colorValuesPosition); - - endPoints[0] = new AstcPixel(0xFF, (short)val[0], (short)val[0], (short)val[0]); - endPoints[1] = new AstcPixel(0xFF, (short)val[1], (short)val[1], (short)val[1]); - - break; - } - - - case 1: - { - uint[] val = ReadUintColorValues(2, colorValues, ref colorValuesPosition); - int l0 = (int)((val[0] >> 2) | (val[1] & 0xC0)); - int l1 = (int)Math.Max(l0 + (val[1] & 0x3F), 0xFFU); - - endPoints[0] = new AstcPixel(0xFF, (short)l0, (short)l0, (short)l0); - endPoints[1] = new AstcPixel(0xFF, (short)l1, (short)l1, (short)l1); - - break; - } - - case 4: - { - uint[] val = ReadUintColorValues(4, colorValues, ref colorValuesPosition); - - endPoints[0] = new AstcPixel((short)val[2], (short)val[0], (short)val[0], (short)val[0]); - endPoints[1] = new AstcPixel((short)val[3], (short)val[1], (short)val[1], (short)val[1]); - - break; - } - - case 5: - { - int[] val = ReadIntColorValues(4, colorValues, ref colorValuesPosition); - - BitArrayStream.BitTransferSigned(ref val[1], ref val[0]); - BitArrayStream.BitTransferSigned(ref val[3], ref val[2]); - - endPoints[0] = new AstcPixel((short)val[2], (short)val[0], (short)val[0], (short)val[0]); - endPoints[1] = new AstcPixel((short)(val[2] + val[3]), (short)(val[0] + val[1]), (short)(val[0] + val[1]), (short)(val[0] + val[1])); - - endPoints[0].ClampByte(); - endPoints[1].ClampByte(); - - break; - } - - case 6: - { - uint[] val = ReadUintColorValues(4, colorValues, ref colorValuesPosition); - - endPoints[0] = new AstcPixel(0xFF, (short)(val[0] * val[3] >> 8), (short)(val[1] * val[3] >> 8), (short)(val[2] * val[3] >> 8)); - endPoints[1] = new AstcPixel(0xFF, (short)val[0], (short)val[1], (short)val[2]); - - break; - } - - case 8: - { - uint[] val = ReadUintColorValues(6, colorValues, ref colorValuesPosition); - - if (val[1] + val[3] + val[5] >= val[0] + val[2] + val[4]) - { - endPoints[0] = new AstcPixel(0xFF, (short)val[0], (short)val[2], (short)val[4]); - endPoints[1] = new AstcPixel(0xFF, (short)val[1], (short)val[3], (short)val[5]); - } - else - { - endPoints[0] = AstcPixel.BlueContract(0xFF, (short)val[1], (short)val[3], (short)val[5]); - endPoints[1] = AstcPixel.BlueContract(0xFF, (short)val[0], (short)val[2], (short)val[4]); - } - - break; - } - - case 9: - { - int[] val = ReadIntColorValues(6, colorValues, ref colorValuesPosition); - - BitArrayStream.BitTransferSigned(ref val[1], ref val[0]); - BitArrayStream.BitTransferSigned(ref val[3], ref val[2]); - BitArrayStream.BitTransferSigned(ref val[5], ref val[4]); - - if (val[1] + val[3] + val[5] >= 0) - { - endPoints[0] = new AstcPixel(0xFF, (short)val[0], (short)val[2], (short)val[4]); - endPoints[1] = new AstcPixel(0xFF, (short)(val[0] + val[1]), (short)(val[2] + val[3]), (short)(val[4] + val[5])); - } - else - { - endPoints[0] = AstcPixel.BlueContract(0xFF, val[0] + val[1], val[2] + val[3], val[4] + val[5]); - endPoints[1] = AstcPixel.BlueContract(0xFF, val[0], val[2], val[4]); - } - - endPoints[0].ClampByte(); - endPoints[1].ClampByte(); - - break; - } - - case 10: - { - uint[] val = ReadUintColorValues(6, colorValues, ref colorValuesPosition); - - endPoints[0] = new AstcPixel((short)val[4], (short)(val[0] * val[3] >> 8), (short)(val[1] * val[3] >> 8), (short)(val[2] * val[3] >> 8)); - endPoints[1] = new AstcPixel((short)val[5], (short)val[0], (short)val[1], (short)val[2]); - - break; - } - - case 12: - { - uint[] val = ReadUintColorValues(8, colorValues, ref colorValuesPosition); - - if (val[1] + val[3] + val[5] >= val[0] + val[2] + val[4]) - { - endPoints[0] = new AstcPixel((short)val[6], (short)val[0], (short)val[2], (short)val[4]); - endPoints[1] = new AstcPixel((short)val[7], (short)val[1], (short)val[3], (short)val[5]); - } - else - { - endPoints[0] = AstcPixel.BlueContract((short)val[7], (short)val[1], (short)val[3], (short)val[5]); - endPoints[1] = AstcPixel.BlueContract((short)val[6], (short)val[0], (short)val[2], (short)val[4]); - } - - break; - } - - case 13: - { - int[] val = ReadIntColorValues(8, colorValues, ref colorValuesPosition); - - BitArrayStream.BitTransferSigned(ref val[1], ref val[0]); - BitArrayStream.BitTransferSigned(ref val[3], ref val[2]); - BitArrayStream.BitTransferSigned(ref val[5], ref val[4]); - BitArrayStream.BitTransferSigned(ref val[7], ref val[6]); - - if (val[1] + val[3] + val[5] >= 0) - { - endPoints[0] = new AstcPixel((short)val[6], (short)val[0], (short)val[2], (short)val[4]); - endPoints[1] = new AstcPixel((short)(val[7] + val[6]), (short)(val[0] + val[1]), (short)(val[2] + val[3]), (short)(val[4] + val[5])); - } - else - { - endPoints[0] = AstcPixel.BlueContract(val[6] + val[7], val[0] + val[1], val[2] + val[3], val[4] + val[5]); - endPoints[1] = AstcPixel.BlueContract(val[6], val[0], val[2], val[4]); - } - - endPoints[0].ClampByte(); - endPoints[1].ClampByte(); - - break; - } - - default: - throw new AstcDecoderException("Unsupported color endpoint mode (is it HDR?)"); - } - } - - static void DecodeColorValues( - int[] outputValues, - byte[] inputData, - uint[] modes, - int numberPartitions, - int numberBitsForColorData) - { - // First figure out how many color values we have - int numberValues = 0; - - for (int i = 0; i < numberPartitions; i++) - { - numberValues += (int)((modes[i] >> 2) + 1) << 1; - } - - // Then based on the number of values and the remaining number of bits, - // figure out the max value for each of them... - int range = 256; - - while (--range > 0) - { - IntegerEncoded intEncoded = IntegerEncoded.CreateEncoding(range); - int bitLength = intEncoded.GetBitLength(numberValues); - - if (bitLength <= numberBitsForColorData) - { - // Find the smallest possible range that matches the given encoding - while (--range > 0) - { - IntegerEncoded newIntEncoded = IntegerEncoded.CreateEncoding(range); - if (!newIntEncoded.MatchesEncoding(intEncoded)) - { - break; - } - } - - // Return to last matching range. - range++; - break; - } - } - - // We now have enough to decode our integer sequence. - List<IntegerEncoded> integerEncodedSequence = new List<IntegerEncoded>(); - BitArrayStream colorBitStream = new BitArrayStream(new BitArray(inputData)); - - IntegerEncoded.DecodeIntegerSequence(integerEncodedSequence, colorBitStream, range, numberValues); - - // Once we have the decoded values, we need to dequantize them to the 0-255 range - // This procedure is outlined in ASTC spec C.2.13 - int outputIndices = 0; - - foreach (IntegerEncoded intEncoded in integerEncodedSequence) - { - int bitLength = intEncoded.NumberBits; - int bitValue = intEncoded.BitValue; - - Debug.Assert(bitLength >= 1); - - int a = 0, b = 0, c = 0, d = 0; - // A is just the lsb replicated 9 times. - a = BitArrayStream.Replicate(bitValue & 1, 1, 9); - - switch (intEncoded.GetEncoding()) - { - case IntegerEncoded.EIntegerEncoding.JustBits: - { - outputValues[outputIndices++] = BitArrayStream.Replicate(bitValue, bitLength, 8); - - break; - } - - case IntegerEncoded.EIntegerEncoding.Trit: - { - d = intEncoded.TritValue; - - switch (bitLength) - { - case 1: - { - c = 204; - - break; - } - - case 2: - { - c = 93; - // B = b000b0bb0 - int b2 = (bitValue >> 1) & 1; - b = (b2 << 8) | (b2 << 4) | (b2 << 2) | (b2 << 1); - - break; - } - - case 3: - { - c = 44; - // B = cb000cbcb - int cb = (bitValue >> 1) & 3; - b = (cb << 7) | (cb << 2) | cb; - - break; - } - - - case 4: - { - c = 22; - // B = dcb000dcb - int dcb = (bitValue >> 1) & 7; - b = (dcb << 6) | dcb; - - break; - } - - case 5: - { - c = 11; - // B = edcb000ed - int edcb = (bitValue >> 1) & 0xF; - b = (edcb << 5) | (edcb >> 2); - - break; - } - - case 6: - { - c = 5; - // B = fedcb000f - int fedcb = (bitValue >> 1) & 0x1F; - b = (fedcb << 4) | (fedcb >> 4); - - break; - } - - default: - throw new AstcDecoderException("Unsupported trit encoding for color values!"); - } - - break; - } - - case IntegerEncoded.EIntegerEncoding.Quint: - { - d = intEncoded.QuintValue; - - switch (bitLength) - { - case 1: - { - c = 113; - - break; - } - - case 2: - { - c = 54; - // B = b0000bb00 - int b2 = (bitValue >> 1) & 1; - b = (b2 << 8) | (b2 << 3) | (b2 << 2); - - break; - } - - case 3: - { - c = 26; - // B = cb0000cbc - int cb = (bitValue >> 1) & 3; - b = (cb << 7) | (cb << 1) | (cb >> 1); - - break; - } - - case 4: - { - c = 13; - // B = dcb0000dc - int dcb = (bitValue >> 1) & 7; - b = (dcb << 6) | (dcb >> 1); - - break; - } - - case 5: - { - c = 6; - // B = edcb0000e - int edcb = (bitValue >> 1) & 0xF; - b = (edcb << 5) | (edcb >> 3); - - break; - } - - default: - throw new AstcDecoderException("Unsupported quint encoding for color values!"); - } - break; - } - } - - if (intEncoded.GetEncoding() != IntegerEncoded.EIntegerEncoding.JustBits) - { - int T = d * c + b; - T ^= a; - T = (a & 0x80) | (T >> 2); - - outputValues[outputIndices++] = T; - } - } - - // Make sure that each of our values is in the proper range... - for (int i = 0; i < numberValues; i++) - { - Debug.Assert(outputValues[i] <= 255); - } - } - - static void FillVoidExtentLdr(BitArrayStream bitStream, int[] outputBuffer, int blockWidth, int blockHeight) - { - // Don't actually care about the void extent, just read the bits... - for (int i = 0; i < 4; ++i) - { - bitStream.ReadBits(13); - } - - // Decode the RGBA components and renormalize them to the range [0, 255] - ushort r = (ushort)bitStream.ReadBits(16); - ushort g = (ushort)bitStream.ReadBits(16); - ushort b = (ushort)bitStream.ReadBits(16); - ushort a = (ushort)bitStream.ReadBits(16); - - int rgba = (r >> 8) | (g & 0xFF00) | ((b) & 0xFF00) << 8 | ((a) & 0xFF00) << 16; - - for (int j = 0; j < blockHeight; j++) - { - for (int i = 0; i < blockWidth; i++) - { - outputBuffer[j * blockWidth + i] = rgba; - } - } - } - - static TexelWeightParams DecodeBlockInfo(BitArrayStream bitStream) - { - TexelWeightParams texelParams = new TexelWeightParams(); - - // Read the entire block mode all at once - ushort modeBits = (ushort)bitStream.ReadBits(11); - - // Does this match the void extent block mode? - if ((modeBits & 0x01FF) == 0x1FC) - { - if ((modeBits & 0x200) != 0) - { - texelParams.VoidExtentHdr = true; - } - else - { - texelParams.VoidExtentLdr = true; - } - - // Next two bits must be one. - if ((modeBits & 0x400) == 0 || bitStream.ReadBits(1) == 0) - { - texelParams.Error = true; - } - - return texelParams; - } - - // First check if the last four bits are zero - if ((modeBits & 0xF) == 0) - { - texelParams.Error = true; - return texelParams; - } - - // If the last two bits are zero, then if bits - // [6-8] are all ones, this is also reserved. - if ((modeBits & 0x3) == 0 && (modeBits & 0x1C0) == 0x1C0) - { - texelParams.Error = true; - - return texelParams; - } - - // Otherwise, there is no error... Figure out the layout - // of the block mode. Layout is determined by a number - // between 0 and 9 corresponding to table C.2.8 of the - // ASTC spec. - int layout = 0; - - if ((modeBits & 0x1) != 0 || (modeBits & 0x2) != 0) - { - // layout is in [0-4] - if ((modeBits & 0x8) != 0) - { - // layout is in [2-4] - if ((modeBits & 0x4) != 0) - { - // layout is in [3-4] - if ((modeBits & 0x100) != 0) - { - layout = 4; - } - else - { - layout = 3; - } - } - else - { - layout = 2; - } - } - else - { - // layout is in [0-1] - if ((modeBits & 0x4) != 0) - { - layout = 1; - } - else - { - layout = 0; - } - } - } - else - { - // layout is in [5-9] - if ((modeBits & 0x100) != 0) - { - // layout is in [7-9] - if ((modeBits & 0x80) != 0) - { - // layout is in [7-8] - Debug.Assert((modeBits & 0x40) == 0); - - if ((modeBits & 0x20) != 0) - { - layout = 8; - } - else - { - layout = 7; - } - } - else - { - layout = 9; - } - } - else - { - // layout is in [5-6] - if ((modeBits & 0x80) != 0) - { - layout = 6; - } - else - { - layout = 5; - } - } - } - - Debug.Assert(layout < 10); - - // Determine R - int r = (modeBits >> 4) & 1; - if (layout < 5) - { - r |= (modeBits & 0x3) << 1; - } - else - { - r |= (modeBits & 0xC) >> 1; - } - - Debug.Assert(2 <= r && r <= 7); - - // Determine width & height - switch (layout) - { - case 0: - { - int a = (modeBits >> 5) & 0x3; - int b = (modeBits >> 7) & 0x3; - - texelParams.Width = b + 4; - texelParams.Height = a + 2; - - break; - } - - case 1: - { - int a = (modeBits >> 5) & 0x3; - int b = (modeBits >> 7) & 0x3; - - texelParams.Width = b + 8; - texelParams.Height = a + 2; - - break; - } - - case 2: - { - int a = (modeBits >> 5) & 0x3; - int b = (modeBits >> 7) & 0x3; - - texelParams.Width = a + 2; - texelParams.Height = b + 8; - - break; - } - - case 3: - { - int a = (modeBits >> 5) & 0x3; - int b = (modeBits >> 7) & 0x1; - - texelParams.Width = a + 2; - texelParams.Height = b + 6; - - break; - } - - case 4: - { - int a = (modeBits >> 5) & 0x3; - int b = (modeBits >> 7) & 0x1; - - texelParams.Width = b + 2; - texelParams.Height = a + 2; - - break; - } - - case 5: - { - int a = (modeBits >> 5) & 0x3; - - texelParams.Width = 12; - texelParams.Height = a + 2; - - break; - } - - case 6: - { - int a = (modeBits >> 5) & 0x3; - - texelParams.Width = a + 2; - texelParams.Height = 12; - - break; - } - - case 7: - { - texelParams.Width = 6; - texelParams.Height = 10; - - break; - } - - case 8: - { - texelParams.Width = 10; - texelParams.Height = 6; - break; - } - - case 9: - { - int a = (modeBits >> 5) & 0x3; - int b = (modeBits >> 9) & 0x3; - - texelParams.Width = a + 6; - texelParams.Height = b + 6; - - break; - } - - default: - // Don't know this layout... - texelParams.Error = true; - break; - } - - // Determine whether or not we're using dual planes - // and/or high precision layouts. - bool d = ((layout != 9) && ((modeBits & 0x400) != 0)); - bool h = (layout != 9) && ((modeBits & 0x200) != 0); - - if (h) - { - int[] maxWeights = { 9, 11, 15, 19, 23, 31 }; - texelParams.MaxWeight = maxWeights[r - 2]; - } - else - { - int[] maxWeights = { 1, 2, 3, 4, 5, 7 }; - texelParams.MaxWeight = maxWeights[r - 2]; - } - - texelParams.DualPlane = d; - - return texelParams; - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/Texture/AstcPixel.cs b/Ryujinx.Graphics/Graphics3d/Texture/AstcPixel.cs deleted file mode 100644 index 2f73c62b..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/AstcPixel.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System; -using System.Diagnostics; - -namespace Ryujinx.Graphics.Texture -{ - class AstcPixel - { - public short R { get; set; } - public short G { get; set; } - public short B { get; set; } - public short A { get; set; } - - byte[] _bitDepth = new byte[4]; - - public AstcPixel(short a, short r, short g, short b) - { - A = a; - R = r; - G = g; - B = b; - - for (int i = 0; i < 4; i++) - _bitDepth[i] = 8; - } - - public void ClampByte() - { - R = Math.Min(Math.Max(R, (short)0), (short)255); - G = Math.Min(Math.Max(G, (short)0), (short)255); - B = Math.Min(Math.Max(B, (short)0), (short)255); - A = Math.Min(Math.Max(A, (short)0), (short)255); - } - - public short GetComponent(int index) - { - switch(index) - { - case 0: return A; - case 1: return R; - case 2: return G; - case 3: return B; - } - - return 0; - } - - public void SetComponent(int index, int value) - { - switch (index) - { - case 0: - A = (short)value; - break; - case 1: - R = (short)value; - break; - case 2: - G = (short)value; - break; - case 3: - B = (short)value; - break; - } - } - - public void ChangeBitDepth(byte[] depth) - { - for (int i = 0; i< 4; i++) - { - int value = ChangeBitDepth(GetComponent(i), _bitDepth[i], depth[i]); - - SetComponent(i, value); - _bitDepth[i] = depth[i]; - } - } - - short ChangeBitDepth(short value, byte oldDepth, byte newDepth) - { - Debug.Assert(newDepth <= 8); - Debug.Assert(oldDepth <= 8); - - if (oldDepth == newDepth) - { - // Do nothing - return value; - } - else if (oldDepth == 0 && newDepth != 0) - { - return (short)((1 << newDepth) - 1); - } - else if (newDepth > oldDepth) - { - return (short)BitArrayStream.Replicate(value, oldDepth, newDepth); - } - else - { - // oldDepth > newDepth - if (newDepth == 0) - { - return 0xFF; - } - else - { - byte bitsWasted = (byte)(oldDepth - newDepth); - short tempValue = value; - - tempValue = (short)((tempValue + (1 << (bitsWasted - 1))) >> bitsWasted); - tempValue = Math.Min(Math.Max((short)0, tempValue), (short)((1 << newDepth) - 1)); - - return (byte)(tempValue); - } - } - } - - public int Pack() - { - AstcPixel newPixel = new AstcPixel(A, R, G, B); - byte[] eightBitDepth = { 8, 8, 8, 8 }; - - newPixel.ChangeBitDepth(eightBitDepth); - - return (byte)newPixel.A << 24 | - (byte)newPixel.B << 16 | - (byte)newPixel.G << 8 | - (byte)newPixel.R << 0; - } - - // Adds more precision to the blue channel as described - // in C.2.14 - public static AstcPixel BlueContract(int a, int r, int g, int b) - { - return new AstcPixel((short)(a), - (short)((r + b) >> 1), - (short)((g + b) >> 1), - (short)(b)); - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/Texture/BitArrayStream.cs b/Ryujinx.Graphics/Graphics3d/Texture/BitArrayStream.cs deleted file mode 100644 index 24069d72..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/BitArrayStream.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections; - -namespace Ryujinx.Graphics.Texture -{ - public class BitArrayStream - { - public BitArray BitsArray; - - public int Position { get; private set; } - - public BitArrayStream(BitArray bitArray) - { - BitsArray = bitArray; - Position = 0; - } - - public short ReadBits(int length) - { - int retValue = 0; - for (int i = Position; i < Position + length; i++) - { - if (BitsArray[i]) - { - retValue |= 1 << (i - Position); - } - } - - Position += length; - return (short)retValue; - } - - public int ReadBits(int start, int end) - { - int retValue = 0; - for (int i = start; i <= end; i++) - { - if (BitsArray[i]) - { - retValue |= 1 << (i - start); - } - } - - return retValue; - } - - public int ReadBit(int index) - { - return Convert.ToInt32(BitsArray[index]); - } - - public void WriteBits(int value, int length) - { - for (int i = Position; i < Position + length; i++) - { - BitsArray[i] = ((value >> (i - Position)) & 1) != 0; - } - - Position += length; - } - - public byte[] ToByteArray() - { - byte[] retArray = new byte[(BitsArray.Length + 7) / 8]; - BitsArray.CopyTo(retArray, 0); - return retArray; - } - - public static int Replicate(int value, int numberBits, int toBit) - { - if (numberBits == 0) return 0; - if (toBit == 0) return 0; - - int tempValue = value & ((1 << numberBits) - 1); - int retValue = tempValue; - int resLength = numberBits; - - while (resLength < toBit) - { - int comp = 0; - if (numberBits > toBit - resLength) - { - int newShift = toBit - resLength; - comp = numberBits - newShift; - numberBits = newShift; - } - retValue <<= numberBits; - retValue |= tempValue >> comp; - resLength += numberBits; - } - return retValue; - } - - public static int PopCnt(int number) - { - int counter; - for (counter = 0; number != 0; counter++) - { - number &= number - 1; - } - return counter; - } - - public static void Swap<T>(ref T lhs, ref T rhs) - { - T temp = lhs; - lhs = rhs; - rhs = temp; - } - - // Transfers a bit as described in C.2.14 - public static void BitTransferSigned(ref int a, ref int b) - { - b >>= 1; - b |= a & 0x80; - a >>= 1; - a &= 0x3F; - if ((a & 0x20) != 0) a -= 0x40; - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/Texture/BlockLinearSwizzle.cs b/Ryujinx.Graphics/Graphics3d/Texture/BlockLinearSwizzle.cs deleted file mode 100644 index 682f7d67..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/BlockLinearSwizzle.cs +++ /dev/null @@ -1,186 +0,0 @@ -using Ryujinx.Common; -using System; - -namespace Ryujinx.Graphics.Texture -{ - class BlockLinearSwizzle : ISwizzle - { - private const int GobWidth = 64; - private const int GobHeight = 8; - - private const int GobSize = GobWidth * GobHeight; - - private int _texWidth; - private int _texHeight; - private int _texDepth; - private int _texGobBlockHeight; - private int _texGobBlockDepth; - private int _texBpp; - - private int _bhMask; - private int _bdMask; - - private int _bhShift; - private int _bdShift; - private int _bppShift; - - private int _xShift; - - private int _robSize; - private int _sliceSize; - - private int _baseOffset; - - public BlockLinearSwizzle( - int width, - int height, - int depth, - int gobBlockHeight, - int gobBlockDepth, - int bpp) - { - _texWidth = width; - _texHeight = height; - _texDepth = depth; - _texGobBlockHeight = gobBlockHeight; - _texGobBlockDepth = gobBlockDepth; - _texBpp = bpp; - - _bppShift = BitUtils.CountTrailingZeros32(bpp); - - SetMipLevel(0); - } - - public void SetMipLevel(int level) - { - _baseOffset = GetMipOffset(level); - - int width = Math.Max(1, _texWidth >> level); - int height = Math.Max(1, _texHeight >> level); - int depth = Math.Max(1, _texDepth >> level); - - GobBlockSizes gbSizes = AdjustGobBlockSizes(height, depth); - - _bhMask = gbSizes.Height - 1; - _bdMask = gbSizes.Depth - 1; - - _bhShift = BitUtils.CountTrailingZeros32(gbSizes.Height); - _bdShift = BitUtils.CountTrailingZeros32(gbSizes.Depth); - - _xShift = BitUtils.CountTrailingZeros32(GobSize * gbSizes.Height * gbSizes.Depth); - - RobAndSliceSizes gsSizes = GetRobAndSliceSizes(width, height, gbSizes); - - _robSize = gsSizes.RobSize; - _sliceSize = gsSizes.SliceSize; - } - - public int GetImageSize(int mipsCount) - { - int size = GetMipOffset(mipsCount); - - size = (size + 0x1fff) & ~0x1fff; - - return size; - } - - public int GetMipOffset(int level) - { - int totalSize = 0; - - for (int index = 0; index < level; index++) - { - int width = Math.Max(1, _texWidth >> index); - int height = Math.Max(1, _texHeight >> index); - int depth = Math.Max(1, _texDepth >> index); - - GobBlockSizes gbSizes = AdjustGobBlockSizes(height, depth); - - RobAndSliceSizes rsSizes = GetRobAndSliceSizes(width, height, gbSizes); - - totalSize += BitUtils.DivRoundUp(depth, gbSizes.Depth) * rsSizes.SliceSize; - } - - return totalSize; - } - - private struct GobBlockSizes - { - public int Height; - public int Depth; - - public GobBlockSizes(int gobBlockHeight, int gobBlockDepth) - { - Height = gobBlockHeight; - Depth = gobBlockDepth; - } - } - - private GobBlockSizes AdjustGobBlockSizes(int height, int depth) - { - int gobBlockHeight = _texGobBlockHeight; - int gobBlockDepth = _texGobBlockDepth; - - int pow2Height = BitUtils.Pow2RoundUp(height); - int pow2Depth = BitUtils.Pow2RoundUp(depth); - - while (gobBlockHeight * GobHeight > pow2Height && gobBlockHeight > 1) - { - gobBlockHeight >>= 1; - } - - while (gobBlockDepth > pow2Depth && gobBlockDepth > 1) - { - gobBlockDepth >>= 1; - } - - return new GobBlockSizes(gobBlockHeight, gobBlockDepth); - } - - private struct RobAndSliceSizes - { - public int RobSize; - public int SliceSize; - - public RobAndSliceSizes(int robSize, int sliceSize) - { - RobSize = robSize; - SliceSize = sliceSize; - } - } - - private RobAndSliceSizes GetRobAndSliceSizes(int width, int height, GobBlockSizes gbSizes) - { - int widthInGobs = BitUtils.DivRoundUp(width * _texBpp, GobWidth); - - int robSize = GobSize * gbSizes.Height * gbSizes.Depth * widthInGobs; - - int sliceSize = BitUtils.DivRoundUp(height, gbSizes.Height * GobHeight) * robSize; - - return new RobAndSliceSizes(robSize, sliceSize); - } - - public int GetSwizzleOffset(int x, int y, int z) - { - x <<= _bppShift; - - int yh = y / GobHeight; - - int position = (z >> _bdShift) * _sliceSize + (yh >> _bhShift) * _robSize; - - position += (x / GobWidth) << _xShift; - - position += (yh & _bhMask) * GobSize; - - position += ((z & _bdMask) * GobSize) << _bhShift; - - position += ((x & 0x3f) >> 5) << 8; - position += ((y & 0x07) >> 1) << 6; - position += ((x & 0x1f) >> 4) << 5; - position += ((y & 0x01) >> 0) << 4; - position += ((x & 0x0f) >> 0) << 0; - - return _baseOffset + position; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/Texture/ISwizzle.cs b/Ryujinx.Graphics/Graphics3d/Texture/ISwizzle.cs deleted file mode 100644 index fae3eada..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/ISwizzle.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Texture -{ - interface ISwizzle - { - int GetSwizzleOffset(int x, int y, int z); - - void SetMipLevel(int level); - - int GetMipOffset(int level); - - int GetImageSize(int mipsCount); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/Texture/ImageUtils.cs b/Ryujinx.Graphics/Graphics3d/Texture/ImageUtils.cs deleted file mode 100644 index 10c36fe1..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/ImageUtils.cs +++ /dev/null @@ -1,561 +0,0 @@ -using ARMeilleure.Memory; -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Memory; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Texture -{ - public static class ImageUtils - { - [Flags] - private enum TargetBuffer - { - Color = 1 << 0, - Depth = 1 << 1, - Stencil = 1 << 2, - - DepthStencil = Depth | Stencil - } - - private struct ImageDescriptor - { - public int BytesPerPixel { get; private set; } - public int BlockWidth { get; private set; } - public int BlockHeight { get; private set; } - public int BlockDepth { get; private set; } - - public TargetBuffer Target { get; private set; } - - public ImageDescriptor(int bytesPerPixel, int blockWidth, int blockHeight, int blockDepth, TargetBuffer target) - { - BytesPerPixel = bytesPerPixel; - BlockWidth = blockWidth; - BlockHeight = blockHeight; - BlockDepth = blockDepth; - Target = target; - } - } - - private const GalImageFormat Snorm = GalImageFormat.Snorm; - private const GalImageFormat Unorm = GalImageFormat.Unorm; - private const GalImageFormat Sint = GalImageFormat.Sint; - private const GalImageFormat Uint = GalImageFormat.Uint; - private const GalImageFormat Float = GalImageFormat.Float; - private const GalImageFormat Srgb = GalImageFormat.Srgb; - - private static readonly Dictionary<GalTextureFormat, GalImageFormat> TextureTable = - new Dictionary<GalTextureFormat, GalImageFormat>() - { - { GalTextureFormat.Rgba32, GalImageFormat.Rgba32 | Sint | Uint | Float }, - { GalTextureFormat.Rgba16, GalImageFormat.Rgba16 | Snorm | Unorm | Sint | Uint | Float }, - { GalTextureFormat.Rg32, GalImageFormat.Rg32 | Sint | Uint | Float }, - { GalTextureFormat.Rgba8, GalImageFormat.Rgba8 | Snorm | Unorm | Sint | Uint | Srgb }, - { GalTextureFormat.Rgb10A2, GalImageFormat.Rgb10A2 | Snorm | Unorm | Sint | Uint }, - { GalTextureFormat.Rg8, GalImageFormat.Rg8 | Snorm | Unorm | Sint | Uint }, - { GalTextureFormat.R16, GalImageFormat.R16 | Snorm | Unorm | Sint | Uint | Float }, - { GalTextureFormat.R8, GalImageFormat.R8 | Snorm | Unorm | Sint | Uint }, - { GalTextureFormat.Rg16, GalImageFormat.Rg16 | Snorm | Unorm | Sint | Float }, - { GalTextureFormat.R32, GalImageFormat.R32 | Sint | Uint | Float }, - { GalTextureFormat.Rgba4, GalImageFormat.Rgba4 | Unorm }, - { GalTextureFormat.Rgb5A1, GalImageFormat.Rgb5A1 | Unorm }, - { GalTextureFormat.Rgb565, GalImageFormat.Rgb565 | Unorm }, - { GalTextureFormat.R11G11B10F, GalImageFormat.R11G11B10 | Float }, - { GalTextureFormat.D24S8, GalImageFormat.D24S8 | Unorm | Uint }, - { GalTextureFormat.D32F, GalImageFormat.D32 | Float }, - { GalTextureFormat.D32Fx24S8, GalImageFormat.D32S8 | Float }, - { GalTextureFormat.D16, GalImageFormat.D16 | Unorm }, - - // Compressed formats - { GalTextureFormat.BptcSfloat, GalImageFormat.BptcSfloat | Float }, - { GalTextureFormat.BptcUfloat, GalImageFormat.BptcUfloat | Float }, - { GalTextureFormat.BptcUnorm, GalImageFormat.BptcUnorm | Unorm | Srgb }, - { GalTextureFormat.BC1, GalImageFormat.BC1 | Unorm | Srgb }, - { GalTextureFormat.BC2, GalImageFormat.BC2 | Unorm | Srgb }, - { GalTextureFormat.BC3, GalImageFormat.BC3 | Unorm | Srgb }, - { GalTextureFormat.BC4, GalImageFormat.BC4 | Unorm | Snorm }, - { GalTextureFormat.BC5, GalImageFormat.BC5 | Unorm | Snorm }, - { GalTextureFormat.Astc2D4x4, GalImageFormat.Astc2D4x4 | Unorm | Srgb }, - { GalTextureFormat.Astc2D5x5, GalImageFormat.Astc2D5x5 | Unorm | Srgb }, - { GalTextureFormat.Astc2D6x6, GalImageFormat.Astc2D6x6 | Unorm | Srgb }, - { GalTextureFormat.Astc2D8x8, GalImageFormat.Astc2D8x8 | Unorm | Srgb }, - { GalTextureFormat.Astc2D10x10, GalImageFormat.Astc2D10x10 | Unorm | Srgb }, - { GalTextureFormat.Astc2D12x12, GalImageFormat.Astc2D12x12 | Unorm | Srgb }, - { GalTextureFormat.Astc2D5x4, GalImageFormat.Astc2D5x4 | Unorm | Srgb }, - { GalTextureFormat.Astc2D6x5, GalImageFormat.Astc2D6x5 | Unorm | Srgb }, - { GalTextureFormat.Astc2D8x6, GalImageFormat.Astc2D8x6 | Unorm | Srgb }, - { GalTextureFormat.Astc2D10x8, GalImageFormat.Astc2D10x8 | Unorm | Srgb }, - { GalTextureFormat.Astc2D12x10, GalImageFormat.Astc2D12x10 | Unorm | Srgb }, - { GalTextureFormat.Astc2D8x5, GalImageFormat.Astc2D8x5 | Unorm | Srgb }, - { GalTextureFormat.Astc2D10x5, GalImageFormat.Astc2D10x5 | Unorm | Srgb }, - { GalTextureFormat.Astc2D10x6, GalImageFormat.Astc2D10x6 | Unorm | Srgb } - }; - - private static readonly Dictionary<GalImageFormat, ImageDescriptor> ImageTable = - new Dictionary<GalImageFormat, ImageDescriptor>() - { - { GalImageFormat.Rgba32, new ImageDescriptor(16, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Rgba16, new ImageDescriptor(8, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Rg32, new ImageDescriptor(8, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Rgbx8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Rgba8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Bgra8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Rgb10A2, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.R32, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Rgba4, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.BptcSfloat, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) }, - { GalImageFormat.BptcUfloat, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) }, - { GalImageFormat.Bgr5A1, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Rgb5A1, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Rgb565, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Bgr565, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.BptcUnorm, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) }, - { GalImageFormat.Rg16, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.Rg8, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.R16, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.R8, new ImageDescriptor(1, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.R11G11B10, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.BC1, new ImageDescriptor(8, 4, 4, 1, TargetBuffer.Color) }, - { GalImageFormat.BC2, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) }, - { GalImageFormat.BC3, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) }, - { GalImageFormat.BC4, new ImageDescriptor(8, 4, 4, 1, TargetBuffer.Color) }, - { GalImageFormat.BC5, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D4x4, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D5x5, new ImageDescriptor(16, 5, 5, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D6x6, new ImageDescriptor(16, 6, 6, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D8x8, new ImageDescriptor(16, 8, 8, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D10x10, new ImageDescriptor(16, 10, 10, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D12x12, new ImageDescriptor(16, 12, 12, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D5x4, new ImageDescriptor(16, 5, 4, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D6x5, new ImageDescriptor(16, 6, 5, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D8x6, new ImageDescriptor(16, 8, 6, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D10x8, new ImageDescriptor(16, 10, 8, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D12x10, new ImageDescriptor(16, 12, 10, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D8x5, new ImageDescriptor(16, 8, 5, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D10x5, new ImageDescriptor(16, 10, 5, 1, TargetBuffer.Color) }, - { GalImageFormat.Astc2D10x6, new ImageDescriptor(16, 10, 6, 1, TargetBuffer.Color) }, - - { GalImageFormat.D16, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Depth) }, - { GalImageFormat.D24, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Depth) }, - { GalImageFormat.D24S8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.DepthStencil) }, - { GalImageFormat.D32, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Depth) }, - { GalImageFormat.D32S8, new ImageDescriptor(8, 1, 1, 1, TargetBuffer.DepthStencil) } - }; - - public static GalImageFormat ConvertTexture( - GalTextureFormat format, - GalTextureType rType, - GalTextureType gType, - GalTextureType bType, - GalTextureType aType, - bool convSrgb) - { - if (!TextureTable.TryGetValue(format, out GalImageFormat imageFormat)) - { - throw new NotImplementedException($"Format 0x{((int)format):x} not implemented!"); - } - - if (!HasDepth(imageFormat) && (rType != gType || rType != bType || rType != aType)) - { - throw new NotImplementedException("Per component types are not implemented!"); - } - - GalImageFormat formatType = convSrgb ? Srgb : GetFormatType(rType); - - GalImageFormat combinedFormat = (imageFormat & GalImageFormat.FormatMask) | formatType; - - if (!imageFormat.HasFlag(formatType)) - { - throw new NotImplementedException($"Format \"{combinedFormat}\" not implemented!"); - } - - return combinedFormat; - } - - public static GalImageFormat ConvertSurface(GalSurfaceFormat format) - { - switch (format) - { - case GalSurfaceFormat.Rgba32Float: return GalImageFormat.Rgba32 | Float; - case GalSurfaceFormat.Rgba32Uint: return GalImageFormat.Rgba32 | Uint; - case GalSurfaceFormat.Rgba16Float: return GalImageFormat.Rgba16 | Float; - case GalSurfaceFormat.Rgba16Uint: return GalImageFormat.Rgba16 | Uint; - case GalSurfaceFormat.Rgba16Unorm: return GalImageFormat.Rgba16 | Unorm; - case GalSurfaceFormat.Rg32Float: return GalImageFormat.Rg32 | Float; - case GalSurfaceFormat.Rg32Sint: return GalImageFormat.Rg32 | Sint; - case GalSurfaceFormat.Rg32Uint: return GalImageFormat.Rg32 | Uint; - case GalSurfaceFormat.Bgra8Unorm: return GalImageFormat.Bgra8 | Unorm; - case GalSurfaceFormat.Bgra8Srgb: return GalImageFormat.Bgra8 | Srgb; - case GalSurfaceFormat.Rgb10A2Unorm: return GalImageFormat.Rgb10A2 | Unorm; - case GalSurfaceFormat.Rgba8Unorm: return GalImageFormat.Rgba8 | Unorm; - case GalSurfaceFormat.Rgba8Srgb: return GalImageFormat.Rgba8 | Srgb; - case GalSurfaceFormat.Rgba8Snorm: return GalImageFormat.Rgba8 | Snorm; - case GalSurfaceFormat.Rg16Snorm: return GalImageFormat.Rg16 | Snorm; - case GalSurfaceFormat.Rg16Unorm: return GalImageFormat.Rg16 | Unorm; - case GalSurfaceFormat.Rg16Sint: return GalImageFormat.Rg16 | Sint; - case GalSurfaceFormat.Rg16Float: return GalImageFormat.Rg16 | Float; - case GalSurfaceFormat.R11G11B10Float: return GalImageFormat.R11G11B10 | Float; - case GalSurfaceFormat.R32Float: return GalImageFormat.R32 | Float; - case GalSurfaceFormat.R32Uint: return GalImageFormat.R32 | Uint; - case GalSurfaceFormat.Rg8Unorm: return GalImageFormat.Rg8 | Unorm; - case GalSurfaceFormat.Rg8Snorm: return GalImageFormat.Rg8 | Snorm; - case GalSurfaceFormat.R16Float: return GalImageFormat.R16 | Float; - case GalSurfaceFormat.R16Unorm: return GalImageFormat.R16 | Unorm; - case GalSurfaceFormat.R16Uint: return GalImageFormat.R16 | Uint; - case GalSurfaceFormat.R8Unorm: return GalImageFormat.R8 | Unorm; - case GalSurfaceFormat.R8Uint: return GalImageFormat.R8 | Uint; - case GalSurfaceFormat.B5G6R5Unorm: return GalImageFormat.Rgb565 | Unorm; - case GalSurfaceFormat.Bgr5A1Unorm: return GalImageFormat.Bgr5A1 | Unorm; - case GalSurfaceFormat.Rgbx8Unorm: return GalImageFormat.Rgbx8 | Unorm; - } - - throw new NotImplementedException(format.ToString()); - } - - public static GalImageFormat ConvertZeta(GalZetaFormat format) - { - switch (format) - { - case GalZetaFormat.D32Float: return GalImageFormat.D32 | Float; - case GalZetaFormat.S8D24Unorm: return GalImageFormat.D24S8 | Unorm; - case GalZetaFormat.D16Unorm: return GalImageFormat.D16 | Unorm; - case GalZetaFormat.D24X8Unorm: return GalImageFormat.D24 | Unorm; - case GalZetaFormat.D24S8Unorm: return GalImageFormat.D24S8 | Unorm; - case GalZetaFormat.D32S8X24Float: return GalImageFormat.D32S8 | Float; - } - - throw new NotImplementedException(format.ToString()); - } - - public static byte[] ReadTexture(IMemory memory, GalImage image, long position) - { - MemoryManager cpuMemory; - - if (memory is NvGpuVmm vmm) - { - cpuMemory = vmm.Memory; - } - else - { - cpuMemory = (MemoryManager)memory; - } - - ISwizzle swizzle = TextureHelper.GetSwizzle(image); - - ImageDescriptor desc = GetImageDescriptor(image.Format); - - (int width, int height, int depth) = GetImageSizeInBlocks(image); - - int bytesPerPixel = desc.BytesPerPixel; - - // Note: Each row of the texture needs to be aligned to 4 bytes. - int pitch = (width * bytesPerPixel + 3) & ~3; - - int dataLayerSize = height * pitch * depth; - byte[] data = new byte[dataLayerSize * image.LayerCount]; - - int targetMipLevel = image.MaxMipmapLevel <= 1 ? 1 : image.MaxMipmapLevel - 1; - int layerOffset = GetLayerOffset(image, targetMipLevel); - - for (int layer = 0; layer < image.LayerCount; layer++) - { - for (int z = 0; z < depth; z++) - { - for (int y = 0; y < height; y++) - { - int outOffs = (dataLayerSize * layer) + y * pitch + (z * width * height * bytesPerPixel); - - for (int x = 0; x < width; x++) - { - long offset = (uint)swizzle.GetSwizzleOffset(x, y, z); - - cpuMemory.ReadBytes(position + (layerOffset * layer) + offset, data, outOffs, bytesPerPixel); - - outOffs += bytesPerPixel; - } - } - } - } - - return data; - } - - public static void WriteTexture(NvGpuVmm vmm, GalImage image, long position, byte[] data) - { - ISwizzle swizzle = TextureHelper.GetSwizzle(image); - - ImageDescriptor desc = GetImageDescriptor(image.Format); - - (int width, int height, int depth) = GetImageSizeInBlocks(image); - - int bytesPerPixel = desc.BytesPerPixel; - - int inOffs = 0; - - for (int z = 0; z < depth; z++) - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) - { - long offset = (uint)swizzle.GetSwizzleOffset(x, y, z); - - vmm.Memory.WriteBytes(position + offset, data, inOffs, bytesPerPixel); - - inOffs += bytesPerPixel; - } - } - - // TODO: Support non 2D - public static bool CopyTexture( - NvGpuVmm vmm, - GalImage srcImage, - GalImage dstImage, - long srcAddress, - long dstAddress, - int srcX, - int srcY, - int dstX, - int dstY, - int width, - int height) - { - ISwizzle srcSwizzle = TextureHelper.GetSwizzle(srcImage); - ISwizzle dstSwizzle = TextureHelper.GetSwizzle(dstImage); - - ImageDescriptor desc = GetImageDescriptor(srcImage.Format); - - if (GetImageDescriptor(dstImage.Format).BytesPerPixel != desc.BytesPerPixel) - { - return false; - } - - int bytesPerPixel = desc.BytesPerPixel; - - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) - { - long srcOffset = (uint)srcSwizzle.GetSwizzleOffset(srcX + x, srcY + y, 0); - long dstOffset = (uint)dstSwizzle.GetSwizzleOffset(dstX + x, dstY + y, 0); - - byte[] texel = vmm.ReadBytes(srcAddress + srcOffset, bytesPerPixel); - - vmm.WriteBytes(dstAddress + dstOffset, texel); - } - - return true; - } - - public static int GetSize(GalImage image) - { - ImageDescriptor desc = GetImageDescriptor(image.Format); - - int componentCount = GetCoordsCountTextureTarget(image.TextureTarget); - - if (IsArray(image.TextureTarget)) - componentCount--; - - int width = DivRoundUp(image.Width, desc.BlockWidth); - int height = DivRoundUp(image.Height, desc.BlockHeight); - int depth = DivRoundUp(image.Depth, desc.BlockDepth); - - switch (componentCount) - { - case 1: - return desc.BytesPerPixel * width * image.LayerCount; - case 2: - return desc.BytesPerPixel * width * height * image.LayerCount; - case 3: - return desc.BytesPerPixel * width * height * depth * image.LayerCount; - default: - throw new InvalidOperationException($"Invalid component count: {componentCount}"); - } - } - - public static int GetGpuSize(GalImage image, bool forcePitch = false) - { - return TextureHelper.GetSwizzle(image).GetImageSize(image.MaxMipmapLevel) * image.LayerCount; - } - - public static int GetLayerOffset(GalImage image, int mipLevel) - { - if (mipLevel <= 0) - { - mipLevel = 1; - } - - return TextureHelper.GetSwizzle(image).GetMipOffset(mipLevel); - } - - public static int GetPitch(GalImageFormat format, int width) - { - ImageDescriptor desc = GetImageDescriptor(format); - - int pitch = desc.BytesPerPixel * DivRoundUp(width, desc.BlockWidth); - - pitch = (pitch + 0x1f) & ~0x1f; - - return pitch; - } - - public static int GetBlockWidth(GalImageFormat format) - { - return GetImageDescriptor(format).BlockWidth; - } - - public static int GetBlockHeight(GalImageFormat format) - { - return GetImageDescriptor(format).BlockHeight; - } - - public static int GetBlockDepth(GalImageFormat format) - { - return GetImageDescriptor(format).BlockDepth; - } - - public static int GetAlignedWidth(GalImage image) - { - ImageDescriptor desc = GetImageDescriptor(image.Format); - - int alignMask; - - if (image.Layout == GalMemoryLayout.BlockLinear) - { - alignMask = image.TileWidth * (64 / desc.BytesPerPixel) - 1; - } - else - { - alignMask = (32 / desc.BytesPerPixel) - 1; - } - - return (image.Width + alignMask) & ~alignMask; - } - - public static (int Width, int Height, int Depth) GetImageSizeInBlocks(GalImage image) - { - ImageDescriptor desc = GetImageDescriptor(image.Format); - - return (DivRoundUp(image.Width, desc.BlockWidth), - DivRoundUp(image.Height, desc.BlockHeight), - DivRoundUp(image.Depth, desc.BlockDepth)); - } - - public static int GetBytesPerPixel(GalImageFormat format) - { - return GetImageDescriptor(format).BytesPerPixel; - } - - private static int DivRoundUp(int lhs, int rhs) - { - return (lhs + (rhs - 1)) / rhs; - } - - public static bool HasColor(GalImageFormat format) - { - return (GetImageDescriptor(format).Target & TargetBuffer.Color) != 0; - } - - public static bool HasDepth(GalImageFormat format) - { - return (GetImageDescriptor(format).Target & TargetBuffer.Depth) != 0; - } - - public static bool HasStencil(GalImageFormat format) - { - return (GetImageDescriptor(format).Target & TargetBuffer.Stencil) != 0; - } - - public static bool IsCompressed(GalImageFormat format) - { - ImageDescriptor desc = GetImageDescriptor(format); - - return (desc.BlockWidth | desc.BlockHeight) != 1; - } - - private static ImageDescriptor GetImageDescriptor(GalImageFormat format) - { - GalImageFormat pixelFormat = format & GalImageFormat.FormatMask; - - if (ImageTable.TryGetValue(pixelFormat, out ImageDescriptor descriptor)) - { - return descriptor; - } - - throw new NotImplementedException($"Format \"{pixelFormat}\" not implemented!"); - } - - private static GalImageFormat GetFormatType(GalTextureType type) - { - switch (type) - { - case GalTextureType.Snorm: return Snorm; - case GalTextureType.Unorm: return Unorm; - case GalTextureType.Sint: return Sint; - case GalTextureType.Uint: return Uint; - case GalTextureType.Float: return Float; - - default: throw new NotImplementedException(((int)type).ToString()); - } - } - - public static TextureTarget GetTextureTarget(GalTextureTarget galTextureTarget) - { - switch (galTextureTarget) - { - case GalTextureTarget.OneD: - return TextureTarget.Texture1D; - case GalTextureTarget.TwoD: - case GalTextureTarget.TwoDNoMipMap: - return TextureTarget.Texture2D; - case GalTextureTarget.ThreeD: - return TextureTarget.Texture3D; - case GalTextureTarget.OneDArray: - return TextureTarget.Texture1DArray; - case GalTextureTarget.OneDBuffer: - return TextureTarget.TextureBuffer; - case GalTextureTarget.TwoDArray: - return TextureTarget.Texture2DArray; - case GalTextureTarget.CubeMap: - return TextureTarget.TextureCubeMap; - case GalTextureTarget.CubeArray: - return TextureTarget.TextureCubeMapArray; - default: - throw new NotSupportedException($"Texture target {galTextureTarget} currently not supported!"); - } - } - - public static bool IsArray(GalTextureTarget textureTarget) - { - switch (textureTarget) - { - case GalTextureTarget.OneDArray: - case GalTextureTarget.TwoDArray: - case GalTextureTarget.CubeArray: - return true; - default: - return false; - } - } - - public static int GetCoordsCountTextureTarget(GalTextureTarget textureTarget) - { - switch (textureTarget) - { - case GalTextureTarget.OneD: - return 1; - case GalTextureTarget.OneDArray: - case GalTextureTarget.OneDBuffer: - case GalTextureTarget.TwoD: - case GalTextureTarget.TwoDNoMipMap: - return 2; - case GalTextureTarget.ThreeD: - case GalTextureTarget.TwoDArray: - case GalTextureTarget.CubeMap: - return 3; - case GalTextureTarget.CubeArray: - return 4; - default: - throw new NotImplementedException($"TextureTarget.{textureTarget} not implemented yet."); - } - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/Texture/IntegerEncoded.cs b/Ryujinx.Graphics/Graphics3d/Texture/IntegerEncoded.cs deleted file mode 100644 index e6d67058..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/IntegerEncoded.cs +++ /dev/null @@ -1,269 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Texture -{ - public struct IntegerEncoded - { - public enum EIntegerEncoding - { - JustBits, - Quint, - Trit - } - - EIntegerEncoding _encoding; - public int NumberBits { get; private set; } - public int BitValue { get; private set; } - public int TritValue { get; private set; } - public int QuintValue { get; private set; } - - public IntegerEncoded(EIntegerEncoding encoding, int numBits) - { - _encoding = encoding; - NumberBits = numBits; - BitValue = 0; - TritValue = 0; - QuintValue = 0; - } - - public bool MatchesEncoding(IntegerEncoded other) - { - return _encoding == other._encoding && NumberBits == other.NumberBits; - } - - public EIntegerEncoding GetEncoding() - { - return _encoding; - } - - public int GetBitLength(int numberVals) - { - int totalBits = NumberBits * numberVals; - if (_encoding == EIntegerEncoding.Trit) - { - totalBits += (numberVals * 8 + 4) / 5; - } - else if (_encoding == EIntegerEncoding.Quint) - { - totalBits += (numberVals * 7 + 2) / 3; - } - return totalBits; - } - - public static IntegerEncoded CreateEncoding(int maxVal) - { - while (maxVal > 0) - { - int check = maxVal + 1; - - // Is maxVal a power of two? - if ((check & (check - 1)) == 0) - { - return new IntegerEncoded(EIntegerEncoding.JustBits, BitArrayStream.PopCnt(maxVal)); - } - - // Is maxVal of the type 3*2^n - 1? - if ((check % 3 == 0) && ((check / 3) & ((check / 3) - 1)) == 0) - { - return new IntegerEncoded(EIntegerEncoding.Trit, BitArrayStream.PopCnt(check / 3 - 1)); - } - - // Is maxVal of the type 5*2^n - 1? - if ((check % 5 == 0) && ((check / 5) & ((check / 5) - 1)) == 0) - { - return new IntegerEncoded(EIntegerEncoding.Quint, BitArrayStream.PopCnt(check / 5 - 1)); - } - - // Apparently it can't be represented with a bounded integer sequence... - // just iterate. - maxVal--; - } - - return new IntegerEncoded(EIntegerEncoding.JustBits, 0); - } - - public static void DecodeTritBlock( - BitArrayStream bitStream, - List<IntegerEncoded> listIntegerEncoded, - int numberBitsPerValue) - { - // Implement the algorithm in section C.2.12 - int[] m = new int[5]; - int[] t = new int[5]; - int T; - - // Read the trit encoded block according to - // table C.2.14 - m[0] = bitStream.ReadBits(numberBitsPerValue); - T = bitStream.ReadBits(2); - m[1] = bitStream.ReadBits(numberBitsPerValue); - T |= bitStream.ReadBits(2) << 2; - m[2] = bitStream.ReadBits(numberBitsPerValue); - T |= bitStream.ReadBits(1) << 4; - m[3] = bitStream.ReadBits(numberBitsPerValue); - T |= bitStream.ReadBits(2) << 5; - m[4] = bitStream.ReadBits(numberBitsPerValue); - T |= bitStream.ReadBits(1) << 7; - - int c = 0; - - BitArrayStream tb = new BitArrayStream(new BitArray(new int[] { T })); - if (tb.ReadBits(2, 4) == 7) - { - c = (tb.ReadBits(5, 7) << 2) | tb.ReadBits(0, 1); - t[4] = t[3] = 2; - } - else - { - c = tb.ReadBits(0, 4); - if (tb.ReadBits(5, 6) == 3) - { - t[4] = 2; - t[3] = tb.ReadBit(7); - } - else - { - t[4] = tb.ReadBit(7); - t[3] = tb.ReadBits(5, 6); - } - } - - BitArrayStream cb = new BitArrayStream(new BitArray(new int[] { c })); - if (cb.ReadBits(0, 1) == 3) - { - t[2] = 2; - t[1] = cb.ReadBit(4); - t[0] = (cb.ReadBit(3) << 1) | (cb.ReadBit(2) & ~cb.ReadBit(3)); - } - else if (cb.ReadBits(2, 3) == 3) - { - t[2] = 2; - t[1] = 2; - t[0] = cb.ReadBits(0, 1); - } - else - { - t[2] = cb.ReadBit(4); - t[1] = cb.ReadBits(2, 3); - t[0] = (cb.ReadBit(1) << 1) | (cb.ReadBit(0) & ~cb.ReadBit(1)); - } - - for (int i = 0; i < 5; i++) - { - IntegerEncoded intEncoded = new IntegerEncoded(EIntegerEncoding.Trit, numberBitsPerValue) - { - BitValue = m[i], - TritValue = t[i] - }; - listIntegerEncoded.Add(intEncoded); - } - } - - public static void DecodeQuintBlock( - BitArrayStream bitStream, - List<IntegerEncoded> listIntegerEncoded, - int numberBitsPerValue) - { - // Implement the algorithm in section C.2.12 - int[] m = new int[3]; - int[] qa = new int[3]; - int q; - - // Read the trit encoded block according to - // table C.2.15 - m[0] = bitStream.ReadBits(numberBitsPerValue); - q = bitStream.ReadBits(3); - m[1] = bitStream.ReadBits(numberBitsPerValue); - q |= bitStream.ReadBits(2) << 3; - m[2] = bitStream.ReadBits(numberBitsPerValue); - q |= bitStream.ReadBits(2) << 5; - - BitArrayStream qb = new BitArrayStream(new BitArray(new int[] { q })); - if (qb.ReadBits(1, 2) == 3 && qb.ReadBits(5, 6) == 0) - { - qa[0] = qa[1] = 4; - qa[2] = (qb.ReadBit(0) << 2) | ((qb.ReadBit(4) & ~qb.ReadBit(0)) << 1) | (qb.ReadBit(3) & ~qb.ReadBit(0)); - } - else - { - int c = 0; - if (qb.ReadBits(1, 2) == 3) - { - qa[2] = 4; - c = (qb.ReadBits(3, 4) << 3) | ((~qb.ReadBits(5, 6) & 3) << 1) | qb.ReadBit(0); - } - else - { - qa[2] = qb.ReadBits(5, 6); - c = qb.ReadBits(0, 4); - } - - BitArrayStream cb = new BitArrayStream(new BitArray(new int[] { c })); - if (cb.ReadBits(0, 2) == 5) - { - qa[1] = 4; - qa[0] = cb.ReadBits(3, 4); - } - else - { - qa[1] = cb.ReadBits(3, 4); - qa[0] = cb.ReadBits(0, 2); - } - } - - for (int i = 0; i < 3; i++) - { - IntegerEncoded intEncoded = new IntegerEncoded(EIntegerEncoding.Quint, numberBitsPerValue) - { - BitValue = m[i], - QuintValue = qa[i] - }; - listIntegerEncoded.Add(intEncoded); - } - } - - public static void DecodeIntegerSequence( - List<IntegerEncoded> decodeIntegerSequence, - BitArrayStream bitStream, - int maxRange, - int numberValues) - { - // Determine encoding parameters - IntegerEncoded intEncoded = CreateEncoding(maxRange); - - // Start decoding - int numberValuesDecoded = 0; - while (numberValuesDecoded < numberValues) - { - switch (intEncoded.GetEncoding()) - { - case EIntegerEncoding.Quint: - { - DecodeQuintBlock(bitStream, decodeIntegerSequence, intEncoded.NumberBits); - numberValuesDecoded += 3; - - break; - } - - case EIntegerEncoding.Trit: - { - DecodeTritBlock(bitStream, decodeIntegerSequence, intEncoded.NumberBits); - numberValuesDecoded += 5; - - break; - } - - case EIntegerEncoding.JustBits: - { - intEncoded.BitValue = bitStream.ReadBits(intEncoded.NumberBits); - decodeIntegerSequence.Add(intEncoded); - numberValuesDecoded++; - - break; - } - } - } - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/Texture/LinearSwizzle.cs b/Ryujinx.Graphics/Graphics3d/Texture/LinearSwizzle.cs deleted file mode 100644 index fb1bd098..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/LinearSwizzle.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Texture -{ - class LinearSwizzle : ISwizzle - { - private int _pitch; - private int _bpp; - - private int _sliceSize; - - public LinearSwizzle(int pitch, int bpp, int width, int height) - { - _pitch = pitch; - _bpp = bpp; - _sliceSize = width * height * bpp; - } - - public void SetMipLevel(int level) - { - throw new NotImplementedException(); - } - - public int GetMipOffset(int level) - { - if (level == 1) - return _sliceSize; - throw new NotImplementedException(); - } - - public int GetImageSize(int mipsCount) - { - int size = GetMipOffset(mipsCount); - - size = (size + 0x1fff) & ~0x1fff; - - return size; - } - - public int GetSwizzleOffset(int x, int y, int z) - { - return z * _sliceSize + x * _bpp + y * _pitch; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs b/Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs deleted file mode 100644 index 28c90502..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs +++ /dev/null @@ -1,166 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Memory; -using System; - -namespace Ryujinx.Graphics.Texture -{ - static class TextureFactory - { - public static GalImage MakeTexture(NvGpuVmm vmm, long ticPosition) - { - int[] tic = ReadWords(vmm, ticPosition, 8); - - GalImageFormat format = GetImageFormat(tic); - - GalTextureTarget textureTarget = (GalTextureTarget)((tic[4] >> 23) & 0xF); - - GalTextureSource xSource = (GalTextureSource)((tic[0] >> 19) & 7); - GalTextureSource ySource = (GalTextureSource)((tic[0] >> 22) & 7); - GalTextureSource zSource = (GalTextureSource)((tic[0] >> 25) & 7); - GalTextureSource wSource = (GalTextureSource)((tic[0] >> 28) & 7); - - TextureSwizzle swizzle = (TextureSwizzle)((tic[2] >> 21) & 7); - - int maxMipmapLevel = (tic[3] >> 28) & 0xF + 1; - - GalMemoryLayout layout; - - if (swizzle == TextureSwizzle.BlockLinear || - swizzle == TextureSwizzle.BlockLinearColorKey) - { - layout = GalMemoryLayout.BlockLinear; - } - else - { - layout = GalMemoryLayout.Pitch; - } - - int gobBlockHeightLog2 = (tic[3] >> 3) & 7; - int gobBlockDepthLog2 = (tic[3] >> 6) & 7; - int tileWidthLog2 = (tic[3] >> 10) & 7; - - int gobBlockHeight = 1 << gobBlockHeightLog2; - int gobBlockDepth = 1 << gobBlockDepthLog2; - int tileWidth = 1 << tileWidthLog2; - - int width = ((tic[4] >> 0) & 0xffff) + 1; - int height = ((tic[5] >> 0) & 0xffff) + 1; - int depth = ((tic[5] >> 16) & 0x3fff) + 1; - - int layoutCount = 1; - - // TODO: check this - if (ImageUtils.IsArray(textureTarget)) - { - layoutCount = depth; - depth = 1; - } - - if (textureTarget == GalTextureTarget.OneD) - { - height = 1; - } - - if (textureTarget == GalTextureTarget.TwoD || textureTarget == GalTextureTarget.OneD) - { - depth = 1; - } - else if (textureTarget == GalTextureTarget.CubeMap) - { - // FIXME: This is a bit hacky but I guess it's fine for now - layoutCount = 6; - depth = 1; - } - else if (textureTarget == GalTextureTarget.CubeArray) - { - // FIXME: This is a really really hacky but I guess it's fine for now - layoutCount *= 6; - depth = 1; - } - - GalImage image = new GalImage( - width, - height, - depth, - layoutCount, - tileWidth, - gobBlockHeight, - gobBlockDepth, - layout, - format, - textureTarget, - maxMipmapLevel, - xSource, - ySource, - zSource, - wSource); - - if (layout == GalMemoryLayout.Pitch) - { - image.Pitch = (tic[3] & 0xffff) << 5; - } - - return image; - } - - public static GalTextureSampler MakeSampler(NvGpu gpu, NvGpuVmm vmm, long tscPosition) - { - int[] tsc = ReadWords(vmm, tscPosition, 8); - - GalTextureWrap addressU = (GalTextureWrap)((tsc[0] >> 0) & 7); - GalTextureWrap addressV = (GalTextureWrap)((tsc[0] >> 3) & 7); - GalTextureWrap addressP = (GalTextureWrap)((tsc[0] >> 6) & 7); - - bool depthCompare = ((tsc[0] >> 9) & 1) == 1; - - DepthCompareFunc depthCompareFunc = (DepthCompareFunc)((tsc[0] >> 10) & 7); - - GalTextureFilter magFilter = (GalTextureFilter) ((tsc[1] >> 0) & 3); - GalTextureFilter minFilter = (GalTextureFilter) ((tsc[1] >> 4) & 3); - GalTextureMipFilter mipFilter = (GalTextureMipFilter)((tsc[1] >> 6) & 3); - - GalColorF borderColor = new GalColorF( - BitConverter.Int32BitsToSingle(tsc[4]), - BitConverter.Int32BitsToSingle(tsc[5]), - BitConverter.Int32BitsToSingle(tsc[6]), - BitConverter.Int32BitsToSingle(tsc[7])); - - return new GalTextureSampler( - addressU, - addressV, - addressP, - minFilter, - magFilter, - mipFilter, - borderColor, - depthCompare, - depthCompareFunc); - } - - private static GalImageFormat GetImageFormat(int[] tic) - { - GalTextureType rType = (GalTextureType)((tic[0] >> 7) & 7); - GalTextureType gType = (GalTextureType)((tic[0] >> 10) & 7); - GalTextureType bType = (GalTextureType)((tic[0] >> 13) & 7); - GalTextureType aType = (GalTextureType)((tic[0] >> 16) & 7); - - GalTextureFormat format = (GalTextureFormat)(tic[0] & 0x7f); - - bool convSrgb = ((tic[4] >> 22) & 1) != 0; - - return ImageUtils.ConvertTexture(format, rType, gType, bType, aType, convSrgb); - } - - private static int[] ReadWords(NvGpuVmm vmm, long position, int count) - { - int[] words = new int[count]; - - for (int index = 0; index < count; index++, position += 4) - { - words[index] = vmm.ReadInt32(position); - } - - return words; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Graphics3d/Texture/TextureHelper.cs b/Ryujinx.Graphics/Graphics3d/Texture/TextureHelper.cs deleted file mode 100644 index e07eb037..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/TextureHelper.cs +++ /dev/null @@ -1,53 +0,0 @@ -using ARMeilleure.Memory; -using Ryujinx.Common; -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Memory; - -namespace Ryujinx.Graphics.Texture -{ - static class TextureHelper - { - public static ISwizzle GetSwizzle(GalImage image) - { - int blockWidth = ImageUtils.GetBlockWidth (image.Format); - int blockHeight = ImageUtils.GetBlockHeight (image.Format); - int blockDepth = ImageUtils.GetBlockDepth (image.Format); - int bytesPerPixel = ImageUtils.GetBytesPerPixel(image.Format); - - int width = BitUtils.DivRoundUp(image.Width, blockWidth); - int height = BitUtils.DivRoundUp(image.Height, blockHeight); - int depth = BitUtils.DivRoundUp(image.Depth, blockDepth); - - if (image.Layout == GalMemoryLayout.BlockLinear) - { - int alignMask = image.TileWidth * (64 / bytesPerPixel) - 1; - - width = (width + alignMask) & ~alignMask; - - return new BlockLinearSwizzle( - width, - height, - depth, - image.GobBlockHeight, - image.GobBlockDepth, - bytesPerPixel); - } - else - { - return new LinearSwizzle(image.Pitch, bytesPerPixel, width, height); - } - } - - public static (MemoryManager Memory, long Position) GetMemoryAndPosition( - IMemory memory, - long position) - { - if (memory is NvGpuVmm vmm) - { - return (vmm.Memory, vmm.GetPhysicalAddress(position)); - } - - return ((MemoryManager)memory, position); - } - } -} diff --git a/Ryujinx.Graphics/Graphics3d/Texture/TextureSwizzle.cs b/Ryujinx.Graphics/Graphics3d/Texture/TextureSwizzle.cs deleted file mode 100644 index 2cc426ab..00000000 --- a/Ryujinx.Graphics/Graphics3d/Texture/TextureSwizzle.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Graphics.Texture -{ - public enum TextureSwizzle - { - _1DBuffer = 0, - PitchColorKey = 1, - Pitch = 2, - BlockLinear = 3, - BlockLinearColorKey = 4 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/GraphicsConfig.cs b/Ryujinx.Graphics/GraphicsConfig.cs deleted file mode 100644 index 3e3ef4ff..00000000 --- a/Ryujinx.Graphics/GraphicsConfig.cs +++ /dev/null @@ -1,4 +0,0 @@ -public static class GraphicsConfig -{ - public static string ShadersDumpPath; -} diff --git a/Ryujinx.Graphics/Memory/NvGpuBufferType.cs b/Ryujinx.Graphics/Memory/NvGpuBufferType.cs deleted file mode 100644 index 6f0d2571..00000000 --- a/Ryujinx.Graphics/Memory/NvGpuBufferType.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Graphics.Memory -{ - public enum NvGpuBufferType - { - Index, - Vertex, - Texture, - ConstBuffer, - Count - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Memory/NvGpuVmm.cs b/Ryujinx.Graphics/Memory/NvGpuVmm.cs deleted file mode 100644 index c72b82e3..00000000 --- a/Ryujinx.Graphics/Memory/NvGpuVmm.cs +++ /dev/null @@ -1,399 +0,0 @@ -using ARMeilleure.Memory; -using Ryujinx.Graphics.Gal; -using System; - -namespace Ryujinx.Graphics.Memory -{ - public class NvGpuVmm : IMemory, IGalMemory - { - public const long AddrSize = 1L << 40; - - private const int PtLvl0Bits = 14; - private const int PtLvl1Bits = 14; - private const int PtPageBits = 12; - - private const int PtLvl0Size = 1 << PtLvl0Bits; - private const int PtLvl1Size = 1 << PtLvl1Bits; - public const int PageSize = 1 << PtPageBits; - - private const int PtLvl0Mask = PtLvl0Size - 1; - private const int PtLvl1Mask = PtLvl1Size - 1; - public const int PageMask = PageSize - 1; - - private const int PtLvl0Bit = PtPageBits + PtLvl1Bits; - private const int PtLvl1Bit = PtPageBits; - - public MemoryManager Memory { get; private set; } - - private NvGpuVmmCache _cache; - - private const long PteUnmapped = -1; - private const long PteReserved = -2; - - private long[][] _pageTable; - - public NvGpuVmm(MemoryManager memory) - { - Memory = memory; - - _cache = new NvGpuVmmCache(memory); - - _pageTable = new long[PtLvl0Size][]; - } - - public long Map(long pa, long va, long size) - { - lock (_pageTable) - { - for (long offset = 0; offset < size; offset += PageSize) - { - SetPte(va + offset, pa + offset); - } - } - - return va; - } - - public long Map(long pa, long size) - { - lock (_pageTable) - { - long va = GetFreePosition(size); - - if (va != -1) - { - for (long offset = 0; offset < size; offset += PageSize) - { - SetPte(va + offset, pa + offset); - } - } - - return va; - } - } - - public long MapLow(long pa, long size) - { - lock (_pageTable) - { - long va = GetFreePosition(size, 1, PageSize); - - if (va != -1 && (ulong)va <= uint.MaxValue && (ulong)(va + size) <= uint.MaxValue) - { - for (long offset = 0; offset < size; offset += PageSize) - { - SetPte(va + offset, pa + offset); - } - } - else - { - va = -1; - } - - return va; - } - } - - public long ReserveFixed(long va, long size) - { - lock (_pageTable) - { - for (long offset = 0; offset < size; offset += PageSize) - { - if (IsPageInUse(va + offset)) - { - return -1; - } - } - - for (long offset = 0; offset < size; offset += PageSize) - { - SetPte(va + offset, PteReserved); - } - } - - return va; - } - - public long Reserve(long size, long align) - { - lock (_pageTable) - { - long position = GetFreePosition(size, align); - - if (position != -1) - { - for (long offset = 0; offset < size; offset += PageSize) - { - SetPte(position + offset, PteReserved); - } - } - - return position; - } - } - - public void Free(long va, long size) - { - lock (_pageTable) - { - for (long offset = 0; offset < size; offset += PageSize) - { - SetPte(va + offset, PteUnmapped); - } - } - } - - private long GetFreePosition(long size, long align = 1, long start = 1L << 32) - { - // Note: Address 0 is not considered valid by the driver, - // when 0 is returned it's considered a mapping error. - long position = start; - long freeSize = 0; - - if (align < 1) - { - align = 1; - } - - align = (align + PageMask) & ~PageMask; - - while (position + freeSize < AddrSize) - { - if (!IsPageInUse(position + freeSize)) - { - freeSize += PageSize; - - if (freeSize >= size) - { - return position; - } - } - else - { - position += freeSize + PageSize; - freeSize = 0; - - long remainder = position % align; - - if (remainder != 0) - { - position = (position - remainder) + align; - } - } - } - - return -1; - } - - public long GetPhysicalAddress(long va) - { - long basePos = GetPte(va); - - if (basePos < 0) - { - return -1; - } - - return basePos + (va & PageMask); - } - - public bool IsRegionFree(long va, long size) - { - for (long offset = 0; offset < size; offset += PageSize) - { - if (IsPageInUse(va + offset)) - { - return false; - } - } - - return true; - } - - private bool IsPageInUse(long va) - { - if (va >> PtLvl0Bits + PtLvl1Bits + PtPageBits != 0) - { - return false; - } - - long l0 = (va >> PtLvl0Bit) & PtLvl0Mask; - long l1 = (va >> PtLvl1Bit) & PtLvl1Mask; - - if (_pageTable[l0] == null) - { - return false; - } - - return _pageTable[l0][l1] != PteUnmapped; - } - - private long GetPte(long position) - { - long l0 = (position >> PtLvl0Bit) & PtLvl0Mask; - long l1 = (position >> PtLvl1Bit) & PtLvl1Mask; - - if (_pageTable[l0] == null) - { - return -1; - } - - return _pageTable[l0][l1]; - } - - private void SetPte(long position, long tgtAddr) - { - long l0 = (position >> PtLvl0Bit) & PtLvl0Mask; - long l1 = (position >> PtLvl1Bit) & PtLvl1Mask; - - if (_pageTable[l0] == null) - { - _pageTable[l0] = new long[PtLvl1Size]; - - for (int index = 0; index < PtLvl1Size; index++) - { - _pageTable[l0][index] = PteUnmapped; - } - } - - _pageTable[l0][l1] = tgtAddr; - } - - public bool IsRegionModified(long pa, long size, NvGpuBufferType bufferType) - { - return _cache.IsRegionModified(pa, size, bufferType); - } - - public bool TryGetHostAddress(long position, long size, out IntPtr ptr) - { - return Memory.TryGetHostAddress(GetPhysicalAddress(position), size, out ptr); - } - - public byte ReadByte(long position) - { - position = GetPhysicalAddress(position); - - return Memory.ReadByte(position); - } - - public ushort ReadUInt16(long position) - { - position = GetPhysicalAddress(position); - - return Memory.ReadUInt16(position); - } - - public uint ReadUInt32(long position) - { - position = GetPhysicalAddress(position); - - return Memory.ReadUInt32(position); - } - - public ulong ReadUInt64(long position) - { - position = GetPhysicalAddress(position); - - return Memory.ReadUInt64(position); - } - - public sbyte ReadSByte(long position) - { - position = GetPhysicalAddress(position); - - return Memory.ReadSByte(position); - } - - public short ReadInt16(long position) - { - position = GetPhysicalAddress(position); - - return Memory.ReadInt16(position); - } - - public int ReadInt32(long position) - { - position = GetPhysicalAddress(position); - - return Memory.ReadInt32(position); - } - - public long ReadInt64(long position) - { - position = GetPhysicalAddress(position); - - return Memory.ReadInt64(position); - } - - public byte[] ReadBytes(long position, long size) - { - position = GetPhysicalAddress(position); - - return Memory.ReadBytes(position, size); - } - - public void WriteByte(long position, byte value) - { - position = GetPhysicalAddress(position); - - Memory.WriteByte(position, value); - } - - public void WriteUInt16(long position, ushort value) - { - position = GetPhysicalAddress(position); - - Memory.WriteUInt16(position, value); - } - - public void WriteUInt32(long position, uint value) - { - position = GetPhysicalAddress(position); - - Memory.WriteUInt32(position, value); - } - - public void WriteUInt64(long position, ulong value) - { - position = GetPhysicalAddress(position); - - Memory.WriteUInt64(position, value); - } - - public void WriteSByte(long position, sbyte value) - { - position = GetPhysicalAddress(position); - - Memory.WriteSByte(position, value); - } - - public void WriteInt16(long position, short value) - { - position = GetPhysicalAddress(position); - - Memory.WriteInt16(position, value); - } - - public void WriteInt32(long position, int value) - { - position = GetPhysicalAddress(position); - - Memory.WriteInt32(position, value); - } - - public void WriteInt64(long position, long value) - { - position = GetPhysicalAddress(position); - - Memory.WriteInt64(position, value); - } - - public void WriteBytes(long position, byte[] data) - { - position = GetPhysicalAddress(position); - - Memory.WriteBytes(position, data); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Memory/NvGpuVmmCache.cs b/Ryujinx.Graphics/Memory/NvGpuVmmCache.cs deleted file mode 100644 index 2a505443..00000000 --- a/Ryujinx.Graphics/Memory/NvGpuVmmCache.cs +++ /dev/null @@ -1,79 +0,0 @@ -using ARMeilleure.Memory; -using System.Collections.Concurrent; - -namespace Ryujinx.Graphics.Memory -{ - class NvGpuVmmCache - { - private const int PageBits = MemoryManager.PageBits; - - private const long PageSize = MemoryManager.PageSize; - private const long PageMask = MemoryManager.PageMask; - - private ConcurrentDictionary<long, int>[] _cachedPages; - - private MemoryManager _memory; - - public NvGpuVmmCache(MemoryManager memory) - { - _memory = memory; - - _cachedPages = new ConcurrentDictionary<long, int>[1 << 20]; - } - - public bool IsRegionModified(long position, long size, NvGpuBufferType bufferType) - { - long va = position; - - long pa = _memory.GetPhysicalAddress(va); - - long endAddr = (va + size + PageMask) & ~PageMask; - - long addrTruncated = va & ~PageMask; - - bool modified = _memory.IsRegionModified(addrTruncated, endAddr - addrTruncated); - - int newBuffMask = 1 << (int)bufferType; - - long cachedPagesCount = 0; - - while (va < endAddr) - { - long page = _memory.GetPhysicalAddress(va) >> PageBits; - - ConcurrentDictionary<long, int> dictionary = _cachedPages[page]; - - if (dictionary == null) - { - dictionary = new ConcurrentDictionary<long, int>(); - - _cachedPages[page] = dictionary; - } - else if (modified) - { - _cachedPages[page].Clear(); - } - - if (dictionary.TryGetValue(pa, out int currBuffMask)) - { - if ((currBuffMask & newBuffMask) != 0) - { - cachedPagesCount++; - } - else - { - dictionary[pa] |= newBuffMask; - } - } - else - { - dictionary[pa] = newBuffMask; - } - - va += PageSize; - } - - return cachedPagesCount != (endAddr - addrTruncated) >> PageBits; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/NvGpu.cs b/Ryujinx.Graphics/NvGpu.cs deleted file mode 100644 index baac0b2d..00000000 --- a/Ryujinx.Graphics/NvGpu.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Graphics3d; -using Ryujinx.Graphics.Memory; -using Ryujinx.Graphics.VDec; -using Ryujinx.Graphics.Vic; - -namespace Ryujinx.Graphics -{ - public class NvGpu - { - public const int MaxViewportSize = 0x3FFF; - - public IGalRenderer Renderer { get; private set; } - - public GpuResourceManager ResourceManager { get; private set; } - - public DmaPusher Pusher { get; private set; } - - internal NvGpuFifo Fifo { get; private set; } - internal NvGpuEngine2d Engine2d { get; private set; } - internal NvGpuEngine3d Engine3d { get; private set; } - internal NvGpuEngineM2mf EngineM2mf { get; private set; } - internal NvGpuEngineP2mf EngineP2mf { get; private set; } - - private CdmaProcessor _cdmaProcessor; - internal VideoDecoder VideoDecoder { get; private set; } - internal VideoImageComposer VideoImageComposer { get; private set; } - - public NvGpu(IGalRenderer renderer) - { - Renderer = renderer; - - ResourceManager = new GpuResourceManager(this); - - Pusher = new DmaPusher(this); - - Fifo = new NvGpuFifo(this); - Engine2d = new NvGpuEngine2d(this); - Engine3d = new NvGpuEngine3d(this); - EngineM2mf = new NvGpuEngineM2mf(this); - EngineP2mf = new NvGpuEngineP2mf(this); - - _cdmaProcessor = new CdmaProcessor(this); - VideoDecoder = new VideoDecoder(this); - VideoImageComposer = new VideoImageComposer(this); - } - - public void PushCommandBuffer(NvGpuVmm vmm, int[] cmdBuffer) - { - lock (_cdmaProcessor) - { - _cdmaProcessor.PushCommands(vmm, cmdBuffer); - } - } - - public void UninitializeVideoDecoder() - { - lock (_cdmaProcessor) - { - FFmpegWrapper.Uninitialize(); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/QuadHelper.cs b/Ryujinx.Graphics/QuadHelper.cs deleted file mode 100644 index 643084ba..00000000 --- a/Ryujinx.Graphics/QuadHelper.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; - -namespace Ryujinx.Graphics -{ - static class QuadHelper - { - public static int ConvertSizeQuadsToTris(int size) - { - return size <= 0 ? 0 : (size / 4) * 6; - } - - public static int ConvertSizeQuadStripToTris(int size) - { - return size <= 1 ? 0 : ((size - 2) / 2) * 6; - } - - public static byte[] ConvertQuadsToTris(byte[] data, int entrySize, int count) - { - int primitivesCount = count / 4; - - int quadPrimSize = 4 * entrySize; - int trisPrimSize = 6 * entrySize; - - byte[] output = new byte[primitivesCount * 6 * entrySize]; - - for (int prim = 0; prim < primitivesCount; prim++) - { - void AssignIndex(int src, int dst, int copyCount = 1) - { - src = prim * quadPrimSize + src * entrySize; - dst = prim * trisPrimSize + dst * entrySize; - - Buffer.BlockCopy(data, src, output, dst, copyCount * entrySize); - } - - // 0 1 2 -> 0 1 2. - AssignIndex(0, 0, 3); - - // 2 3 -> 3 4. - AssignIndex(2, 3, 2); - - // 0 -> 5. - AssignIndex(0, 5); - } - - return output; - } - - public static byte[] ConvertQuadStripToTris(byte[] data, int entrySize, int count) - { - int primitivesCount = (count - 2) / 2; - - int quadPrimSize = 2 * entrySize; - int trisPrimSize = 6 * entrySize; - - byte[] output = new byte[primitivesCount * 6 * entrySize]; - - for (int prim = 0; prim < primitivesCount; prim++) - { - void AssignIndex(int src, int dst, int copyCount = 1) - { - src = prim * quadPrimSize + src * entrySize + 2 * entrySize; - dst = prim * trisPrimSize + dst * entrySize; - - Buffer.BlockCopy(data, src, output, dst, copyCount * entrySize); - } - - // -2 -1 0 -> 0 1 2. - AssignIndex(-2, 0, 3); - - // 0 1 -> 3 4. - AssignIndex(0, 3, 2); - - // -2 -> 5. - AssignIndex(-2, 5); - } - - return output; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Ryujinx.Graphics.csproj b/Ryujinx.Graphics/Ryujinx.Graphics.csproj deleted file mode 100644 index 4467fcdd..00000000 --- a/Ryujinx.Graphics/Ryujinx.Graphics.csproj +++ /dev/null @@ -1,40 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>netcoreapp3.0</TargetFramework> - <RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers> - <Configurations>Debug;Release;Profile Debug;Profile Release</Configurations> - </PropertyGroup> - - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - </PropertyGroup> - - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Debug|AnyCPU'"> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <DefineConstants>TRACE;USE_PROFILING</DefineConstants> - <Optimize>false</Optimize> - </PropertyGroup> - - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - </PropertyGroup> - - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Release|AnyCPU'"> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <DefineConstants>TRACE;USE_PROFILING</DefineConstants> - <Optimize>true</Optimize> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="FFmpeg.AutoGen" Version="4.2.0" /> - <PackageReference Include="OpenTK.NetStandard" Version="1.0.4" /> - </ItemGroup> - - <ItemGroup> - <ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" /> - <ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" /> - <ProjectReference Include="..\Ryujinx.Profiler\Ryujinx.Profiler.csproj" /> - </ItemGroup> - -</Project> diff --git a/Ryujinx.Graphics/Shader/CBufferDescriptor.cs b/Ryujinx.Graphics/Shader/CBufferDescriptor.cs deleted file mode 100644 index f99665e1..00000000 --- a/Ryujinx.Graphics/Shader/CBufferDescriptor.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Shader -{ - public struct CBufferDescriptor - { - public string Name { get; } - - public int Slot { get; } - - public CBufferDescriptor(string name, int slot) - { - Name = name; - Slot = slot; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs deleted file mode 100644 index dcbdc309..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Collections.Generic; -using System.Text; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - class CodeGenContext - { - private const string Tab = " "; - - public ShaderConfig Config { get; } - - public List<CBufferDescriptor> CBufferDescriptors { get; } - public List<TextureDescriptor> TextureDescriptors { get; } - - public OperandManager OperandManager { get; } - - private StringBuilder _sb; - - private int _level; - - private string _indentation; - - public CodeGenContext(ShaderConfig config) - { - Config = config; - - CBufferDescriptors = new List<CBufferDescriptor>(); - TextureDescriptors = new List<TextureDescriptor>(); - - OperandManager = new OperandManager(); - - _sb = new StringBuilder(); - } - - public void AppendLine() - { - _sb.AppendLine(); - } - - public void AppendLine(string str) - { - _sb.AppendLine(_indentation + str); - } - - public string GetCode() - { - return _sb.ToString(); - } - - public void EnterScope() - { - AppendLine("{"); - - _level++; - - UpdateIndentation(); - } - - public void LeaveScope(string suffix = "") - { - if (_level == 0) - { - return; - } - - _level--; - - UpdateIndentation(); - - AppendLine("}" + suffix); - } - - private void UpdateIndentation() - { - _indentation = GetIndentation(_level); - } - - private static string GetIndentation(int level) - { - string indentation = string.Empty; - - for (int index = 0; index < level; index++) - { - indentation += Tab; - } - - return indentation; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs deleted file mode 100644 index 5412d872..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs +++ /dev/null @@ -1,206 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - static class Declarations - { - public static void Declare(CodeGenContext context, StructuredProgramInfo info) - { - context.AppendLine("#version 420 core"); - - context.AppendLine(); - - context.AppendLine($"const int {DefaultNames.UndefinedName} = 0;"); - - context.AppendLine(); - - if (context.Config.Type == GalShaderType.Geometry) - { - context.AppendLine("layout (points) in;"); - context.AppendLine("layout (triangle_strip, max_vertices = 4) out;"); - - context.AppendLine(); - } - - context.AppendLine("layout (std140) uniform Extra"); - - context.EnterScope(); - - context.AppendLine("vec2 flip;"); - context.AppendLine("int instance;"); - - context.LeaveScope(";"); - - context.AppendLine(); - - if (info.CBuffers.Count != 0) - { - DeclareUniforms(context, info); - - context.AppendLine(); - } - - if (info.Samplers.Count != 0) - { - DeclareSamplers(context, info); - - context.AppendLine(); - } - - if (info.IAttributes.Count != 0) - { - DeclareInputAttributes(context, info); - - context.AppendLine(); - } - - if (info.OAttributes.Count != 0) - { - DeclareOutputAttributes(context, info); - - context.AppendLine(); - } - } - - public static void DeclareLocals(CodeGenContext context, StructuredProgramInfo info) - { - foreach (AstOperand decl in info.Locals) - { - string name = context.OperandManager.DeclareLocal(decl); - - context.AppendLine(GetVarTypeName(decl.VarType) + " " + name + ";"); - } - } - - private static string GetVarTypeName(VariableType type) - { - switch (type) - { - case VariableType.Bool: return "bool"; - case VariableType.F32: return "float"; - case VariableType.S32: return "int"; - case VariableType.U32: return "uint"; - } - - throw new ArgumentException($"Invalid variable type \"{type}\"."); - } - - private static void DeclareUniforms(CodeGenContext context, StructuredProgramInfo info) - { - foreach (int cbufSlot in info.CBuffers.OrderBy(x => x)) - { - string ubName = OperandManager.GetShaderStagePrefix(context.Config.Type); - - ubName += "_" + DefaultNames.UniformNamePrefix + cbufSlot; - - context.CBufferDescriptors.Add(new CBufferDescriptor(ubName, cbufSlot)); - - context.AppendLine("layout (std140) uniform " + ubName); - - context.EnterScope(); - - string ubSize = "[" + NumberFormatter.FormatInt(context.Config.MaxCBufferSize / 16) + "]"; - - context.AppendLine("vec4 " + OperandManager.GetUbName(context.Config.Type, cbufSlot) + ubSize + ";"); - - context.LeaveScope(";"); - } - } - - private static void DeclareSamplers(CodeGenContext context, StructuredProgramInfo info) - { - Dictionary<string, AstTextureOperation> samplers = new Dictionary<string, AstTextureOperation>(); - - foreach (AstTextureOperation texOp in info.Samplers.OrderBy(x => x.Handle)) - { - string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp); - - if (!samplers.TryAdd(samplerName, texOp)) - { - continue; - } - - string samplerTypeName = GetSamplerTypeName(texOp.Type); - - context.AppendLine("uniform " + samplerTypeName + " " + samplerName + ";"); - } - - foreach (KeyValuePair<string, AstTextureOperation> kv in samplers) - { - string samplerName = kv.Key; - - AstTextureOperation texOp = kv.Value; - - TextureDescriptor desc; - - if ((texOp.Flags & TextureFlags.Bindless) != 0) - { - AstOperand operand = texOp.GetSource(0) as AstOperand; - - desc = new TextureDescriptor(samplerName, operand.CbufSlot, operand.CbufOffset); - } - else - { - desc = new TextureDescriptor(samplerName, texOp.Handle); - } - - context.TextureDescriptors.Add(desc); - } - } - - private static void DeclareInputAttributes(CodeGenContext context, StructuredProgramInfo info) - { - string suffix = context.Config.Type == GalShaderType.Geometry ? "[]" : string.Empty; - - foreach (int attr in info.IAttributes.OrderBy(x => x)) - { - context.AppendLine($"layout (location = {attr}) in vec4 {DefaultNames.IAttributePrefix}{attr}{suffix};"); - } - } - - private static void DeclareOutputAttributes(CodeGenContext context, StructuredProgramInfo info) - { - foreach (int attr in info.OAttributes.OrderBy(x => x)) - { - context.AppendLine($"layout (location = {attr}) out vec4 {DefaultNames.OAttributePrefix}{attr};"); - } - } - - private static string GetSamplerTypeName(TextureType type) - { - string typeName; - - switch (type & TextureType.Mask) - { - case TextureType.Texture1D: typeName = "sampler1D"; break; - case TextureType.Texture2D: typeName = "sampler2D"; break; - case TextureType.Texture3D: typeName = "sampler3D"; break; - case TextureType.TextureCube: typeName = "samplerCube"; break; - - default: throw new ArgumentException($"Invalid sampler type \"{type}\"."); - } - - if ((type & TextureType.Multisample) != 0) - { - typeName += "MS"; - } - - if ((type & TextureType.Array) != 0) - { - typeName += "Array"; - } - - if ((type & TextureType.Shadow) != 0) - { - typeName += "Shadow"; - } - - return typeName; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/DefaultNames.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/DefaultNames.cs deleted file mode 100644 index 1d3939fb..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/DefaultNames.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - static class DefaultNames - { - public const string LocalNamePrefix = "temp"; - - public const string SamplerNamePrefix = "tex"; - - public const string IAttributePrefix = "in_attr"; - public const string OAttributePrefix = "out_attr"; - - public const string UniformNamePrefix = "c"; - public const string UniformNameSuffix = "data"; - - public const string UndefinedName = "undef"; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs deleted file mode 100644 index 4edbda8b..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs +++ /dev/null @@ -1,133 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using System; - -using static Ryujinx.Graphics.Shader.CodeGen.Glsl.TypeConversion; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - static class GlslGenerator - { - public static GlslProgram Generate(StructuredProgramInfo info, ShaderConfig config) - { - CodeGenContext context = new CodeGenContext(config); - - Declarations.Declare(context, info); - - PrintMainBlock(context, info); - - return new GlslProgram( - context.CBufferDescriptors.ToArray(), - context.TextureDescriptors.ToArray(), - context.GetCode()); - } - - private static void PrintMainBlock(CodeGenContext context, StructuredProgramInfo info) - { - context.AppendLine("void main()"); - - context.EnterScope(); - - Declarations.DeclareLocals(context, info); - - PrintBlock(context, info.MainBlock); - - context.LeaveScope(); - } - - private static void PrintBlock(CodeGenContext context, AstBlock block) - { - AstBlockVisitor visitor = new AstBlockVisitor(block); - - visitor.BlockEntered += (sender, e) => - { - switch (e.Block.Type) - { - case AstBlockType.DoWhile: - context.AppendLine("do"); - break; - - case AstBlockType.Else: - context.AppendLine("else"); - break; - - case AstBlockType.ElseIf: - context.AppendLine($"else if ({GetCondExpr(context, e.Block.Condition)})"); - break; - - case AstBlockType.If: - context.AppendLine($"if ({GetCondExpr(context, e.Block.Condition)})"); - break; - - default: throw new InvalidOperationException($"Found unexpected block type \"{e.Block.Type}\"."); - } - - context.EnterScope(); - }; - - visitor.BlockLeft += (sender, e) => - { - context.LeaveScope(); - - if (e.Block.Type == AstBlockType.DoWhile) - { - context.AppendLine($"while ({GetCondExpr(context, e.Block.Condition)});"); - } - }; - - foreach (IAstNode node in visitor.Visit()) - { - if (node is AstOperation operation) - { - if (operation.Inst == Instruction.Return) - { - PrepareForReturn(context); - } - - context.AppendLine(InstGen.GetExpression(context, operation) + ";"); - } - else if (node is AstAssignment assignment) - { - VariableType srcType = OperandManager.GetNodeDestType(assignment.Source); - VariableType dstType = OperandManager.GetNodeDestType(assignment.Destination); - - string dest; - - if (assignment.Destination is AstOperand operand && operand.Type == OperandType.Attribute) - { - dest = OperandManager.GetOutAttributeName(operand, context.Config.Type); - } - else - { - dest = InstGen.GetExpression(context, assignment.Destination); - } - - string src = ReinterpretCast(context, assignment.Source, srcType, dstType); - - context.AppendLine(dest + " = " + src + ";"); - } - else - { - throw new InvalidOperationException($"Found unexpected node type \"{node?.GetType().Name ?? "null"}\"."); - } - } - } - - private static string GetCondExpr(CodeGenContext context, IAstNode cond) - { - VariableType srcType = OperandManager.GetNodeDestType(cond); - - return ReinterpretCast(context, cond, srcType, VariableType.Bool); - } - - private static void PrepareForReturn(CodeGenContext context) - { - if (context.Config.Type == GalShaderType.Vertex) - { - context.AppendLine("gl_Position.xy *= flip;"); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslProgram.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslProgram.cs deleted file mode 100644 index e616aa1f..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslProgram.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - class GlslProgram - { - public CBufferDescriptor[] CBufferDescriptors { get; } - public TextureDescriptor[] TextureDescriptors { get; } - - public string Code { get; } - - public GlslProgram( - CBufferDescriptor[] cBufferDescs, - TextureDescriptor[] textureDescs, - string code) - { - CBufferDescriptors = cBufferDescs; - TextureDescriptors = textureDescs; - Code = code; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs deleted file mode 100644 index b0b2ec1a..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs +++ /dev/null @@ -1,110 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using System; - -using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - static class InstGen - { - public static string GetExpression(CodeGenContext context, IAstNode node) - { - if (node is AstOperation operation) - { - return GetExpression(context, operation); - } - else if (node is AstOperand operand) - { - return context.OperandManager.GetExpression(operand, context.Config.Type); - } - - throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\"."); - } - - private static string GetExpression(CodeGenContext context, AstOperation operation) - { - Instruction inst = operation.Inst; - - InstInfo info = GetInstructionInfo(inst); - - if ((info.Type & InstType.Call) != 0) - { - int arity = (int)(info.Type & InstType.ArityMask); - - string args = string.Empty; - - for (int argIndex = 0; argIndex < arity; argIndex++) - { - if (argIndex != 0) - { - args += ", "; - } - - VariableType dstType = GetSrcVarType(inst, argIndex); - - args += GetSoureExpr(context, operation.GetSource(argIndex), dstType); - } - - return info.OpName + "(" + args + ")"; - } - else if ((info.Type & InstType.Op) != 0) - { - string op = info.OpName; - - int arity = (int)(info.Type & InstType.ArityMask); - - string[] expr = new string[arity]; - - for (int index = 0; index < arity; index++) - { - IAstNode src = operation.GetSource(index); - - string srcExpr = GetSoureExpr(context, src, GetSrcVarType(inst, index)); - - bool isLhs = arity == 2 && index == 0; - - expr[index] = Enclose(srcExpr, src, inst, info, isLhs); - } - - switch (arity) - { - case 0: - return op; - - case 1: - return op + expr[0]; - - case 2: - return $"{expr[0]} {op} {expr[1]}"; - - case 3: - return $"{expr[0]} {op[0]} {expr[1]} {op[1]} {expr[2]}"; - } - } - else if ((info.Type & InstType.Special) != 0) - { - switch (inst) - { - case Instruction.LoadConstant: - return InstGenMemory.LoadConstant(context, operation); - - case Instruction.PackHalf2x16: - return InstGenPacking.PackHalf2x16(context, operation); - - case Instruction.TextureSample: - return InstGenMemory.TextureSample(context, operation); - - case Instruction.TextureSize: - return InstGenMemory.TextureSize(context, operation); - - case Instruction.UnpackHalf2x16: - return InstGenPacking.UnpackHalf2x16(context, operation); - } - } - - throw new InvalidOperationException($"Unexpected instruction type \"{info.Type}\"."); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs deleted file mode 100644 index 9855cd91..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs +++ /dev/null @@ -1,170 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; - -using static Ryujinx.Graphics.Shader.CodeGen.Glsl.TypeConversion; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - static class InstGenHelper - { - private static InstInfo[] _infoTbl; - - static InstGenHelper() - { - _infoTbl = new InstInfo[(int)Instruction.Count]; - - Add(Instruction.Absolute, InstType.CallUnary, "abs"); - Add(Instruction.Add, InstType.OpBinaryCom, "+", 2); - Add(Instruction.BitfieldExtractS32, InstType.CallTernary, "bitfieldExtract"); - Add(Instruction.BitfieldExtractU32, InstType.CallTernary, "bitfieldExtract"); - Add(Instruction.BitfieldInsert, InstType.CallQuaternary, "bitfieldInsert"); - Add(Instruction.BitfieldReverse, InstType.CallUnary, "bitfieldReverse"); - Add(Instruction.BitwiseAnd, InstType.OpBinaryCom, "&", 6); - Add(Instruction.BitwiseExclusiveOr, InstType.OpBinaryCom, "^", 7); - Add(Instruction.BitwiseNot, InstType.OpUnary, "~", 0); - Add(Instruction.BitwiseOr, InstType.OpBinaryCom, "|", 8); - Add(Instruction.Ceiling, InstType.CallUnary, "ceil"); - Add(Instruction.Clamp, InstType.CallTernary, "clamp"); - Add(Instruction.ClampU32, InstType.CallTernary, "clamp"); - Add(Instruction.CompareEqual, InstType.OpBinaryCom, "==", 5); - Add(Instruction.CompareGreater, InstType.OpBinary, ">", 4); - Add(Instruction.CompareGreaterOrEqual, InstType.OpBinary, ">=", 4); - Add(Instruction.CompareGreaterOrEqualU32, InstType.OpBinary, ">=", 4); - Add(Instruction.CompareGreaterU32, InstType.OpBinary, ">", 4); - Add(Instruction.CompareLess, InstType.OpBinary, "<", 4); - Add(Instruction.CompareLessOrEqual, InstType.OpBinary, "<=", 4); - Add(Instruction.CompareLessOrEqualU32, InstType.OpBinary, "<=", 4); - Add(Instruction.CompareLessU32, InstType.OpBinary, "<", 4); - Add(Instruction.CompareNotEqual, InstType.OpBinaryCom, "!=", 5); - Add(Instruction.ConditionalSelect, InstType.OpTernary, "?:", 12); - Add(Instruction.ConvertFPToS32, InstType.CallUnary, "int"); - Add(Instruction.ConvertS32ToFP, InstType.CallUnary, "float"); - Add(Instruction.ConvertU32ToFP, InstType.CallUnary, "float"); - Add(Instruction.Cosine, InstType.CallUnary, "cos"); - Add(Instruction.Discard, InstType.OpNullary, "discard"); - Add(Instruction.Divide, InstType.OpBinary, "/", 1); - Add(Instruction.EmitVertex, InstType.CallNullary, "EmitVertex"); - Add(Instruction.EndPrimitive, InstType.CallNullary, "EndPrimitive"); - Add(Instruction.ExponentB2, InstType.CallUnary, "exp2"); - Add(Instruction.Floor, InstType.CallUnary, "floor"); - Add(Instruction.FusedMultiplyAdd, InstType.CallTernary, "fma"); - Add(Instruction.IsNan, InstType.CallUnary, "isnan"); - Add(Instruction.LoadConstant, InstType.Special); - Add(Instruction.LogarithmB2, InstType.CallUnary, "log2"); - Add(Instruction.LogicalAnd, InstType.OpBinaryCom, "&&", 9); - Add(Instruction.LogicalExclusiveOr, InstType.OpBinaryCom, "^^", 10); - Add(Instruction.LogicalNot, InstType.OpUnary, "!", 0); - Add(Instruction.LogicalOr, InstType.OpBinaryCom, "||", 11); - Add(Instruction.LoopBreak, InstType.OpNullary, "break"); - Add(Instruction.LoopContinue, InstType.OpNullary, "continue"); - Add(Instruction.PackHalf2x16, InstType.Special); - Add(Instruction.ShiftLeft, InstType.OpBinary, "<<", 3); - Add(Instruction.ShiftRightS32, InstType.OpBinary, ">>", 3); - Add(Instruction.ShiftRightU32, InstType.OpBinary, ">>", 3); - Add(Instruction.Maximum, InstType.CallBinary, "max"); - Add(Instruction.MaximumU32, InstType.CallBinary, "max"); - Add(Instruction.Minimum, InstType.CallBinary, "min"); - Add(Instruction.MinimumU32, InstType.CallBinary, "min"); - Add(Instruction.Multiply, InstType.OpBinaryCom, "*", 1); - Add(Instruction.Negate, InstType.OpUnary, "-", 0); - Add(Instruction.ReciprocalSquareRoot, InstType.CallUnary, "inversesqrt"); - Add(Instruction.Return, InstType.OpNullary, "return"); - Add(Instruction.Sine, InstType.CallUnary, "sin"); - Add(Instruction.SquareRoot, InstType.CallUnary, "sqrt"); - Add(Instruction.Subtract, InstType.OpBinary, "-", 2); - Add(Instruction.TextureSample, InstType.Special); - Add(Instruction.TextureSize, InstType.Special); - Add(Instruction.Truncate, InstType.CallUnary, "trunc"); - Add(Instruction.UnpackHalf2x16, InstType.Special); - } - - private static void Add(Instruction inst, InstType flags, string opName = null, int precedence = 0) - { - _infoTbl[(int)inst] = new InstInfo(flags, opName, precedence); - } - - public static InstInfo GetInstructionInfo(Instruction inst) - { - return _infoTbl[(int)(inst & Instruction.Mask)]; - } - - public static string GetSoureExpr(CodeGenContext context, IAstNode node, VariableType dstType) - { - return ReinterpretCast(context, node, OperandManager.GetNodeDestType(node), dstType); - } - - public static string Enclose(string expr, IAstNode node, Instruction pInst, bool isLhs) - { - InstInfo pInfo = GetInstructionInfo(pInst); - - return Enclose(expr, node, pInst, pInfo, isLhs); - } - - public static string Enclose(string expr, IAstNode node, Instruction pInst, InstInfo pInfo, bool isLhs = false) - { - if (NeedsParenthesis(node, pInst, pInfo, isLhs)) - { - expr = "(" + expr + ")"; - } - - return expr; - } - - public static bool NeedsParenthesis(IAstNode node, Instruction pInst, InstInfo pInfo, bool isLhs) - { - // If the node isn't a operation, then it can only be a operand, - // and those never needs to be surrounded in parenthesis. - if (!(node is AstOperation operation)) - { - // This is sort of a special case, if this is a negative constant, - // and it is consumed by a unary operation, we need to put on the parenthesis, - // as in GLSL a sequence like --2 or ~-1 is not valid. - if (IsNegativeConst(node) && pInfo.Type == InstType.OpUnary) - { - return true; - } - - return false; - } - - if ((pInfo.Type & (InstType.Call | InstType.Special)) != 0) - { - return false; - } - - InstInfo info = _infoTbl[(int)(operation.Inst & Instruction.Mask)]; - - if ((info.Type & (InstType.Call | InstType.Special)) != 0) - { - return false; - } - - if (info.Precedence < pInfo.Precedence) - { - return false; - } - - if (info.Precedence == pInfo.Precedence && isLhs) - { - return false; - } - - if (pInst == operation.Inst && info.Type == InstType.OpBinaryCom) - { - return false; - } - - return true; - } - - private static bool IsNegativeConst(IAstNode node) - { - if (!(node is AstOperand operand)) - { - return false; - } - - return operand.Type == OperandType.Constant && operand.Value < 0; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs deleted file mode 100644 index 8b5257fc..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs +++ /dev/null @@ -1,244 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; - -using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - static class InstGenMemory - { - public static string LoadConstant(CodeGenContext context, AstOperation operation) - { - IAstNode src1 = operation.GetSource(1); - - string offsetExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 1)); - - offsetExpr = Enclose(offsetExpr, src1, Instruction.ShiftRightS32, isLhs: true); - - return OperandManager.GetConstantBufferName(operation.GetSource(0), offsetExpr, context.Config.Type); - } - - public static string TextureSample(CodeGenContext context, AstOperation operation) - { - AstTextureOperation texOp = (AstTextureOperation)operation; - - bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0; - bool isGather = (texOp.Flags & TextureFlags.Gather) != 0; - bool intCoords = (texOp.Flags & TextureFlags.IntCoords) != 0; - bool hasLodBias = (texOp.Flags & TextureFlags.LodBias) != 0; - bool hasLodLevel = (texOp.Flags & TextureFlags.LodLevel) != 0; - bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0; - bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0; - bool isArray = (texOp.Type & TextureType.Array) != 0; - bool isMultisample = (texOp.Type & TextureType.Multisample) != 0; - bool isShadow = (texOp.Type & TextureType.Shadow) != 0; - - string texCall = intCoords ? "texelFetch" : "texture"; - - if (isGather) - { - texCall += "Gather"; - } - else if (hasLodLevel && !intCoords) - { - texCall += "Lod"; - } - - if (hasOffset) - { - texCall += "Offset"; - } - else if (hasOffsets) - { - texCall += "Offsets"; - } - - string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp); - - texCall += "(" + samplerName; - - int coordsCount = texOp.Type.GetCoordsCount(); - - int pCount = coordsCount; - - int arrayIndexElem = -1; - - if (isArray) - { - arrayIndexElem = pCount++; - } - - // The sampler 1D shadow overload expects a - // dummy value on the middle of the vector, who knows why... - bool hasDummy1DShadowElem = texOp.Type == (TextureType.Texture1D | TextureType.Shadow); - - if (hasDummy1DShadowElem) - { - pCount++; - } - - if (isShadow && !isGather) - { - pCount++; - } - - // On textureGather*, the comparison value is - // always specified as an extra argument. - bool hasExtraCompareArg = isShadow && isGather; - - if (pCount == 5) - { - pCount = 4; - - hasExtraCompareArg = true; - } - - int srcIndex = isBindless ? 1 : 0; - - string Src(VariableType type) - { - return GetSoureExpr(context, texOp.GetSource(srcIndex++), type); - } - - void Append(string str) - { - texCall += ", " + str; - } - - VariableType coordType = intCoords ? VariableType.S32 : VariableType.F32; - - string AssemblePVector(int count) - { - if (count > 1) - { - string[] elems = new string[count]; - - for (int index = 0; index < count; index++) - { - if (arrayIndexElem == index) - { - elems[index] = Src(VariableType.S32); - - if (!intCoords) - { - elems[index] = "float(" + elems[index] + ")"; - } - } - else if (index == 1 && hasDummy1DShadowElem) - { - elems[index] = NumberFormatter.FormatFloat(0); - } - else - { - elems[index] = Src(coordType); - } - } - - string prefix = intCoords ? "i" : string.Empty; - - return prefix + "vec" + count + "(" + string.Join(", ", elems) + ")"; - } - else - { - return Src(coordType); - } - } - - Append(AssemblePVector(pCount)); - - if (hasExtraCompareArg) - { - Append(Src(VariableType.F32)); - } - - if (isMultisample) - { - Append(Src(VariableType.S32)); - } - else if (hasLodLevel) - { - Append(Src(coordType)); - } - - string AssembleOffsetVector(int count) - { - if (count > 1) - { - string[] elems = new string[count]; - - for (int index = 0; index < count; index++) - { - elems[index] = Src(VariableType.S32); - } - - return "ivec" + count + "(" + string.Join(", ", elems) + ")"; - } - else - { - return Src(VariableType.S32); - } - } - - if (hasOffset) - { - Append(AssembleOffsetVector(coordsCount)); - } - else if (hasOffsets) - { - texCall += $", ivec{coordsCount}[4]("; - - texCall += AssembleOffsetVector(coordsCount) + ", "; - texCall += AssembleOffsetVector(coordsCount) + ", "; - texCall += AssembleOffsetVector(coordsCount) + ", "; - texCall += AssembleOffsetVector(coordsCount) + ")"; - } - - if (hasLodBias) - { - Append(Src(VariableType.F32)); - } - - // textureGather* optional extra component index, - // not needed for shadow samplers. - if (isGather && !isShadow) - { - Append(Src(VariableType.S32)); - } - - texCall += ")" + (isGather || !isShadow ? GetMask(texOp.ComponentMask) : ""); - - return texCall; - } - - public static string TextureSize(CodeGenContext context, AstOperation operation) - { - AstTextureOperation texOp = (AstTextureOperation)operation; - - bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0; - - string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp); - - IAstNode src0 = operation.GetSource(isBindless ? 1 : 0); - - string src0Expr = GetSoureExpr(context, src0, GetSrcVarType(operation.Inst, 0)); - - return $"textureSize({samplerName}, {src0Expr}){GetMask(texOp.ComponentMask)}"; - } - - private static string GetMask(int compMask) - { - string mask = "."; - - for (int index = 0; index < 4; index++) - { - if ((compMask & (1 << index)) != 0) - { - mask += "rgba".Substring(index, 1); - } - } - - return mask; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenPacking.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenPacking.cs deleted file mode 100644 index 4a40032c..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenPacking.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Ryujinx.Graphics.Shader.StructuredIr; - -using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - static class InstGenPacking - { - public static string PackHalf2x16(CodeGenContext context, AstOperation operation) - { - IAstNode src0 = operation.GetSource(0); - IAstNode src1 = operation.GetSource(1); - - string src0Expr = GetSoureExpr(context, src0, GetSrcVarType(operation.Inst, 0)); - string src1Expr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 1)); - - return $"packHalf2x16(vec2({src0Expr}, {src1Expr}))"; - } - - public static string UnpackHalf2x16(CodeGenContext context, AstOperation operation) - { - IAstNode src = operation.GetSource(0); - - string srcExpr = GetSoureExpr(context, src, GetSrcVarType(operation.Inst, 0)); - - return $"unpackHalf2x16({srcExpr}){GetMask(operation.ComponentMask)}"; - } - - private static string GetMask(int compMask) - { - string mask = "."; - - for (int index = 0; index < 2; index++) - { - if ((compMask & (1 << index)) != 0) - { - mask += "xy".Substring(index, 1); - } - } - - return mask; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstInfo.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstInfo.cs deleted file mode 100644 index fc9aef7e..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstInfo.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - struct InstInfo - { - public InstType Type { get; } - - public string OpName { get; } - - public int Precedence { get; } - - public InstInfo(InstType type, string opName, int precedence) - { - Type = type; - OpName = opName; - Precedence = precedence; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstType.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstType.cs deleted file mode 100644 index 121cd079..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstType.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - [Flags] - enum InstType - { - OpNullary = Op | 0, - OpUnary = Op | 1, - OpBinary = Op | 2, - OpTernary = Op | 3, - OpBinaryCom = OpBinary | Commutative, - - CallNullary = Call | 0, - CallUnary = Call | 1, - CallBinary = Call | 2, - CallTernary = Call | 3, - CallQuaternary = Call | 4, - - Commutative = 1 << 8, - Op = 1 << 9, - Call = 1 << 10, - Special = 1 << 11, - - ArityMask = 0xff - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/NumberFormatter.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/NumberFormatter.cs deleted file mode 100644 index 2ec44277..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/NumberFormatter.cs +++ /dev/null @@ -1,104 +0,0 @@ -using Ryujinx.Graphics.Shader.StructuredIr; -using System; -using System.Globalization; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - static class NumberFormatter - { - private const int MaxDecimal = 256; - - public static bool TryFormat(int value, VariableType dstType, out string formatted) - { - if (dstType == VariableType.F32) - { - return TryFormatFloat(BitConverter.Int32BitsToSingle(value), out formatted); - } - else if (dstType == VariableType.S32) - { - formatted = FormatInt(value); - } - else if (dstType == VariableType.U32) - { - formatted = FormatUint((uint)value); - } - else if (dstType == VariableType.Bool) - { - formatted = value != 0 ? "true" : "false"; - } - else - { - throw new ArgumentException($"Invalid variable type \"{dstType}\"."); - } - - return true; - } - - public static string FormatFloat(float value) - { - if (!TryFormatFloat(value, out string formatted)) - { - throw new ArgumentException("Failed to convert float value to string."); - } - - return formatted; - } - - public static bool TryFormatFloat(float value, out string formatted) - { - if (float.IsNaN(value) || float.IsInfinity(value)) - { - formatted = null; - - return false; - } - - formatted = value.ToString("G9", CultureInfo.InvariantCulture); - - if (!(formatted.Contains('.') || - formatted.Contains('e') || - formatted.Contains('E'))) - { - formatted += ".0"; - } - - return true; - } - - public static string FormatInt(int value, VariableType dstType) - { - if (dstType == VariableType.S32) - { - return FormatInt(value); - } - else if (dstType == VariableType.U32) - { - return FormatUint((uint)value); - } - else - { - throw new ArgumentException($"Invalid variable type \"{dstType}\"."); - } - } - - public static string FormatInt(int value) - { - if (value <= MaxDecimal && value >= -MaxDecimal) - { - return value.ToString(CultureInfo.InvariantCulture); - } - - return "0x" + value.ToString("X", CultureInfo.InvariantCulture); - } - - public static string FormatUint(uint value) - { - if (value <= MaxDecimal && value >= 0) - { - return value.ToString(CultureInfo.InvariantCulture) + "u"; - } - - return "0x" + value.ToString("X", CultureInfo.InvariantCulture) + "u"; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs deleted file mode 100644 index 19f7185e..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs +++ /dev/null @@ -1,249 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using System; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - class OperandManager - { - private static string[] _stagePrefixes = new string[] { "vp", "tcp", "tep", "gp", "fp" }; - - private struct BuiltInAttribute - { - public string Name { get; } - - public VariableType Type { get; } - - public BuiltInAttribute(string name, VariableType type) - { - Name = name; - Type = type; - } - } - - private static Dictionary<int, BuiltInAttribute> _builtInAttributes = - new Dictionary<int, BuiltInAttribute>() - { - { AttributeConsts.Layer, new BuiltInAttribute("gl_Layer", VariableType.S32) }, - { AttributeConsts.PointSize, new BuiltInAttribute("gl_PointSize", VariableType.F32) }, - { AttributeConsts.PositionX, new BuiltInAttribute("gl_Position.x", VariableType.F32) }, - { AttributeConsts.PositionY, new BuiltInAttribute("gl_Position.y", VariableType.F32) }, - { AttributeConsts.PositionZ, new BuiltInAttribute("gl_Position.z", VariableType.F32) }, - { AttributeConsts.PositionW, new BuiltInAttribute("gl_Position.w", VariableType.F32) }, - { AttributeConsts.ClipDistance0, new BuiltInAttribute("gl_ClipDistance[0]", VariableType.F32) }, - { AttributeConsts.ClipDistance1, new BuiltInAttribute("gl_ClipDistance[1]", VariableType.F32) }, - { AttributeConsts.ClipDistance2, new BuiltInAttribute("gl_ClipDistance[2]", VariableType.F32) }, - { AttributeConsts.ClipDistance3, new BuiltInAttribute("gl_ClipDistance[3]", VariableType.F32) }, - { AttributeConsts.ClipDistance4, new BuiltInAttribute("gl_ClipDistance[4]", VariableType.F32) }, - { AttributeConsts.ClipDistance5, new BuiltInAttribute("gl_ClipDistance[5]", VariableType.F32) }, - { AttributeConsts.ClipDistance6, new BuiltInAttribute("gl_ClipDistance[6]", VariableType.F32) }, - { AttributeConsts.ClipDistance7, new BuiltInAttribute("gl_ClipDistance[7]", VariableType.F32) }, - { AttributeConsts.PointCoordX, new BuiltInAttribute("gl_PointCoord.x", VariableType.F32) }, - { AttributeConsts.PointCoordY, new BuiltInAttribute("gl_PointCoord.y", VariableType.F32) }, - { AttributeConsts.TessCoordX, new BuiltInAttribute("gl_TessCoord.x", VariableType.F32) }, - { AttributeConsts.TessCoordY, new BuiltInAttribute("gl_TessCoord.y", VariableType.F32) }, - { AttributeConsts.InstanceId, new BuiltInAttribute("instance", VariableType.S32) }, - { AttributeConsts.VertexId, new BuiltInAttribute("gl_VertexID", VariableType.S32) }, - { AttributeConsts.FrontFacing, new BuiltInAttribute("gl_FrontFacing", VariableType.Bool) }, - { AttributeConsts.FragmentOutputDepth, new BuiltInAttribute("gl_FragDepth", VariableType.F32) } - }; - - private Dictionary<AstOperand, string> _locals; - - public OperandManager() - { - _locals = new Dictionary<AstOperand, string>(); - } - - public string DeclareLocal(AstOperand operand) - { - string name = $"{DefaultNames.LocalNamePrefix}_{_locals.Count}"; - - _locals.Add(operand, name); - - return name; - } - - public string GetExpression(AstOperand operand, GalShaderType shaderType) - { - switch (operand.Type) - { - case OperandType.Attribute: - return GetAttributeName(operand, shaderType); - - case OperandType.Constant: - return NumberFormatter.FormatInt(operand.Value); - - case OperandType.ConstantBuffer: - return GetConstantBufferName(operand, shaderType); - - case OperandType.LocalVariable: - return _locals[operand]; - - case OperandType.Undefined: - return DefaultNames.UndefinedName; - } - - throw new ArgumentException($"Invalid operand type \"{operand.Type}\"."); - } - - public static string GetConstantBufferName(AstOperand cbuf, GalShaderType shaderType) - { - string ubName = GetUbName(shaderType, cbuf.CbufSlot); - - ubName += "[" + (cbuf.CbufOffset >> 2) + "]"; - - return ubName + "." + GetSwizzleMask(cbuf.CbufOffset & 3); - } - - public static string GetConstantBufferName(IAstNode slot, string offsetExpr, GalShaderType shaderType) - { - // Non-constant slots are not supported. - // It is expected that upstream stages are never going to generate non-constant - // slot access. - AstOperand operand = (AstOperand)slot; - - string ubName = GetUbName(shaderType, operand.Value); - - string index0 = "[" + offsetExpr + " >> 4]"; - string index1 = "[" + offsetExpr + " >> 2 & 3]"; - - return ubName + index0 + index1; - } - - public static string GetOutAttributeName(AstOperand attr, GalShaderType shaderType) - { - return GetAttributeName(attr, shaderType, isOutAttr: true); - } - - private static string GetAttributeName(AstOperand attr, GalShaderType shaderType, bool isOutAttr = false) - { - int value = attr.Value; - - string swzMask = GetSwizzleMask((value >> 2) & 3); - - if (value >= AttributeConsts.UserAttributeBase && - value < AttributeConsts.UserAttributeEnd) - { - value -= AttributeConsts.UserAttributeBase; - - string prefix = isOutAttr - ? DefaultNames.OAttributePrefix - : DefaultNames.IAttributePrefix; - - string name = $"{prefix}{(value >> 4)}"; - - if (shaderType == GalShaderType.Geometry && !isOutAttr) - { - name += "[0]"; - } - - name += "." + swzMask; - - return name; - } - else - { - if (value >= AttributeConsts.FragmentOutputColorBase && - value < AttributeConsts.FragmentOutputColorEnd) - { - value -= AttributeConsts.FragmentOutputColorBase; - - return $"{DefaultNames.OAttributePrefix}{(value >> 4)}.{swzMask}"; - } - else if (_builtInAttributes.TryGetValue(value & ~3, out BuiltInAttribute builtInAttr)) - { - // TODO: There must be a better way to handle this... - if (shaderType == GalShaderType.Fragment) - { - switch (value & ~3) - { - case AttributeConsts.PositionX: return "gl_FragCoord.x"; - case AttributeConsts.PositionY: return "gl_FragCoord.y"; - case AttributeConsts.PositionZ: return "gl_FragCoord.z"; - case AttributeConsts.PositionW: return "1.0"; - } - } - - string name = builtInAttr.Name; - - if (shaderType == GalShaderType.Geometry && !isOutAttr) - { - name = "gl_in[0]." + name; - } - - return name; - } - } - - // TODO: Warn about unknown built-in attribute. - - return isOutAttr ? "// bad_attr0x" + value.ToString("X") : "0.0"; - } - - public static string GetUbName(GalShaderType shaderType, int slot) - { - string ubName = GetShaderStagePrefix(shaderType); - - ubName += "_" + DefaultNames.UniformNamePrefix + slot; - - return ubName + "_" + DefaultNames.UniformNameSuffix; - } - - public static string GetSamplerName(GalShaderType shaderType, AstTextureOperation texOp) - { - string suffix; - - if ((texOp.Flags & TextureFlags.Bindless) != 0) - { - AstOperand operand = texOp.GetSource(0) as AstOperand; - - suffix = "_cb" + operand.CbufSlot + "_" + operand.CbufOffset; - } - else - { - suffix = (texOp.Handle - 8).ToString(); - } - - return GetShaderStagePrefix(shaderType) + "_" + DefaultNames.SamplerNamePrefix + suffix; - } - - public static string GetShaderStagePrefix(GalShaderType shaderType) - { - return _stagePrefixes[(int)shaderType]; - } - - private static string GetSwizzleMask(int value) - { - return "xyzw".Substring(value, 1); - } - - public static VariableType GetNodeDestType(IAstNode node) - { - if (node is AstOperation operation) - { - return GetDestVarType(operation.Inst); - } - else if (node is AstOperand operand) - { - if (operand.Type == OperandType.Attribute) - { - if (_builtInAttributes.TryGetValue(operand.Value & ~3, out BuiltInAttribute builtInAttr)) - { - return builtInAttr.Type; - } - } - - return OperandInfo.GetVarType(operand); - } - else - { - throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\"."); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/TypeConversion.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/TypeConversion.cs deleted file mode 100644 index 7adc5ad3..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/TypeConversion.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using System; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - static class TypeConversion - { - public static string ReinterpretCast( - CodeGenContext context, - IAstNode node, - VariableType srcType, - VariableType dstType) - { - if (node is AstOperand operand && operand.Type == OperandType.Constant) - { - if (NumberFormatter.TryFormat(operand.Value, dstType, out string formatted)) - { - return formatted; - } - } - - string expr = InstGen.GetExpression(context, node); - - return ReinterpretCast(expr, node, srcType, dstType); - } - - private static string ReinterpretCast(string expr, IAstNode node, VariableType srcType, VariableType dstType) - { - if (srcType == dstType) - { - return expr; - } - - if (srcType == VariableType.F32) - { - switch (dstType) - { - case VariableType.S32: return $"floatBitsToInt({expr})"; - case VariableType.U32: return $"floatBitsToUint({expr})"; - } - } - else if (dstType == VariableType.F32) - { - switch (srcType) - { - case VariableType.Bool: return $"intBitsToFloat({ReinterpretBoolToInt(expr, node, VariableType.S32)})"; - case VariableType.S32: return $"intBitsToFloat({expr})"; - case VariableType.U32: return $"uintBitsToFloat({expr})"; - } - } - else if (srcType == VariableType.Bool) - { - return ReinterpretBoolToInt(expr, node, dstType); - } - else if (dstType == VariableType.Bool) - { - expr = InstGenHelper.Enclose(expr, node, Instruction.CompareNotEqual, isLhs: true); - - return $"({expr} != 0)"; - } - else if (dstType == VariableType.S32) - { - return $"int({expr})"; - } - else if (dstType == VariableType.U32) - { - return $"uint({expr})"; - } - - throw new ArgumentException($"Invalid reinterpret cast from \"{srcType}\" to \"{dstType}\"."); - } - - private static string ReinterpretBoolToInt(string expr, IAstNode node, VariableType dstType) - { - string trueExpr = NumberFormatter.FormatInt(IrConsts.True, dstType); - string falseExpr = NumberFormatter.FormatInt(IrConsts.False, dstType); - - expr = InstGenHelper.Enclose(expr, node, Instruction.ConditionalSelect, isLhs: false); - - return $"({expr} ? {trueExpr} : {falseExpr})"; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/BitfieldExtensions.cs b/Ryujinx.Graphics/Shader/Decoders/BitfieldExtensions.cs deleted file mode 100644 index 3bb9bc1f..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/BitfieldExtensions.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - static class BitfieldExtensions - { - public static bool Extract(this int value, int lsb) - { - return ((int)(value >> lsb) & 1) != 0; - } - - public static int Extract(this int value, int lsb, int length) - { - return (int)(value >> lsb) & (int)(uint.MaxValue >> (32 - length)); - } - - public static bool Extract(this long value, int lsb) - { - return ((int)(value >> lsb) & 1) != 0; - } - - public static int Extract(this long value, int lsb, int length) - { - return (int)(value >> lsb) & (int)(uint.MaxValue >> (32 - length)); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/Block.cs b/Ryujinx.Graphics/Shader/Decoders/Block.cs deleted file mode 100644 index b5e610d7..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/Block.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class Block - { - public ulong Address { get; set; } - public ulong EndAddress { get; set; } - - public Block Next { get; set; } - public Block Branch { get; set; } - - public List<OpCode> OpCodes { get; } - public List<OpCodeSsy> SsyOpCodes { get; } - - public Block(ulong address) - { - Address = address; - - OpCodes = new List<OpCode>(); - SsyOpCodes = new List<OpCodeSsy>(); - } - - public void Split(Block rightBlock) - { - int splitIndex = BinarySearch(OpCodes, rightBlock.Address); - - if (OpCodes[splitIndex].Address < rightBlock.Address) - { - splitIndex++; - } - - int splitCount = OpCodes.Count - splitIndex; - - if (splitCount <= 0) - { - throw new ArgumentException("Can't split at right block address."); - } - - rightBlock.EndAddress = EndAddress; - - rightBlock.Next = Next; - rightBlock.Branch = Branch; - - rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount)); - - rightBlock.UpdateSsyOpCodes(); - - EndAddress = rightBlock.Address; - - Next = rightBlock; - Branch = null; - - OpCodes.RemoveRange(splitIndex, splitCount); - - UpdateSsyOpCodes(); - } - - private static int BinarySearch(List<OpCode> opCodes, ulong address) - { - int left = 0; - int middle = 0; - int right = opCodes.Count - 1; - - while (left <= right) - { - int size = right - left; - - middle = left + (size >> 1); - - OpCode opCode = opCodes[middle]; - - if (address == opCode.Address) - { - break; - } - - if (address < opCode.Address) - { - right = middle - 1; - } - else - { - left = middle + 1; - } - } - - return middle; - } - - public OpCode GetLastOp() - { - if (OpCodes.Count != 0) - { - return OpCodes[OpCodes.Count - 1]; - } - - return null; - } - - public void UpdateSsyOpCodes() - { - SsyOpCodes.Clear(); - - for (int index = 0; index < OpCodes.Count; index++) - { - if (!(OpCodes[index] is OpCodeSsy op)) - { - continue; - } - - SsyOpCodes.Add(op); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/Condition.cs b/Ryujinx.Graphics/Shader/Decoders/Condition.cs deleted file mode 100644 index 10400f94..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/Condition.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum Condition - { - Less = 1 << 0, - Equal = 1 << 1, - Greater = 1 << 2, - Nan = 1 << 3, - Unsigned = 1 << 4, - - Never = 0, - - LessOrEqual = Less | Equal, - NotEqual = Less | Greater, - GreaterOrEqual = Greater | Equal, - Number = Greater | Equal | Less, - - LessUnordered = Less | Nan, - EqualUnordered = Equal | Nan, - LessOrEqualUnordered = LessOrEqual | Nan, - GreaterUnordered = Greater | Nan, - NotEqualUnordered = NotEqual | Nan, - GreaterOrEqualUnordered = GreaterOrEqual | Nan, - - Always = 0xf, - - Off = Unsigned | Never, - Lower = Unsigned | Less, - Sff = Unsigned | Equal, - LowerOrSame = Unsigned | LessOrEqual, - Higher = Unsigned | Greater, - Sft = Unsigned | NotEqual, - HigherOrSame = Unsigned | GreaterOrEqual, - Oft = Unsigned | Always, - - CsmTa = 0x18, - CsmTr = 0x19, - CsmMx = 0x1a, - FcsmTa = 0x1b, - FcsmTr = 0x1c, - FcsmMx = 0x1d, - Rle = 0x1e, - Rgt = 0x1f - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/ConditionalOperation.cs b/Ryujinx.Graphics/Shader/Decoders/ConditionalOperation.cs deleted file mode 100644 index 4fc31e84..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/ConditionalOperation.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum ConditionalOperation - { - False = 0, - True = 1, - Zero = 2, - NotZero = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/Decoder.cs b/Ryujinx.Graphics/Shader/Decoders/Decoder.cs deleted file mode 100644 index 754e0388..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/Decoder.cs +++ /dev/null @@ -1,406 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.Instructions; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Reflection.Emit; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - static class Decoder - { - private const long HeaderSize = 0x50; - - private delegate object OpActivator(InstEmitter emitter, ulong address, long opCode); - - private static ConcurrentDictionary<Type, OpActivator> _opActivators; - - static Decoder() - { - _opActivators = new ConcurrentDictionary<Type, OpActivator>(); - } - - public static Block[] Decode(IGalMemory memory, ulong address) - { - List<Block> blocks = new List<Block>(); - - Queue<Block> workQueue = new Queue<Block>(); - - Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>(); - - Block GetBlock(ulong blkAddress) - { - if (!visited.TryGetValue(blkAddress, out Block block)) - { - block = new Block(blkAddress); - - workQueue.Enqueue(block); - - visited.Add(blkAddress, block); - } - - return block; - } - - ulong startAddress = address + HeaderSize; - - GetBlock(startAddress); - - while (workQueue.TryDequeue(out Block currBlock)) - { - // Check if the current block is inside another block. - if (BinarySearch(blocks, currBlock.Address, out int nBlkIndex)) - { - Block nBlock = blocks[nBlkIndex]; - - if (nBlock.Address == currBlock.Address) - { - throw new InvalidOperationException("Found duplicate block address on the list."); - } - - nBlock.Split(currBlock); - - blocks.Insert(nBlkIndex + 1, currBlock); - - continue; - } - - // If we have a block after the current one, set the limit address. - ulong limitAddress = ulong.MaxValue; - - if (nBlkIndex != blocks.Count) - { - Block nBlock = blocks[nBlkIndex]; - - int nextIndex = nBlkIndex + 1; - - if (nBlock.Address < currBlock.Address && nextIndex < blocks.Count) - { - limitAddress = blocks[nextIndex].Address; - } - else if (nBlock.Address > currBlock.Address) - { - limitAddress = blocks[nBlkIndex].Address; - } - } - - FillBlock(memory, currBlock, limitAddress, startAddress); - - if (currBlock.OpCodes.Count != 0) - { - foreach (OpCodeSsy ssyOp in currBlock.SsyOpCodes) - { - GetBlock(ssyOp.GetAbsoluteAddress()); - } - - // Set child blocks. "Branch" is the block the branch instruction - // points to (when taken), "Next" is the block at the next address, - // executed when the branch is not taken. For Unconditional Branches - // or end of program, Next is null. - OpCode lastOp = currBlock.GetLastOp(); - - if (lastOp is OpCodeBranch op) - { - currBlock.Branch = GetBlock(op.GetAbsoluteAddress()); - } - - if (!IsUnconditionalBranch(lastOp)) - { - currBlock.Next = GetBlock(currBlock.EndAddress); - } - } - - // Insert the new block on the list (sorted by address). - if (blocks.Count != 0) - { - Block nBlock = blocks[nBlkIndex]; - - blocks.Insert(nBlkIndex + (nBlock.Address < currBlock.Address ? 1 : 0), currBlock); - } - else - { - blocks.Add(currBlock); - } - } - - foreach (Block ssyBlock in blocks.Where(x => x.SsyOpCodes.Count != 0)) - { - for (int ssyIndex = 0; ssyIndex < ssyBlock.SsyOpCodes.Count; ssyIndex++) - { - PropagateSsy(visited, ssyBlock, ssyIndex); - } - } - - return blocks.ToArray(); - } - - private static bool BinarySearch(List<Block> blocks, ulong address, out int index) - { - index = 0; - - int left = 0; - int right = blocks.Count - 1; - - while (left <= right) - { - int size = right - left; - - int middle = left + (size >> 1); - - Block block = blocks[middle]; - - index = middle; - - if (address >= block.Address && address < block.EndAddress) - { - return true; - } - - if (address < block.Address) - { - right = middle - 1; - } - else - { - left = middle + 1; - } - } - - return false; - } - - private static void FillBlock( - IGalMemory memory, - Block block, - ulong limitAddress, - ulong startAddress) - { - ulong address = block.Address; - - do - { - if (address >= limitAddress) - { - break; - } - - // Ignore scheduling instructions, which are written every 32 bytes. - if (((address - startAddress) & 0x1f) == 0) - { - address += 8; - - continue; - } - - uint word0 = (uint)memory.ReadInt32((long)(address + 0)); - uint word1 = (uint)memory.ReadInt32((long)(address + 4)); - - ulong opAddress = address; - - address += 8; - - long opCode = word0 | (long)word1 << 32; - - (InstEmitter emitter, Type opCodeType) = OpCodeTable.GetEmitter(opCode); - - if (emitter == null) - { - // TODO: Warning, illegal encoding. - continue; - } - - OpCode op = MakeOpCode(opCodeType, emitter, opAddress, opCode); - - block.OpCodes.Add(op); - } - while (!IsBranch(block.GetLastOp())); - - block.EndAddress = address; - - block.UpdateSsyOpCodes(); - } - - private static bool IsUnconditionalBranch(OpCode opCode) - { - return IsUnconditional(opCode) && IsBranch(opCode); - } - - private static bool IsUnconditional(OpCode opCode) - { - if (opCode is OpCodeExit op && op.Condition != Condition.Always) - { - return false; - } - - return opCode.Predicate.Index == RegisterConsts.PredicateTrueIndex && !opCode.InvertPredicate; - } - - private static bool IsBranch(OpCode opCode) - { - return (opCode is OpCodeBranch && opCode.Emitter != InstEmit.Ssy) || - opCode is OpCodeSync || - opCode is OpCodeExit; - } - - private static OpCode MakeOpCode(Type type, InstEmitter emitter, ulong address, long opCode) - { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } - - OpActivator createInstance = _opActivators.GetOrAdd(type, CacheOpActivator); - - return (OpCode)createInstance(emitter, address, opCode); - } - - private static OpActivator CacheOpActivator(Type type) - { - Type[] argTypes = new Type[] { typeof(InstEmitter), typeof(ulong), typeof(long) }; - - DynamicMethod mthd = new DynamicMethod($"Make{type.Name}", type, argTypes); - - ILGenerator generator = mthd.GetILGenerator(); - - generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Ldarg_1); - generator.Emit(OpCodes.Ldarg_2); - generator.Emit(OpCodes.Newobj, type.GetConstructor(argTypes)); - generator.Emit(OpCodes.Ret); - - return (OpActivator)mthd.CreateDelegate(typeof(OpActivator)); - } - - private struct PathBlockState - { - public Block Block { get; } - - private enum RestoreType - { - None, - PopSsy, - PushSync - } - - private RestoreType _restoreType; - - private ulong _restoreValue; - - public bool ReturningFromVisit => _restoreType != RestoreType.None; - - public PathBlockState(Block block) - { - Block = block; - _restoreType = RestoreType.None; - _restoreValue = 0; - } - - public PathBlockState(int oldSsyStackSize) - { - Block = null; - _restoreType = RestoreType.PopSsy; - _restoreValue = (ulong)oldSsyStackSize; - } - - public PathBlockState(ulong syncAddress) - { - Block = null; - _restoreType = RestoreType.PushSync; - _restoreValue = syncAddress; - } - - public void RestoreStackState(Stack<ulong> ssyStack) - { - if (_restoreType == RestoreType.PushSync) - { - ssyStack.Push(_restoreValue); - } - else if (_restoreType == RestoreType.PopSsy) - { - while (ssyStack.Count > (uint)_restoreValue) - { - ssyStack.Pop(); - } - } - } - } - - private static void PropagateSsy(Dictionary<ulong, Block> blocks, Block ssyBlock, int ssyIndex) - { - OpCodeSsy ssyOp = ssyBlock.SsyOpCodes[ssyIndex]; - - Stack<PathBlockState> workQueue = new Stack<PathBlockState>(); - - HashSet<Block> visited = new HashSet<Block>(); - - Stack<ulong> ssyStack = new Stack<ulong>(); - - void Push(PathBlockState pbs) - { - if (pbs.Block == null || visited.Add(pbs.Block)) - { - workQueue.Push(pbs); - } - } - - Push(new PathBlockState(ssyBlock)); - - while (workQueue.TryPop(out PathBlockState pbs)) - { - if (pbs.ReturningFromVisit) - { - pbs.RestoreStackState(ssyStack); - - continue; - } - - Block current = pbs.Block; - - int ssyOpCodesCount = current.SsyOpCodes.Count; - - if (ssyOpCodesCount != 0) - { - Push(new PathBlockState(ssyStack.Count)); - - for (int index = ssyIndex; index < ssyOpCodesCount; index++) - { - ssyStack.Push(current.SsyOpCodes[index].GetAbsoluteAddress()); - } - } - - ssyIndex = 0; - - if (current.Next != null) - { - Push(new PathBlockState(current.Next)); - } - - if (current.Branch != null) - { - Push(new PathBlockState(current.Branch)); - } - else if (current.GetLastOp() is OpCodeSync op) - { - ulong syncAddress = ssyStack.Pop(); - - if (ssyStack.Count == 0) - { - ssyStack.Push(syncAddress); - - op.Targets.Add(ssyOp, op.Targets.Count); - - ssyOp.Syncs.TryAdd(op, Local()); - } - else - { - Push(new PathBlockState(syncAddress)); - Push(new PathBlockState(blocks[syncAddress])); - } - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/DecoderHelper.cs b/Ryujinx.Graphics/Shader/Decoders/DecoderHelper.cs deleted file mode 100644 index fd0a45e8..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/DecoderHelper.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - static class DecoderHelper - { - public static int DecodeS20Immediate(long opCode) - { - int imm = opCode.Extract(20, 19); - - bool negate = opCode.Extract(56); - - if (negate) - { - imm = -imm; - } - - return imm; - } - - public static int Decode2xF10Immediate(long opCode) - { - int immH0 = opCode.Extract(20, 9); - int immH1 = opCode.Extract(30, 9); - - bool negateH0 = opCode.Extract(29); - bool negateH1 = opCode.Extract(56); - - if (negateH0) - { - immH0 |= 1 << 9; - } - - if (negateH1) - { - immH1 |= 1 << 9; - } - - return immH1 << 22 | immH0 << 6; - } - - public static float DecodeF20Immediate(long opCode) - { - int imm = opCode.Extract(20, 19); - - bool negate = opCode.Extract(56); - - imm <<= 12; - - if (negate) - { - imm |= 1 << 31; - } - - return BitConverter.Int32BitsToSingle(imm); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/FPHalfSwizzle.cs b/Ryujinx.Graphics/Shader/Decoders/FPHalfSwizzle.cs deleted file mode 100644 index 3ddf17cf..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/FPHalfSwizzle.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum FPHalfSwizzle - { - FP16 = 0, - FP32 = 1, - DupH0 = 2, - DupH1 = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/FPType.cs b/Ryujinx.Graphics/Shader/Decoders/FPType.cs deleted file mode 100644 index e602ad45..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/FPType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum FPType - { - FP16 = 1, - FP32 = 2, - FP64 = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/FmulScale.cs b/Ryujinx.Graphics/Shader/Decoders/FmulScale.cs deleted file mode 100644 index c35c6e48..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/FmulScale.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum FmulScale - { - None = 0, - Divide2 = 1, - Divide4 = 2, - Divide8 = 3, - Multiply8 = 4, - Multiply4 = 5, - Multiply2 = 6 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCode.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCode.cs deleted file mode 100644 index dd6ad79a..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCode.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCode - { - InstEmitter Emitter { get; } - - ulong Address { get; } - long RawOpCode { get; } - - Register Predicate { get; } - - bool InvertPredicate { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeAlu.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeAlu.cs deleted file mode 100644 index d840d49d..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeAlu.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeAlu : IOpCodeRd, IOpCodeRa - { - Register Predicate39 { get; } - - bool InvertP { get; } - bool Extended { get; } - bool SetCondCode { get; } - bool Saturate { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeCbuf.cs deleted file mode 100644 index 42a17451..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeCbuf.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeCbuf : IOpCode - { - int Offset { get; } - int Slot { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeFArith.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeFArith.cs deleted file mode 100644 index d68ccf59..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeFArith.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeFArith : IOpCodeAlu - { - RoundingMode RoundingMode { get; } - - FmulScale Scale { get; } - - bool FlushToZero { get; } - bool AbsoluteA { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeHfma.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeHfma.cs deleted file mode 100644 index 4638f660..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeHfma.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeHfma : IOpCode - { - bool NegateB { get; } - bool NegateC { get; } - bool Saturate { get; } - - FPHalfSwizzle SwizzleA { get; } - FPHalfSwizzle SwizzleB { get; } - FPHalfSwizzle SwizzleC { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeImm.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeImm.cs deleted file mode 100644 index 9cfcd69b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeImm.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeImm : IOpCode - { - int Immediate { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeImmF.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeImmF.cs deleted file mode 100644 index 629eff79..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeImmF.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeImmF : IOpCode - { - float Immediate { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeLop.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeLop.cs deleted file mode 100644 index 62c87bf4..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeLop.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeLop : IOpCodeAlu - { - LogicalOperation LogicalOp { get; } - - bool InvertA { get; } - bool InvertB { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRa.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeRa.cs deleted file mode 100644 index e5902110..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRa.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeRa : IOpCode - { - Register Ra { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRc.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeRc.cs deleted file mode 100644 index bb806b95..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRc.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeRc : IOpCode - { - Register Rc { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRd.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeRd.cs deleted file mode 100644 index 099c4061..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRd.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeRd : IOpCode - { - Register Rd { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeReg.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeReg.cs deleted file mode 100644 index 3ed157e8..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeReg.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeReg : IOpCode - { - Register Rb { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRegCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeRegCbuf.cs deleted file mode 100644 index 429f01bb..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRegCbuf.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeRegCbuf : IOpCodeRc - { - int Offset { get; } - int Slot { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IntegerCondition.cs b/Ryujinx.Graphics/Shader/Decoders/IntegerCondition.cs deleted file mode 100644 index a1937c2f..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IntegerCondition.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum IntegerCondition - { - Less = 1 << 0, - Equal = 1 << 1, - Greater = 1 << 2, - - Never = 0, - - LessOrEqual = Less | Equal, - NotEqual = Less | Greater, - GreaterOrEqual = Greater | Equal, - Number = Greater | Equal | Less, - - Always = 7 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IntegerHalfPart.cs b/Ryujinx.Graphics/Shader/Decoders/IntegerHalfPart.cs deleted file mode 100644 index b779f44d..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IntegerHalfPart.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum IntegerHalfPart - { - B32 = 0, - H0 = 1, - H1 = 2 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IntegerShift.cs b/Ryujinx.Graphics/Shader/Decoders/IntegerShift.cs deleted file mode 100644 index ce4d9f3b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IntegerShift.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum IntegerShift - { - NoShift = 0, - ShiftRight = 1, - ShiftLeft = 2 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IntegerSize.cs b/Ryujinx.Graphics/Shader/Decoders/IntegerSize.cs deleted file mode 100644 index 70fdfc3d..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IntegerSize.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum IntegerSize - { - U8 = 0, - S8 = 1, - U16 = 2, - S16 = 3, - B32 = 4, - B64 = 5 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IntegerType.cs b/Ryujinx.Graphics/Shader/Decoders/IntegerType.cs deleted file mode 100644 index 46734dbe..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IntegerType.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum IntegerType - { - U8 = 0, - U16 = 1, - U32 = 2, - U64 = 3, - S8 = 4, - S16 = 5, - S32 = 6, - S64 = 7 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/LogicalOperation.cs b/Ryujinx.Graphics/Shader/Decoders/LogicalOperation.cs deleted file mode 100644 index 52214425..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/LogicalOperation.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum LogicalOperation - { - And = 0, - Or = 1, - ExclusiveOr = 2, - Passthrough = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/MufuOperation.cs b/Ryujinx.Graphics/Shader/Decoders/MufuOperation.cs deleted file mode 100644 index 88bd1f5c..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/MufuOperation.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum MufuOperation - { - Cosine = 0, - Sine = 1, - ExponentB2 = 2, - LogarithmB2 = 3, - Reciprocal = 4, - ReciprocalSquareRoot = 5, - Reciprocal64H = 6, - ReciprocalSquareRoot64H = 7, - SquareRoot = 8 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCode.cs b/Ryujinx.Graphics/Shader/Decoders/OpCode.cs deleted file mode 100644 index 94af49e0..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCode.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCode - { - public InstEmitter Emitter { get; } - - public ulong Address { get; } - public long RawOpCode { get; } - - public Register Predicate { get; protected set; } - - public bool InvertPredicate { get; protected set; } - - // When inverted, the always true predicate == always false. - public bool NeverExecute => Predicate.Index == RegisterConsts.PredicateTrueIndex && InvertPredicate; - - public OpCode(InstEmitter emitter, ulong address, long opCode) - { - Emitter = emitter; - Address = address; - RawOpCode = opCode; - - Predicate = new Register(opCode.Extract(16, 3), RegisterType.Predicate); - - InvertPredicate = opCode.Extract(19); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAlu.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAlu.cs deleted file mode 100644 index 15fbb9af..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAlu.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAlu : OpCode, IOpCodeAlu, IOpCodeRc - { - public Register Rd { get; } - public Register Ra { get; } - public Register Rc { get; } - public Register Predicate39 { get; } - - public int ByteSelection { get; } - - public bool InvertP { get; } - public bool Extended { get; protected set; } - public bool SetCondCode { get; protected set; } - public bool Saturate { get; protected set; } - - public OpCodeAlu(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr); - Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); - Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr); - Predicate39 = new Register(opCode.Extract(39, 3), RegisterType.Predicate); - - ByteSelection = opCode.Extract(41, 2); - - InvertP = opCode.Extract(42); - Extended = opCode.Extract(43); - SetCondCode = opCode.Extract(47); - Saturate = opCode.Extract(50); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluCbuf.cs deleted file mode 100644 index 9c127989..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluCbuf.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluCbuf : OpCodeAlu, IOpCodeCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeAluCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm.cs deleted file mode 100644 index a407fc6b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluImm : OpCodeAlu, IOpCodeImm - { - public int Immediate { get; } - - public OpCodeAluImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.DecodeS20Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm2x10.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm2x10.cs deleted file mode 100644 index 9aeb32bd..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm2x10.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluImm2x10 : OpCodeAlu, IOpCodeImm - { - public int Immediate { get; } - - public OpCodeAluImm2x10(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.Decode2xF10Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm32.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm32.cs deleted file mode 100644 index 5941e0b9..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm32.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluImm32 : OpCodeAlu, IOpCodeImm - { - public int Immediate { get; } - - public OpCodeAluImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = opCode.Extract(20, 32); - - SetCondCode = opCode.Extract(52); - Extended = opCode.Extract(53); - Saturate = opCode.Extract(54); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluReg.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluReg.cs deleted file mode 100644 index 13b96a3a..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluReg.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluReg : OpCodeAlu, IOpCodeReg - { - public Register Rb { get; protected set; } - - public OpCodeAluReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluRegCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluRegCbuf.cs deleted file mode 100644 index 6cf6bd2e..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluRegCbuf.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluRegCbuf : OpCodeAluReg, IOpCodeRegCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeAluRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - - Rb = new Register(opCode.Extract(39, 8), RegisterType.Gpr); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAttribute.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAttribute.cs deleted file mode 100644 index fd8e63fc..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAttribute.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAttribute : OpCodeAluReg - { - public int AttributeOffset { get; } - public int Count { get; } - - public OpCodeAttribute(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - AttributeOffset = opCode.Extract(20, 10); - Count = opCode.Extract(47, 2) + 1; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeBranch.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeBranch.cs deleted file mode 100644 index 25941b39..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeBranch.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeBranch : OpCode - { - public int Offset { get; } - - public OpCodeBranch(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = ((int)(opCode >> 20) << 8) >> 8; - } - - public ulong GetAbsoluteAddress() - { - return (ulong)((long)Address + (long)Offset + 8); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs deleted file mode 100644 index d50903eb..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeExit : OpCode - { - public Condition Condition { get; } - - public OpCodeExit(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Condition = (Condition)opCode.Extract(0, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArith.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArith.cs deleted file mode 100644 index c88f7f0e..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArith.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArith : OpCodeAlu, IOpCodeFArith - { - public RoundingMode RoundingMode { get; } - - public FmulScale Scale { get; } - - public bool FlushToZero { get; } - public bool AbsoluteA { get; } - - public OpCodeFArith(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - RoundingMode = (RoundingMode)opCode.Extract(39, 2); - - Scale = (FmulScale)opCode.Extract(41, 3); - - FlushToZero = opCode.Extract(44); - AbsoluteA = opCode.Extract(46); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithCbuf.cs deleted file mode 100644 index 5486bb0b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithCbuf.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArithCbuf : OpCodeFArith, IOpCodeCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeFArithCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm.cs deleted file mode 100644 index 1bb6f425..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArithImm : OpCodeFArith, IOpCodeImmF - { - public float Immediate { get; } - - public OpCodeFArithImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.DecodeF20Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm32.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm32.cs deleted file mode 100644 index ec9da6f3..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm32.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; -using System; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArithImm32 : OpCodeAlu, IOpCodeFArith, IOpCodeImmF - { - public RoundingMode RoundingMode => RoundingMode.ToNearest; - - public FmulScale Scale => FmulScale.None; - - public bool FlushToZero { get; } - public bool AbsoluteA { get; } - - public float Immediate { get; } - - public OpCodeFArithImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - int imm = opCode.Extract(20, 32); - - Immediate = BitConverter.Int32BitsToSingle(imm); - - SetCondCode = opCode.Extract(52); - AbsoluteA = opCode.Extract(54); - FlushToZero = opCode.Extract(55); - - Saturate = false; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithReg.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithReg.cs deleted file mode 100644 index 55cf4485..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithReg.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArithReg : OpCodeFArith, IOpCodeReg - { - public Register Rb { get; protected set; } - - public OpCodeFArithReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithRegCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithRegCbuf.cs deleted file mode 100644 index 315c2c8b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithRegCbuf.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArithRegCbuf : OpCodeFArith, IOpCodeRegCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeFArithRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFsetImm.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFsetImm.cs deleted file mode 100644 index cb5f155e..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFsetImm.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFsetImm : OpCodeSet, IOpCodeImmF - { - public float Immediate { get; } - - public OpCodeFsetImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.DecodeF20Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfma.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfma.cs deleted file mode 100644 index 32f3cd7a..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfma.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfma : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeRc - { - public Register Rd { get; } - public Register Ra { get; } - public Register Rc { get; protected set; } - - public FPHalfSwizzle SwizzleA { get; } - - public OpCodeHfma(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr); - Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); - Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr); - - SwizzleA = (FPHalfSwizzle)opCode.Extract(47, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaCbuf.cs deleted file mode 100644 index 33768c7d..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaCbuf.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfmaCbuf : OpCodeHfma, IOpCodeHfma, IOpCodeCbuf - { - public int Offset { get; } - public int Slot { get; } - - public bool NegateB { get; } - public bool NegateC { get; } - public bool Saturate { get; } - - public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP32; - public FPHalfSwizzle SwizzleC { get; } - - public OpCodeHfmaCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - - NegateC = opCode.Extract(51); - Saturate = opCode.Extract(52); - - SwizzleC = (FPHalfSwizzle)opCode.Extract(53, 2); - - NegateB = opCode.Extract(56); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm2x10.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm2x10.cs deleted file mode 100644 index 80a5a140..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm2x10.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfmaImm2x10 : OpCodeHfma, IOpCodeHfma, IOpCodeImm - { - public int Immediate { get; } - - public bool NegateB => false; - public bool NegateC { get; } - public bool Saturate { get; } - - public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP16; - public FPHalfSwizzle SwizzleC { get; } - - public OpCodeHfmaImm2x10(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.Decode2xF10Immediate(opCode); - - NegateC = opCode.Extract(51); - Saturate = opCode.Extract(52); - - SwizzleC = (FPHalfSwizzle)opCode.Extract(53, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm32.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm32.cs deleted file mode 100644 index 05eb9ffe..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm32.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfmaImm32 : OpCodeHfma, IOpCodeHfma, IOpCodeImm - { - public int Immediate { get; } - - public bool NegateB => false; - public bool NegateC { get; } - public bool Saturate => false; - - public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP16; - public FPHalfSwizzle SwizzleC => FPHalfSwizzle.FP16; - - public OpCodeHfmaImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = opCode.Extract(20, 32); - - NegateC = opCode.Extract(52); - - Rc = Rd; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaReg.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaReg.cs deleted file mode 100644 index 714c89de..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaReg.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfmaReg : OpCodeHfma, IOpCodeHfma, IOpCodeReg - { - public Register Rb { get; } - - public bool NegateB { get; } - public bool NegateC { get; } - public bool Saturate { get; } - - public FPHalfSwizzle SwizzleB { get; } - public FPHalfSwizzle SwizzleC { get; } - - public OpCodeHfmaReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - - SwizzleB = (FPHalfSwizzle)opCode.Extract(28, 2); - - NegateC = opCode.Extract(30); - NegateB = opCode.Extract(31); - Saturate = opCode.Extract(32); - - SwizzleC = (FPHalfSwizzle)opCode.Extract(35, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaRegCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaRegCbuf.cs deleted file mode 100644 index c0001908..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaRegCbuf.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfmaRegCbuf : OpCodeHfma, IOpCodeHfma, IOpCodeRegCbuf - { - public int Offset { get; } - public int Slot { get; } - - public bool NegateB { get; } - public bool NegateC { get; } - public bool Saturate { get; } - - public FPHalfSwizzle SwizzleB { get; } - public FPHalfSwizzle SwizzleC => FPHalfSwizzle.FP32; - - public OpCodeHfmaRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - - NegateC = opCode.Extract(51); - Saturate = opCode.Extract(52); - - SwizzleB = (FPHalfSwizzle)opCode.Extract(53, 2); - - NegateB = opCode.Extract(56); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeIpa.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeIpa.cs deleted file mode 100644 index e21095a3..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeIpa.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeIpa : OpCodeAluReg - { - public int AttributeOffset { get; } - - public OpCodeIpa(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - AttributeOffset = opCode.Extract(28, 10); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLdc.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLdc.cs deleted file mode 100644 index cc9f0658..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLdc.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLdc : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeCbuf - { - public Register Rd { get; } - public Register Ra { get; } - - public int Offset { get; } - public int Slot { get; } - - public IntegerSize Size { get; } - - public OpCodeLdc(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr); - Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); - - Offset = opCode.Extract(22, 14); - Slot = opCode.Extract(36, 5); - - Size = (IntegerSize)opCode.Extract(48, 3); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLop.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLop.cs deleted file mode 100644 index c5f90345..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLop.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLop : OpCodeAlu, IOpCodeLop - { - public bool InvertA { get; protected set; } - public bool InvertB { get; protected set; } - - public LogicalOperation LogicalOp { get; } - - public ConditionalOperation CondOp { get; } - - public Register Predicate48 { get; } - - public OpCodeLop(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - InvertA = opCode.Extract(39); - InvertB = opCode.Extract(40); - - LogicalOp = (LogicalOperation)opCode.Extract(41, 2); - - CondOp = (ConditionalOperation)opCode.Extract(44, 2); - - Predicate48 = new Register(opCode.Extract(48, 3), RegisterType.Predicate); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLopCbuf.cs deleted file mode 100644 index f174733c..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopCbuf.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLopCbuf : OpCodeLop, IOpCodeCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeLopCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm.cs deleted file mode 100644 index a2f091a2..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLopImm : OpCodeLop, IOpCodeImm - { - public int Immediate { get; } - - public OpCodeLopImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.DecodeS20Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm32.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm32.cs deleted file mode 100644 index cb48f3a6..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm32.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLopImm32 : OpCodeAluImm32, IOpCodeLop, IOpCodeImm - { - public LogicalOperation LogicalOp { get; } - - public bool InvertA { get; } - public bool InvertB { get; } - - public OpCodeLopImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - LogicalOp = (LogicalOperation)opCode.Extract(53, 2); - - InvertA = opCode.Extract(55); - InvertB = opCode.Extract(56); - - Extended = opCode.Extract(57); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopReg.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLopReg.cs deleted file mode 100644 index 5f43db72..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopReg.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLopReg : OpCodeLop, IOpCodeReg - { - public Register Rb { get; } - - public OpCodeLopReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodePsetp.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodePsetp.cs deleted file mode 100644 index 729e3207..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodePsetp.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodePsetp : OpCodeSet - { - public Register Predicate12 { get; } - public Register Predicate29 { get; } - - public LogicalOperation LogicalOpAB { get; } - - public OpCodePsetp(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Predicate12 = new Register(opCode.Extract(12, 3), RegisterType.Predicate); - Predicate29 = new Register(opCode.Extract(29, 3), RegisterType.Predicate); - - LogicalOpAB = (LogicalOperation)opCode.Extract(24, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSet.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSet.cs deleted file mode 100644 index cd6773a1..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSet.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSet : OpCodeAlu - { - public Register Predicate0 { get; } - public Register Predicate3 { get; } - - public bool NegateP { get; } - - public LogicalOperation LogicalOp { get; } - - public bool FlushToZero { get; } - - public OpCodeSet(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Predicate0 = new Register(opCode.Extract(0, 3), RegisterType.Predicate); - Predicate3 = new Register(opCode.Extract(3, 3), RegisterType.Predicate); - - LogicalOp = (LogicalOperation)opCode.Extract(45, 2); - - FlushToZero = opCode.Extract(47); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSetCbuf.cs deleted file mode 100644 index 4f3dbd74..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetCbuf.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSetCbuf : OpCodeSet, IOpCodeCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeSetCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetImm.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSetImm.cs deleted file mode 100644 index bc63b9f4..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetImm.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSetImm : OpCodeSet, IOpCodeImm - { - public int Immediate { get; } - - public OpCodeSetImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.DecodeS20Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetReg.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSetReg.cs deleted file mode 100644 index bbdee196..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetReg.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSetReg : OpCodeSet, IOpCodeReg - { - public Register Rb { get; protected set; } - - public OpCodeSetReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSsy.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSsy.cs deleted file mode 100644 index 499c0706..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSsy.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSsy : OpCodeBranch - { - public Dictionary<OpCodeSync, Operand> Syncs { get; } - - public OpCodeSsy(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Syncs = new Dictionary<OpCodeSync, Operand>(); - - Predicate = new Register(RegisterConsts.PredicateTrueIndex, RegisterType.Predicate); - - InvertPredicate = false; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSync.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSync.cs deleted file mode 100644 index 081d08a0..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSync.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSync : OpCode - { - public Dictionary<OpCodeSsy, int> Targets { get; } - - public OpCodeSync(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Targets = new Dictionary<OpCodeSsy, int>(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTable.cs deleted file mode 100644 index d588ce8e..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTable.cs +++ /dev/null @@ -1,216 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; -using System; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - static class OpCodeTable - { - private const int EncodingBits = 14; - - private class TableEntry - { - public InstEmitter Emitter { get; } - - public Type OpCodeType { get; } - - public int XBits { get; } - - public TableEntry(InstEmitter emitter, Type opCodeType, int xBits) - { - Emitter = emitter; - OpCodeType = opCodeType; - XBits = xBits; - } - } - - private static TableEntry[] _opCodes; - - static OpCodeTable() - { - _opCodes = new TableEntry[1 << EncodingBits]; - -#region Instructions - Set("1110111111011x", InstEmit.Ald, typeof(OpCodeAttribute)); - Set("1110111111110x", InstEmit.Ast, typeof(OpCodeAttribute)); - Set("0100110000000x", InstEmit.Bfe, typeof(OpCodeAluCbuf)); - Set("0011100x00000x", InstEmit.Bfe, typeof(OpCodeAluImm)); - Set("0101110000000x", InstEmit.Bfe, typeof(OpCodeAluReg)); - Set("111000100100xx", InstEmit.Bra, typeof(OpCodeBranch)); - Set("111000110000xx", InstEmit.Exit, typeof(OpCodeExit)); - Set("0100110010101x", InstEmit.F2F, typeof(OpCodeFArithCbuf)); - Set("0011100x10101x", InstEmit.F2F, typeof(OpCodeFArithImm)); - Set("0101110010101x", InstEmit.F2F, typeof(OpCodeFArithReg)); - Set("0100110010110x", InstEmit.F2I, typeof(OpCodeFArithCbuf)); - Set("0011100x10110x", InstEmit.F2I, typeof(OpCodeFArithImm)); - Set("0101110010110x", InstEmit.F2I, typeof(OpCodeFArithReg)); - Set("0100110001011x", InstEmit.Fadd, typeof(OpCodeFArithCbuf)); - Set("0011100x01011x", InstEmit.Fadd, typeof(OpCodeFArithImm)); - Set("000010xxxxxxxx", InstEmit.Fadd, typeof(OpCodeFArithImm32)); - Set("0101110001011x", InstEmit.Fadd, typeof(OpCodeFArithReg)); - Set("010010011xxxxx", InstEmit.Ffma, typeof(OpCodeFArithCbuf)); - Set("0011001x1xxxxx", InstEmit.Ffma, typeof(OpCodeFArithImm)); - Set("010100011xxxxx", InstEmit.Ffma, typeof(OpCodeFArithRegCbuf)); - Set("010110011xxxxx", InstEmit.Ffma, typeof(OpCodeFArithReg)); - Set("0100110001100x", InstEmit.Fmnmx, typeof(OpCodeFArithCbuf)); - Set("0011100x01100x", InstEmit.Fmnmx, typeof(OpCodeFArithImm)); - Set("0101110001100x", InstEmit.Fmnmx, typeof(OpCodeFArithReg)); - Set("0100110001101x", InstEmit.Fmul, typeof(OpCodeFArithCbuf)); - Set("0011100x01101x", InstEmit.Fmul, typeof(OpCodeFArithImm)); - Set("00011110xxxxxx", InstEmit.Fmul, typeof(OpCodeFArithImm32)); - Set("0101110001101x", InstEmit.Fmul, typeof(OpCodeFArithReg)); - Set("0100100xxxxxxx", InstEmit.Fset, typeof(OpCodeSetCbuf)); - Set("0011000xxxxxxx", InstEmit.Fset, typeof(OpCodeFsetImm)); - Set("01011000xxxxxx", InstEmit.Fset, typeof(OpCodeSetReg)); - Set("010010111011xx", InstEmit.Fsetp, typeof(OpCodeSetCbuf)); - Set("0011011x1011xx", InstEmit.Fsetp, typeof(OpCodeFsetImm)); - Set("010110111011xx", InstEmit.Fsetp, typeof(OpCodeSetReg)); - Set("0111101x1xxxxx", InstEmit.Hadd2, typeof(OpCodeAluCbuf)); - Set("0111101x0xxxxx", InstEmit.Hadd2, typeof(OpCodeAluImm2x10)); - Set("0010110xxxxxxx", InstEmit.Hadd2, typeof(OpCodeAluImm32)); - Set("0101110100010x", InstEmit.Hadd2, typeof(OpCodeAluReg)); - Set("01110xxx1xxxxx", InstEmit.Hfma2, typeof(OpCodeHfmaCbuf)); - Set("01110xxx0xxxxx", InstEmit.Hfma2, typeof(OpCodeHfmaImm2x10)); - Set("0010100xxxxxxx", InstEmit.Hfma2, typeof(OpCodeHfmaImm32)); - Set("0101110100000x", InstEmit.Hfma2, typeof(OpCodeHfmaReg)); - Set("01100xxx1xxxxx", InstEmit.Hfma2, typeof(OpCodeHfmaRegCbuf)); - Set("0111100x1xxxxx", InstEmit.Hmul2, typeof(OpCodeAluCbuf)); - Set("0111100x0xxxxx", InstEmit.Hmul2, typeof(OpCodeAluImm2x10)); - Set("0010101xxxxxxx", InstEmit.Hmul2, typeof(OpCodeAluImm32)); - Set("0101110100001x", InstEmit.Hmul2, typeof(OpCodeAluReg)); - Set("0100110010111x", InstEmit.I2F, typeof(OpCodeAluCbuf)); - Set("0011100x10111x", InstEmit.I2F, typeof(OpCodeAluImm)); - Set("0101110010111x", InstEmit.I2F, typeof(OpCodeAluReg)); - Set("0100110011100x", InstEmit.I2I, typeof(OpCodeAluCbuf)); - Set("0011100x11100x", InstEmit.I2I, typeof(OpCodeAluImm)); - Set("0101110011100x", InstEmit.I2I, typeof(OpCodeAluReg)); - Set("0100110000010x", InstEmit.Iadd, typeof(OpCodeAluCbuf)); - Set("0011100000010x", InstEmit.Iadd, typeof(OpCodeAluImm)); - Set("0001110x0xxxxx", InstEmit.Iadd, typeof(OpCodeAluImm32)); - Set("0101110000010x", InstEmit.Iadd, typeof(OpCodeAluReg)); - Set("010011001100xx", InstEmit.Iadd3, typeof(OpCodeAluCbuf)); - Set("001110001100xx", InstEmit.Iadd3, typeof(OpCodeAluImm)); - Set("010111001100xx", InstEmit.Iadd3, typeof(OpCodeAluReg)); - Set("0100110000100x", InstEmit.Imnmx, typeof(OpCodeAluCbuf)); - Set("0011100x00100x", InstEmit.Imnmx, typeof(OpCodeAluImm)); - Set("0101110000100x", InstEmit.Imnmx, typeof(OpCodeAluReg)); - Set("11100000xxxxxx", InstEmit.Ipa, typeof(OpCodeIpa)); - Set("0100110000011x", InstEmit.Iscadd, typeof(OpCodeAluCbuf)); - Set("0011100x00011x", InstEmit.Iscadd, typeof(OpCodeAluImm)); - Set("000101xxxxxxxx", InstEmit.Iscadd, typeof(OpCodeAluImm32)); - Set("0101110000011x", InstEmit.Iscadd, typeof(OpCodeAluReg)); - Set("010010110101xx", InstEmit.Iset, typeof(OpCodeSetCbuf)); - Set("001101100101xx", InstEmit.Iset, typeof(OpCodeSetImm)); - Set("010110110101xx", InstEmit.Iset, typeof(OpCodeSetReg)); - Set("010010110110xx", InstEmit.Isetp, typeof(OpCodeSetCbuf)); - Set("0011011x0110xx", InstEmit.Isetp, typeof(OpCodeSetImm)); - Set("010110110110xx", InstEmit.Isetp, typeof(OpCodeSetReg)); - Set("111000110011xx", InstEmit.Kil, typeof(OpCodeExit)); - Set("1110111110010x", InstEmit.Ldc, typeof(OpCodeLdc)); - Set("0100110001000x", InstEmit.Lop, typeof(OpCodeLopCbuf)); - Set("0011100001000x", InstEmit.Lop, typeof(OpCodeLopImm)); - Set("000001xxxxxxxx", InstEmit.Lop, typeof(OpCodeLopImm32)); - Set("0101110001000x", InstEmit.Lop, typeof(OpCodeLopReg)); - Set("0010000xxxxxxx", InstEmit.Lop3, typeof(OpCodeLopCbuf)); - Set("001111xxxxxxxx", InstEmit.Lop3, typeof(OpCodeLopImm)); - Set("0101101111100x", InstEmit.Lop3, typeof(OpCodeLopReg)); - Set("0100110010011x", InstEmit.Mov, typeof(OpCodeAluCbuf)); - Set("0011100x10011x", InstEmit.Mov, typeof(OpCodeAluImm)); - Set("000000010000xx", InstEmit.Mov, typeof(OpCodeAluImm32)); - Set("0101110010011x", InstEmit.Mov, typeof(OpCodeAluReg)); - Set("0101000010000x", InstEmit.Mufu, typeof(OpCodeFArith)); - Set("1111101111100x", InstEmit.Out, typeof(OpCode)); - Set("0101000010010x", InstEmit.Psetp, typeof(OpCodePsetp)); - Set("0100110010010x", InstEmit.Rro, typeof(OpCodeFArithCbuf)); - Set("0011100x10010x", InstEmit.Rro, typeof(OpCodeFArithImm)); - Set("0101110010010x", InstEmit.Rro, typeof(OpCodeFArithReg)); - Set("0100110010100x", InstEmit.Sel, typeof(OpCodeAluCbuf)); - Set("0011100010100x", InstEmit.Sel, typeof(OpCodeAluImm)); - Set("0101110010100x", InstEmit.Sel, typeof(OpCodeAluReg)); - Set("0100110001001x", InstEmit.Shl, typeof(OpCodeAluCbuf)); - Set("0011100x01001x", InstEmit.Shl, typeof(OpCodeAluImm)); - Set("0101110001001x", InstEmit.Shl, typeof(OpCodeAluReg)); - Set("0100110000101x", InstEmit.Shr, typeof(OpCodeAluCbuf)); - Set("0011100x00101x", InstEmit.Shr, typeof(OpCodeAluImm)); - Set("0101110000101x", InstEmit.Shr, typeof(OpCodeAluReg)); - Set("111000101001xx", InstEmit.Ssy, typeof(OpCodeSsy)); - Set("1111000011111x", InstEmit.Sync, typeof(OpCodeSync)); - Set("110000xxxx111x", InstEmit.Tex, typeof(OpCodeTex)); - Set("1101111010111x", InstEmit.Tex_B, typeof(OpCodeTex)); - Set("1101x00xxxxxxx", InstEmit.Texs, typeof(OpCodeTexs)); - Set("1101x01xxxxxxx", InstEmit.Texs, typeof(OpCodeTlds)); - Set("1101x11100xxxx", InstEmit.Texs, typeof(OpCodeTld4s)); - Set("11011100xx111x", InstEmit.Tld, typeof(OpCodeTld)); - Set("11011101xx111x", InstEmit.Tld_B, typeof(OpCodeTld)); - Set("110010xxxx111x", InstEmit.Tld4, typeof(OpCodeTld4)); - Set("1101111101001x", InstEmit.Txq, typeof(OpCodeTex)); - Set("1101111101010x", InstEmit.Txq_B, typeof(OpCodeTex)); - Set("0100111xxxxxxx", InstEmit.Xmad, typeof(OpCodeAluCbuf)); - Set("0011011x00xxxx", InstEmit.Xmad, typeof(OpCodeAluImm)); - Set("010100010xxxxx", InstEmit.Xmad, typeof(OpCodeAluRegCbuf)); - Set("0101101100xxxx", InstEmit.Xmad, typeof(OpCodeAluReg)); -#endregion - } - - private static void Set(string encoding, InstEmitter emitter, Type opCodeType) - { - if (encoding.Length != EncodingBits) - { - throw new ArgumentException(nameof(encoding)); - } - - int bit = encoding.Length - 1; - int value = 0; - int xMask = 0; - int xBits = 0; - - int[] xPos = new int[encoding.Length]; - - for (int index = 0; index < encoding.Length; index++, bit--) - { - char chr = encoding[index]; - - if (chr == '1') - { - value |= 1 << bit; - } - else if (chr == 'x') - { - xMask |= 1 << bit; - - xPos[xBits++] = bit; - } - } - - xMask = ~xMask; - - TableEntry entry = new TableEntry(emitter, opCodeType, xBits); - - for (int index = 0; index < (1 << xBits); index++) - { - value &= xMask; - - for (int X = 0; X < xBits; X++) - { - value |= ((index >> X) & 1) << xPos[X]; - } - - if (_opCodes[value] == null || _opCodes[value].XBits > xBits) - { - _opCodes[value] = entry; - } - } - } - - public static (InstEmitter emitter, Type opCodeType) GetEmitter(long OpCode) - { - TableEntry entry = _opCodes[(ulong)OpCode >> (64 - EncodingBits)]; - - if (entry != null) - { - return (entry.Emitter, entry.OpCodeType); - } - - return (null, null); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTex.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTex.cs deleted file mode 100644 index da8756b9..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTex.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTex : OpCodeTexture - { - public OpCodeTex(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - HasDepthCompare = opCode.Extract(50); - - HasOffset = opCode.Extract(54); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTexs.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTexs.cs deleted file mode 100644 index 0822c4c0..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTexs.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTexs : OpCodeTextureScalar - { - public TextureScalarType Type => (TextureScalarType)RawType; - - public OpCodeTexs(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) { } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTexture.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTexture.cs deleted file mode 100644 index 7a7e8f46..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTexture.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTexture : OpCode - { - public Register Rd { get; } - public Register Ra { get; } - public Register Rb { get; } - - public bool IsArray { get; } - - public TextureDimensions Dimensions { get; } - - public int ComponentMask { get; } - - public int Immediate { get; } - - public TextureLodMode LodMode { get; protected set; } - - public bool HasOffset { get; protected set; } - public bool HasDepthCompare { get; protected set; } - public bool IsMultisample { get; protected set; } - - public OpCodeTexture(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr); - Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - - IsArray = opCode.Extract(28); - - Dimensions = (TextureDimensions)opCode.Extract(29, 2); - - ComponentMask = opCode.Extract(31, 4); - - Immediate = opCode.Extract(36, 13); - - LodMode = (TextureLodMode)opCode.Extract(55, 3); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTextureScalar.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTextureScalar.cs deleted file mode 100644 index 470b81f5..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTextureScalar.cs +++ /dev/null @@ -1,62 +0,0 @@ -// ReSharper disable InconsistentNaming -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTextureScalar : OpCode - { -#region "Component mask LUT" - private const int ____ = 0x0; - private const int R___ = 0x1; - private const int _G__ = 0x2; - private const int RG__ = 0x3; - private const int __B_ = 0x4; - private const int RGB_ = 0x7; - private const int ___A = 0x8; - private const int R__A = 0x9; - private const int _G_A = 0xa; - private const int RG_A = 0xb; - private const int __BA = 0xc; - private const int R_BA = 0xd; - private const int _GBA = 0xe; - private const int RGBA = 0xf; - - private static int[,] _maskLut = new int[,] - { - { R___, _G__, __B_, ___A, RG__, R__A, _G_A, __BA }, - { RGB_, RG_A, R_BA, _GBA, RGBA, ____, ____, ____ } - }; -#endregion - - public Register Rd0 { get; } - public Register Ra { get; } - public Register Rb { get; } - public Register Rd1 { get; } - - public int Immediate { get; } - - public int ComponentMask { get; } - - protected int RawType; - - public bool IsFp16 { get; } - - public OpCodeTextureScalar(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rd0 = new Register(opCode.Extract(0, 8), RegisterType.Gpr); - Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - Rd1 = new Register(opCode.Extract(28, 8), RegisterType.Gpr); - - Immediate = opCode.Extract(36, 13); - - int compSel = opCode.Extract(50, 3); - - RawType = opCode.Extract(53, 4); - - IsFp16 = !opCode.Extract(59); - - ComponentMask = _maskLut[Rd1.IsRZ ? 0 : 1, compSel]; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTld.cs deleted file mode 100644 index 61bd900b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTld : OpCodeTexture - { - public OpCodeTld(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - HasOffset = opCode.Extract(35); - - IsMultisample = opCode.Extract(50); - - bool isLL = opCode.Extract(55); - - LodMode = isLL - ? TextureLodMode.LodLevel - : TextureLodMode.LodZero; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4.cs deleted file mode 100644 index 485edf93..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTld4 : OpCodeTexture - { - public TextureGatherOffset Offset { get; } - - public int GatherCompIndex { get; } - - public OpCodeTld4(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - HasDepthCompare = opCode.Extract(50); - - Offset = (TextureGatherOffset)opCode.Extract(54, 2); - - GatherCompIndex = opCode.Extract(56, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4s.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4s.cs deleted file mode 100644 index 0d7b8460..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4s.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTld4s : OpCodeTextureScalar - { - public bool HasDepthCompare { get; } - public bool HasOffset { get; } - - public int GatherCompIndex { get; } - - public OpCodeTld4s(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - HasDepthCompare = opCode.Extract(50); - HasOffset = opCode.Extract(51); - - GatherCompIndex = opCode.Extract(52, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTlds.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTlds.cs deleted file mode 100644 index e117721e..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTlds.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTlds : OpCodeTextureScalar - { - public TexelLoadScalarType Type => (TexelLoadScalarType)RawType; - - public OpCodeTlds(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) { } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/Register.cs b/Ryujinx.Graphics/Shader/Decoders/Register.cs deleted file mode 100644 index 30840d8c..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/Register.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - struct Register : IEquatable<Register> - { - public int Index { get; } - - public RegisterType Type { get; } - - public bool IsRZ => Type == RegisterType.Gpr && Index == RegisterConsts.RegisterZeroIndex; - public bool IsPT => Type == RegisterType.Predicate && Index == RegisterConsts.PredicateTrueIndex; - - public Register(int index, RegisterType type) - { - Index = index; - Type = type; - } - - public override int GetHashCode() - { - return (ushort)Index | ((ushort)Type << 16); - } - - public override bool Equals(object obj) - { - return obj is Register reg && Equals(reg); - } - - public bool Equals(Register other) - { - return other.Index == Index && - other.Type == Type; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/RegisterConsts.cs b/Ryujinx.Graphics/Shader/Decoders/RegisterConsts.cs deleted file mode 100644 index d381f954..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/RegisterConsts.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - static class RegisterConsts - { - public const int GprsCount = 255; - public const int PredsCount = 7; - public const int FlagsCount = 4; - public const int TotalCount = GprsCount + PredsCount + FlagsCount; - - public const int RegisterZeroIndex = GprsCount; - public const int PredicateTrueIndex = PredsCount; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/RegisterType.cs b/Ryujinx.Graphics/Shader/Decoders/RegisterType.cs deleted file mode 100644 index 648f816a..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/RegisterType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum RegisterType - { - Flag, - Gpr, - Predicate, - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/RoundingMode.cs b/Ryujinx.Graphics/Shader/Decoders/RoundingMode.cs deleted file mode 100644 index 13bb08dc..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/RoundingMode.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum RoundingMode - { - ToNearest = 0, - TowardsNegativeInfinity = 1, - TowardsPositiveInfinity = 2, - TowardsZero = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TexelLoadScalarType.cs b/Ryujinx.Graphics/Shader/Decoders/TexelLoadScalarType.cs deleted file mode 100644 index cef5778a..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TexelLoadScalarType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TexelLoadScalarType - { - Texture1DLodZero = 0x0, - Texture1DLodLevel = 0x1, - Texture2DLodZero = 0x2, - Texture2DLodZeroOffset = 0x4, - Texture2DLodLevel = 0x5, - Texture2DLodZeroMultisample = 0x6, - Texture3DLodZero = 0x7, - Texture2DArrayLodZero = 0x8, - Texture2DLodLevelOffset = 0xc - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TextureDimensions.cs b/Ryujinx.Graphics/Shader/Decoders/TextureDimensions.cs deleted file mode 100644 index dbdf1927..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TextureDimensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TextureDimensions - { - Texture1D = 0, - Texture2D = 1, - Texture3D = 2, - TextureCube = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TextureGatherOffset.cs b/Ryujinx.Graphics/Shader/Decoders/TextureGatherOffset.cs deleted file mode 100644 index 4e9ade26..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TextureGatherOffset.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TextureGatherOffset - { - None = 0, - Offset = 1, - Offsets = 2 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TextureLodMode.cs b/Ryujinx.Graphics/Shader/Decoders/TextureLodMode.cs deleted file mode 100644 index 0cc6f714..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TextureLodMode.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TextureLodMode - { - None = 0, - LodZero = 1, - LodBias = 2, - LodLevel = 3, - LodBiasA = 4, //? - LodLevelA = 5 //? - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TextureProperty.cs b/Ryujinx.Graphics/Shader/Decoders/TextureProperty.cs deleted file mode 100644 index ea35b1d1..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TextureProperty.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TextureProperty - { - Dimensions = 0x1, - Type = 0x2, - SamplePos = 0x5, - Filter = 0xa, - Lod = 0xc, - Wrap = 0xe, - BorderColor = 0x10 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TextureScalarType.cs b/Ryujinx.Graphics/Shader/Decoders/TextureScalarType.cs deleted file mode 100644 index 0055174b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TextureScalarType.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TextureScalarType - { - Texture1DLodZero = 0x0, - Texture2D = 0x1, - Texture2DLodZero = 0x2, - Texture2DLodLevel = 0x3, - Texture2DDepthCompare = 0x4, - Texture2DLodLevelDepthCompare = 0x5, - Texture2DLodZeroDepthCompare = 0x6, - Texture2DArray = 0x7, - Texture2DArrayLodZero = 0x8, - Texture2DArrayLodZeroDepthCompare = 0x9, - Texture3D = 0xa, - Texture3DLodZero = 0xb, - TextureCube = 0xc, - TextureCubeLodLevel = 0xd - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/XmadCMode.cs b/Ryujinx.Graphics/Shader/Decoders/XmadCMode.cs deleted file mode 100644 index 949a2ef7..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/XmadCMode.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum XmadCMode - { - Cfull = 0, - Clo = 1, - Chi = 2, - Csfu = 3, - Cbcc = 4 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs deleted file mode 100644 index 8e2b39bf..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs +++ /dev/null @@ -1,684 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Bfe(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool isReverse = op.RawOpCode.Extract(40); - bool isSigned = op.RawOpCode.Extract(48); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - if (isReverse) - { - srcA = context.BitfieldReverse(srcA); - } - - Operand position = context.BitwiseAnd(srcB, Const(0xff)); - - Operand size = context.BitfieldExtractU32(srcB, Const(8), Const(8)); - - Operand res = isSigned - ? context.BitfieldExtractS32(srcA, position, size) - : context.BitfieldExtractU32(srcA, position, size); - - context.Copy(GetDest(context), res); - - // TODO: CC, X, corner cases - } - - public static void Iadd(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool negateA = false, negateB = false; - - if (!(op is OpCodeAluImm32)) - { - negateB = op.RawOpCode.Extract(48); - negateA = op.RawOpCode.Extract(49); - } - - Operand srcA = context.INegate(GetSrcA(context), negateA); - Operand srcB = context.INegate(GetSrcB(context), negateB); - - Operand res = context.IAdd(srcA, srcB); - - bool isSubtraction = negateA || negateB; - - if (op.Extended) - { - // Add carry, or subtract borrow. - res = context.IAdd(res, isSubtraction - ? context.BitwiseNot(GetCF(context)) - : context.BitwiseAnd(GetCF(context), Const(1))); - } - - SetIaddFlags(context, res, srcA, srcB, op.SetCondCode, op.Extended, isSubtraction); - - context.Copy(GetDest(context), res); - } - - public static void Iadd3(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - IntegerHalfPart partC = (IntegerHalfPart)op.RawOpCode.Extract(31, 2); - IntegerHalfPart partB = (IntegerHalfPart)op.RawOpCode.Extract(33, 2); - IntegerHalfPart partA = (IntegerHalfPart)op.RawOpCode.Extract(35, 2); - - IntegerShift mode = (IntegerShift)op.RawOpCode.Extract(37, 2); - - bool negateC = op.RawOpCode.Extract(49); - bool negateB = op.RawOpCode.Extract(50); - bool negateA = op.RawOpCode.Extract(51); - - Operand Extend(Operand src, IntegerHalfPart part) - { - if (!(op is OpCodeAluReg) || part == IntegerHalfPart.B32) - { - return src; - } - - if (part == IntegerHalfPart.H0) - { - return context.BitwiseAnd(src, Const(0xffff)); - } - else if (part == IntegerHalfPart.H1) - { - return context.ShiftRightU32(src, Const(16)); - } - else - { - // TODO: Warning. - } - - return src; - } - - Operand srcA = context.INegate(Extend(GetSrcA(context), partA), negateA); - Operand srcB = context.INegate(Extend(GetSrcB(context), partB), negateB); - Operand srcC = context.INegate(Extend(GetSrcC(context), partC), negateC); - - Operand res = context.IAdd(srcA, srcB); - - if (op is OpCodeAluReg && mode != IntegerShift.NoShift) - { - if (mode == IntegerShift.ShiftLeft) - { - res = context.ShiftLeft(res, Const(16)); - } - else if (mode == IntegerShift.ShiftRight) - { - res = context.ShiftRightU32(res, Const(16)); - } - else - { - // TODO: Warning. - } - } - - res = context.IAdd(res, srcC); - - context.Copy(GetDest(context), res); - - // TODO: CC, X, corner cases - } - - public static void Imnmx(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool isSignedInt = op.RawOpCode.Extract(48); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - Operand resMin = isSignedInt - ? context.IMinimumS32(srcA, srcB) - : context.IMinimumU32(srcA, srcB); - - Operand resMax = isSignedInt - ? context.IMaximumS32(srcA, srcB) - : context.IMaximumU32(srcA, srcB); - - Operand pred = GetPredicate39(context); - - Operand dest = GetDest(context); - - context.Copy(dest, context.ConditionalSelect(pred, resMin, resMax)); - - SetZnFlags(context, dest, op.SetCondCode); - - // TODO: X flags. - } - - public static void Iscadd(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool negateA = false, negateB = false; - - if (!(op is OpCodeAluImm32)) - { - negateB = op.RawOpCode.Extract(48); - negateA = op.RawOpCode.Extract(49); - } - - int shift = op is OpCodeAluImm32 - ? op.RawOpCode.Extract(53, 5) - : op.RawOpCode.Extract(39, 5); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - srcA = context.ShiftLeft(srcA, Const(shift)); - - srcA = context.INegate(srcA, negateA); - srcB = context.INegate(srcB, negateB); - - Operand res = context.IAdd(srcA, srcB); - - context.Copy(GetDest(context), res); - - // TODO: CC, X - } - - public static void Iset(EmitterContext context) - { - OpCodeSet op = (OpCodeSet)context.CurrOp; - - bool boolFloat = op.RawOpCode.Extract(44); - bool isSigned = op.RawOpCode.Extract(48); - - IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - Operand res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned); - - Operand pred = GetPredicate39(context); - - res = GetPredLogicalOp(context, op.LogicalOp, res, pred); - - Operand dest = GetDest(context); - - if (boolFloat) - { - context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0))); - } - else - { - context.Copy(dest, res); - } - - // TODO: CC, X - } - - public static void Isetp(EmitterContext context) - { - OpCodeSet op = (OpCodeSet)context.CurrOp; - - bool isSigned = op.RawOpCode.Extract(48); - - IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - Operand p0Res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned); - - Operand p1Res = context.BitwiseNot(p0Res); - - Operand pred = GetPredicate39(context); - - p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred); - p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred); - - context.Copy(Register(op.Predicate3), p0Res); - context.Copy(Register(op.Predicate0), p1Res); - } - - public static void Lop(EmitterContext context) - { - IOpCodeLop op = (IOpCodeLop)context.CurrOp; - - Operand srcA = context.BitwiseNot(GetSrcA(context), op.InvertA); - Operand srcB = context.BitwiseNot(GetSrcB(context), op.InvertB); - - Operand res = srcB; - - switch (op.LogicalOp) - { - case LogicalOperation.And: res = context.BitwiseAnd (srcA, srcB); break; - case LogicalOperation.Or: res = context.BitwiseOr (srcA, srcB); break; - case LogicalOperation.ExclusiveOr: res = context.BitwiseExclusiveOr(srcA, srcB); break; - } - - EmitLopPredWrite(context, op, res); - - Operand dest = GetDest(context); - - context.Copy(dest, res); - - SetZnFlags(context, dest, op.SetCondCode, op.Extended); - } - - public static void Lop3(EmitterContext context) - { - IOpCodeLop op = (IOpCodeLop)context.CurrOp; - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - Operand srcC = GetSrcC(context); - - bool regVariant = op is OpCodeLopReg; - - int truthTable = regVariant - ? op.RawOpCode.Extract(28, 8) - : op.RawOpCode.Extract(48, 8); - - Operand res = Lop3Expression.GetFromTruthTable(context, srcA, srcB, srcC, truthTable); - - if (regVariant) - { - EmitLopPredWrite(context, op, res); - } - - Operand dest = GetDest(context); - - context.Copy(dest, res); - - SetZnFlags(context, dest, op.SetCondCode, op.Extended); - } - - public static void Psetp(EmitterContext context) - { - OpCodePsetp op = (OpCodePsetp)context.CurrOp; - - bool invertA = op.RawOpCode.Extract(15); - bool invertB = op.RawOpCode.Extract(32); - - Operand srcA = context.BitwiseNot(Register(op.Predicate12), invertA); - Operand srcB = context.BitwiseNot(Register(op.Predicate29), invertB); - - Operand p0Res = GetPredLogicalOp(context, op.LogicalOpAB, srcA, srcB); - - Operand p1Res = context.BitwiseNot(p0Res); - - Operand pred = GetPredicate39(context); - - p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred); - p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred); - - context.Copy(Register(op.Predicate3), p0Res); - context.Copy(Register(op.Predicate0), p1Res); - } - - public static void Rro(EmitterContext context) - { - // This is the range reduction operator, - // we translate it as a simple move, as it - // should be always followed by a matching - // MUFU instruction. - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool negateB = op.RawOpCode.Extract(45); - bool absoluteB = op.RawOpCode.Extract(49); - - Operand srcB = GetSrcB(context); - - srcB = context.FPAbsNeg(srcB, absoluteB, negateB); - - context.Copy(GetDest(context), srcB); - } - - public static void Shl(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool isMasked = op.RawOpCode.Extract(39); - - Operand srcB = GetSrcB(context); - - if (isMasked) - { - srcB = context.BitwiseAnd(srcB, Const(0x1f)); - } - - Operand res = context.ShiftLeft(GetSrcA(context), srcB); - - if (!isMasked) - { - // Clamped shift value. - Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32)); - - res = context.ConditionalSelect(isLessThan32, res, Const(0)); - } - - // TODO: X, CC - - context.Copy(GetDest(context), res); - } - - public static void Shr(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool isMasked = op.RawOpCode.Extract(39); - bool isReverse = op.RawOpCode.Extract(40); - bool isSigned = op.RawOpCode.Extract(48); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - if (isReverse) - { - srcA = context.BitfieldReverse(srcA); - } - - if (isMasked) - { - srcB = context.BitwiseAnd(srcB, Const(0x1f)); - } - - Operand res = isSigned - ? context.ShiftRightS32(srcA, srcB) - : context.ShiftRightU32(srcA, srcB); - - if (!isMasked) - { - // Clamped shift value. - Operand resShiftBy32; - - if (isSigned) - { - resShiftBy32 = context.ShiftRightS32(srcA, Const(31)); - } - else - { - resShiftBy32 = Const(0); - } - - Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32)); - - res = context.ConditionalSelect(isLessThan32, res, resShiftBy32); - } - - // TODO: X, CC - - context.Copy(GetDest(context), res); - } - - public static void Xmad(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool signedA = context.CurrOp.RawOpCode.Extract(48); - bool signedB = context.CurrOp.RawOpCode.Extract(49); - bool highA = context.CurrOp.RawOpCode.Extract(53); - bool highB = false; - - XmadCMode mode; - - if (op is OpCodeAluReg) - { - highB = context.CurrOp.RawOpCode.Extract(35); - - mode = (XmadCMode)context.CurrOp.RawOpCode.Extract(50, 3); - } - else - { - mode = (XmadCMode)context.CurrOp.RawOpCode.Extract(50, 2); - - if (!(op is OpCodeAluImm)) - { - highB = context.CurrOp.RawOpCode.Extract(52); - } - } - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - Operand srcC = GetSrcC(context); - - // XMAD immediates are 16-bits unsigned integers. - if (srcB.Type == OperandType.Constant) - { - srcB = Const(srcB.Value & 0xffff); - } - - Operand Extend16To32(Operand src, bool high, bool signed) - { - if (signed && high) - { - return context.ShiftRightS32(src, Const(16)); - } - else if (signed) - { - return context.BitfieldExtractS32(src, Const(0), Const(16)); - } - else if (high) - { - return context.ShiftRightU32(src, Const(16)); - } - else - { - return context.BitwiseAnd(src, Const(0xffff)); - } - } - - srcA = Extend16To32(srcA, highA, signedA); - srcB = Extend16To32(srcB, highB, signedB); - - bool productShiftLeft = false; - bool merge = false; - - if (!(op is OpCodeAluRegCbuf)) - { - productShiftLeft = context.CurrOp.RawOpCode.Extract(36); - merge = context.CurrOp.RawOpCode.Extract(37); - } - - bool extended; - - if ((op is OpCodeAluReg) || (op is OpCodeAluImm)) - { - extended = context.CurrOp.RawOpCode.Extract(38); - } - else - { - extended = context.CurrOp.RawOpCode.Extract(54); - } - - Operand res = context.IMultiply(srcA, srcB); - - if (productShiftLeft) - { - res = context.ShiftLeft(res, Const(16)); - } - - switch (mode) - { - case XmadCMode.Cfull: break; - - case XmadCMode.Clo: srcC = Extend16To32(srcC, high: false, signed: false); break; - case XmadCMode.Chi: srcC = Extend16To32(srcC, high: true, signed: false); break; - - case XmadCMode.Cbcc: - { - srcC = context.IAdd(srcC, context.ShiftLeft(GetSrcB(context), Const(16))); - - break; - } - - case XmadCMode.Csfu: - { - Operand signAdjustA = context.ShiftLeft(context.ShiftRightU32(srcA, Const(31)), Const(16)); - Operand signAdjustB = context.ShiftLeft(context.ShiftRightU32(srcB, Const(31)), Const(16)); - - srcC = context.ISubtract(srcC, context.IAdd(signAdjustA, signAdjustB)); - - break; - } - - default: /* TODO: Warning */ break; - } - - Operand product = res; - - if (extended) - { - // Add with carry. - res = context.IAdd(res, context.BitwiseAnd(GetCF(context), Const(1))); - } - else - { - // Add (no carry in). - res = context.IAdd(res, srcC); - } - - SetIaddFlags(context, res, product, srcC, op.SetCondCode, extended); - - if (merge) - { - res = context.BitwiseAnd(res, Const(0xffff)); - res = context.BitwiseOr(res, context.ShiftLeft(GetSrcB(context), Const(16))); - } - - context.Copy(GetDest(context), res); - } - - private static Operand GetIntComparison( - EmitterContext context, - IntegerCondition cond, - Operand srcA, - Operand srcB, - bool isSigned) - { - Operand res; - - if (cond == IntegerCondition.Always) - { - res = Const(IrConsts.True); - } - else if (cond == IntegerCondition.Never) - { - res = Const(IrConsts.False); - } - else - { - Instruction inst; - - switch (cond) - { - case IntegerCondition.Less: inst = Instruction.CompareLessU32; break; - case IntegerCondition.Equal: inst = Instruction.CompareEqual; break; - case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqualU32; break; - case IntegerCondition.Greater: inst = Instruction.CompareGreaterU32; break; - case IntegerCondition.NotEqual: inst = Instruction.CompareNotEqual; break; - case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqualU32; break; - - default: throw new InvalidOperationException($"Unexpected condition \"{cond}\"."); - } - - if (isSigned) - { - switch (cond) - { - case IntegerCondition.Less: inst = Instruction.CompareLess; break; - case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqual; break; - case IntegerCondition.Greater: inst = Instruction.CompareGreater; break; - case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqual; break; - } - } - - res = context.Add(inst, Local(), srcA, srcB); - } - - return res; - } - - private static void EmitLopPredWrite(EmitterContext context, IOpCodeLop op, Operand result) - { - if (op is OpCodeLop opLop && !opLop.Predicate48.IsPT) - { - Operand pRes; - - if (opLop.CondOp == ConditionalOperation.False) - { - pRes = Const(IrConsts.False); - } - else if (opLop.CondOp == ConditionalOperation.True) - { - pRes = Const(IrConsts.True); - } - else if (opLop.CondOp == ConditionalOperation.Zero) - { - pRes = context.ICompareEqual(result, Const(0)); - } - else /* if (opLop.CondOp == ConditionalOperation.NotZero) */ - { - pRes = context.ICompareNotEqual(result, Const(0)); - } - - context.Copy(Register(opLop.Predicate48), pRes); - } - } - - private static void SetIaddFlags( - EmitterContext context, - Operand res, - Operand srcA, - Operand srcB, - bool setCC, - bool extended, - bool isSubtraction = false) - { - if (!setCC) - { - return; - } - - if (!extended || isSubtraction) - { - // C = d < a - context.Copy(GetCF(context), context.ICompareLessUnsigned(res, srcA)); - } - else - { - // C = (d == a && CIn) || d < a - Operand tempC0 = context.ICompareEqual (res, srcA); - Operand tempC1 = context.ICompareLessUnsigned(res, srcA); - - tempC0 = context.BitwiseAnd(tempC0, GetCF(context)); - - context.Copy(GetCF(context), context.BitwiseOr(tempC0, tempC1)); - } - - // V = (d ^ a) & ~(a ^ b) < 0 - Operand tempV0 = context.BitwiseExclusiveOr(res, srcA); - Operand tempV1 = context.BitwiseExclusiveOr(srcA, srcB); - - tempV1 = context.BitwiseNot(tempV1); - - Operand tempV = context.BitwiseAnd(tempV0, tempV1); - - context.Copy(GetVF(context), context.ICompareLess(tempV, Const(0))); - - SetZnFlags(context, res, setCC: true, extended: extended); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs deleted file mode 100644 index 5c4f5398..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs +++ /dev/null @@ -1,88 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static class InstEmitAluHelper - { - public static int GetIntMin(IntegerType type) - { - switch (type) - { - case IntegerType.U8: return byte.MinValue; - case IntegerType.S8: return sbyte.MinValue; - case IntegerType.U16: return ushort.MinValue; - case IntegerType.S16: return short.MinValue; - case IntegerType.U32: return (int)uint.MinValue; - case IntegerType.S32: return int.MinValue; - } - - throw new ArgumentException($"The type \"{type}\" is not a supported int type."); - } - - public static int GetIntMax(IntegerType type) - { - switch (type) - { - case IntegerType.U8: return byte.MaxValue; - case IntegerType.S8: return sbyte.MaxValue; - case IntegerType.U16: return ushort.MaxValue; - case IntegerType.S16: return short.MaxValue; - case IntegerType.U32: return unchecked((int)uint.MaxValue); - case IntegerType.S32: return int.MaxValue; - } - - throw new ArgumentException($"The type \"{type}\" is not a supported int type."); - } - - public static Operand GetPredLogicalOp( - EmitterContext context, - LogicalOperation logicalOp, - Operand input, - Operand pred) - { - switch (logicalOp) - { - case LogicalOperation.And: return context.BitwiseAnd (input, pred); - case LogicalOperation.Or: return context.BitwiseOr (input, pred); - case LogicalOperation.ExclusiveOr: return context.BitwiseExclusiveOr(input, pred); - } - - return input; - } - - public static void SetZnFlags(EmitterContext context, Operand dest, bool setCC, bool extended = false) - { - if (!setCC) - { - return; - } - - if (extended) - { - // When the operation is extended, it means we are doing - // the operation on a long word with any number of bits, - // so we need to AND the zero flag from result with the - // previous result when extended is specified, to ensure - // we have ZF set only if all words are zero, and not just - // the last one. - Operand oldZF = GetZF(context); - - Operand res = context.BitwiseAnd(context.ICompareEqual(dest, Const(0)), oldZF); - - context.Copy(GetZF(context), res); - } - else - { - context.Copy(GetZF(context), context.ICompareEqual(dest, Const(0))); - } - - context.Copy(GetNF(context), context.ICompareLess(dest, Const(0))); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs deleted file mode 100644 index c4de1750..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs +++ /dev/null @@ -1,213 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void F2F(EmitterContext context) - { - OpCodeFArith op = (OpCodeFArith)context.CurrOp; - - FPType srcType = (FPType)op.RawOpCode.Extract(8, 2); - FPType dstType = (FPType)op.RawOpCode.Extract(10, 2); - - bool pass = op.RawOpCode.Extract(40); - bool negateB = op.RawOpCode.Extract(45); - bool absoluteB = op.RawOpCode.Extract(49); - - pass &= op.RoundingMode == RoundingMode.TowardsNegativeInfinity; - - Operand srcB = context.FPAbsNeg(GetSrcB(context, srcType), absoluteB, negateB); - - if (!pass) - { - switch (op.RoundingMode) - { - case RoundingMode.TowardsNegativeInfinity: - srcB = context.FPFloor(srcB); - break; - - case RoundingMode.TowardsPositiveInfinity: - srcB = context.FPCeiling(srcB); - break; - - case RoundingMode.TowardsZero: - srcB = context.FPTruncate(srcB); - break; - } - } - - srcB = context.FPSaturate(srcB, op.Saturate); - - WriteFP(context, dstType, srcB); - - // TODO: CC. - } - - public static void F2I(EmitterContext context) - { - OpCodeFArith op = (OpCodeFArith)context.CurrOp; - - IntegerType intType = (IntegerType)op.RawOpCode.Extract(8, 2); - - bool isSmallInt = intType <= IntegerType.U16; - - FPType floatType = (FPType)op.RawOpCode.Extract(10, 2); - - bool isSignedInt = op.RawOpCode.Extract(12); - bool negateB = op.RawOpCode.Extract(45); - bool absoluteB = op.RawOpCode.Extract(49); - - if (isSignedInt) - { - intType |= IntegerType.S8; - } - - Operand srcB = context.FPAbsNeg(GetSrcB(context, floatType), absoluteB, negateB); - - switch (op.RoundingMode) - { - case RoundingMode.TowardsNegativeInfinity: - srcB = context.FPFloor(srcB); - break; - - case RoundingMode.TowardsPositiveInfinity: - srcB = context.FPCeiling(srcB); - break; - - case RoundingMode.TowardsZero: - srcB = context.FPTruncate(srcB); - break; - } - - srcB = context.FPConvertToS32(srcB); - - // TODO: S/U64, conversion overflow handling. - if (intType != IntegerType.S32) - { - int min = GetIntMin(intType); - int max = GetIntMax(intType); - - srcB = isSignedInt - ? context.IClampS32(srcB, Const(min), Const(max)) - : context.IClampU32(srcB, Const(min), Const(max)); - } - - Operand dest = GetDest(context); - - context.Copy(dest, srcB); - - // TODO: CC. - } - - public static void I2F(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - FPType dstType = (FPType)op.RawOpCode.Extract(8, 2); - - IntegerType srcType = (IntegerType)op.RawOpCode.Extract(10, 2); - - bool isSmallInt = srcType <= IntegerType.U16; - - bool isSignedInt = op.RawOpCode.Extract(13); - bool negateB = op.RawOpCode.Extract(45); - bool absoluteB = op.RawOpCode.Extract(49); - - Operand srcB = context.IAbsNeg(GetSrcB(context), absoluteB, negateB); - - if (isSmallInt) - { - int size = srcType == IntegerType.U16 ? 16 : 8; - - srcB = isSignedInt - ? context.BitfieldExtractS32(srcB, Const(op.ByteSelection * 8), Const(size)) - : context.BitfieldExtractU32(srcB, Const(op.ByteSelection * 8), Const(size)); - } - - srcB = isSignedInt - ? context.IConvertS32ToFP(srcB) - : context.IConvertU32ToFP(srcB); - - WriteFP(context, dstType, srcB); - - // TODO: CC. - } - - public static void I2I(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - IntegerType dstType = (IntegerType)op.RawOpCode.Extract(8, 2); - IntegerType srcType = (IntegerType)op.RawOpCode.Extract(10, 2); - - if (srcType == IntegerType.U64 || dstType == IntegerType.U64) - { - // TODO: Warning. This instruction doesn't support 64-bits integers - } - - bool srcIsSmallInt = srcType <= IntegerType.U16; - - bool dstIsSignedInt = op.RawOpCode.Extract(12); - bool srcIsSignedInt = op.RawOpCode.Extract(13); - bool negateB = op.RawOpCode.Extract(45); - bool absoluteB = op.RawOpCode.Extract(49); - - Operand srcB = GetSrcB(context); - - if (srcIsSmallInt) - { - int size = srcType == IntegerType.U16 ? 16 : 8; - - srcB = srcIsSignedInt - ? context.BitfieldExtractS32(srcB, Const(op.ByteSelection * 8), Const(size)) - : context.BitfieldExtractU32(srcB, Const(op.ByteSelection * 8), Const(size)); - } - - srcB = context.IAbsNeg(srcB, absoluteB, negateB); - - if (op.Saturate) - { - if (dstIsSignedInt) - { - dstType |= IntegerType.S8; - } - - int min = GetIntMin(dstType); - int max = GetIntMax(dstType); - - srcB = dstIsSignedInt - ? context.IClampS32(srcB, Const(min), Const(max)) - : context.IClampU32(srcB, Const(min), Const(max)); - } - - context.Copy(GetDest(context), srcB); - - // TODO: CC. - } - - private static void WriteFP(EmitterContext context, FPType type, Operand srcB) - { - Operand dest = GetDest(context); - - if (type == FPType.FP32) - { - context.Copy(dest, srcB); - } - else if (type == FPType.FP16) - { - context.Copy(dest, context.PackHalf2x16(srcB, ConstF(0))); - } - else - { - // TODO. - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs deleted file mode 100644 index b22639de..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs +++ /dev/null @@ -1,370 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper; -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Fadd(EmitterContext context) - { - IOpCodeFArith op = (IOpCodeFArith)context.CurrOp; - - bool absoluteA = op.AbsoluteA, absoluteB, negateA, negateB; - - if (op is OpCodeFArithImm32) - { - negateB = op.RawOpCode.Extract(53); - negateA = op.RawOpCode.Extract(56); - absoluteB = op.RawOpCode.Extract(57); - } - else - { - negateB = op.RawOpCode.Extract(45); - negateA = op.RawOpCode.Extract(48); - absoluteB = op.RawOpCode.Extract(49); - } - - Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA); - Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB); - - Operand dest = GetDest(context); - - context.Copy(dest, context.FPSaturate(context.FPAdd(srcA, srcB), op.Saturate)); - - SetFPZnFlags(context, dest, op.SetCondCode); - } - - public static void Ffma(EmitterContext context) - { - IOpCodeFArith op = (IOpCodeFArith)context.CurrOp; - - bool negateB = op.RawOpCode.Extract(48); - bool negateC = op.RawOpCode.Extract(49); - - Operand srcA = GetSrcA(context); - - Operand srcB = context.FPNegate(GetSrcB(context), negateB); - Operand srcC = context.FPNegate(GetSrcC(context), negateC); - - Operand dest = GetDest(context); - - context.Copy(dest, context.FPSaturate(context.FPFusedMultiplyAdd(srcA, srcB, srcC), op.Saturate)); - - SetFPZnFlags(context, dest, op.SetCondCode); - } - - public static void Fmnmx(EmitterContext context) - { - IOpCodeFArith op = (IOpCodeFArith)context.CurrOp; - - bool absoluteA = op.AbsoluteA; - bool negateB = op.RawOpCode.Extract(45); - bool negateA = op.RawOpCode.Extract(48); - bool absoluteB = op.RawOpCode.Extract(49); - - Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA); - Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB); - - Operand resMin = context.FPMinimum(srcA, srcB); - Operand resMax = context.FPMaximum(srcA, srcB); - - Operand pred = GetPredicate39(context); - - Operand dest = GetDest(context); - - context.Copy(dest, context.ConditionalSelect(pred, resMin, resMax)); - - SetFPZnFlags(context, dest, op.SetCondCode); - } - - public static void Fmul(EmitterContext context) - { - IOpCodeFArith op = (IOpCodeFArith)context.CurrOp; - - bool negateB = !(op is OpCodeFArithImm32) && op.RawOpCode.Extract(48); - - Operand srcA = GetSrcA(context); - - Operand srcB = context.FPNegate(GetSrcB(context), negateB); - - switch (op.Scale) - { - case FmulScale.None: break; - - case FmulScale.Divide2: srcA = context.FPDivide (srcA, ConstF(2)); break; - case FmulScale.Divide4: srcA = context.FPDivide (srcA, ConstF(4)); break; - case FmulScale.Divide8: srcA = context.FPDivide (srcA, ConstF(8)); break; - case FmulScale.Multiply2: srcA = context.FPMultiply(srcA, ConstF(2)); break; - case FmulScale.Multiply4: srcA = context.FPMultiply(srcA, ConstF(4)); break; - case FmulScale.Multiply8: srcA = context.FPMultiply(srcA, ConstF(8)); break; - - default: break; //TODO: Warning. - } - - Operand dest = GetDest(context); - - context.Copy(dest, context.FPSaturate(context.FPMultiply(srcA, srcB), op.Saturate)); - - SetFPZnFlags(context, dest, op.SetCondCode); - } - - public static void Fset(EmitterContext context) - { - OpCodeSet op = (OpCodeSet)context.CurrOp; - - Condition cmpOp = (Condition)op.RawOpCode.Extract(48, 4); - - bool negateA = op.RawOpCode.Extract(43); - bool absoluteB = op.RawOpCode.Extract(44); - bool boolFloat = op.RawOpCode.Extract(52); - bool negateB = op.RawOpCode.Extract(53); - bool absoluteA = op.RawOpCode.Extract(54); - - Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA); - Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB); - - Operand res = GetFPComparison(context, cmpOp, srcA, srcB); - - Operand pred = GetPredicate39(context); - - res = GetPredLogicalOp(context, op.LogicalOp, res, pred); - - Operand dest = GetDest(context); - - if (boolFloat) - { - context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0))); - } - else - { - context.Copy(dest, res); - } - - // TODO: CC, X - } - - public static void Fsetp(EmitterContext context) - { - OpCodeSet op = (OpCodeSet)context.CurrOp; - - Condition cmpOp = (Condition)op.RawOpCode.Extract(48, 4); - - bool absoluteA = op.RawOpCode.Extract(7); - bool negateA = op.RawOpCode.Extract(43); - bool absoluteB = op.RawOpCode.Extract(44); - bool negateB = op.RawOpCode.Extract(6); - - Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA); - Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB); - - Operand p0Res = GetFPComparison(context, cmpOp, srcA, srcB); - - Operand p1Res = context.BitwiseNot(p0Res); - - Operand pred = GetPredicate39(context); - - p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred); - p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred); - - context.Copy(Register(op.Predicate3), p0Res); - context.Copy(Register(op.Predicate0), p1Res); - } - - public static void Hadd2(EmitterContext context) - { - Hadd2Hmul2Impl(context, isAdd: true); - } - - public static void Hfma2(EmitterContext context) - { - IOpCodeHfma op = (IOpCodeHfma)context.CurrOp; - - Operand[] srcA = GetHfmaSrcA(context); - Operand[] srcB = GetHfmaSrcB(context); - Operand[] srcC = GetHfmaSrcC(context); - - Operand[] res = new Operand[2]; - - for (int index = 0; index < res.Length; index++) - { - res[index] = context.FPFusedMultiplyAdd(srcA[index], srcB[index], srcC[index]); - - res[index] = context.FPSaturate(res[index], op.Saturate); - } - - context.Copy(GetDest(context), GetHalfPacked(context, res)); - } - - public static void Hmul2(EmitterContext context) - { - Hadd2Hmul2Impl(context, isAdd: false); - } - - private static void Hadd2Hmul2Impl(EmitterContext context, bool isAdd) - { - OpCode op = context.CurrOp; - - bool saturate = op.RawOpCode.Extract(op is OpCodeAluImm32 ? 52 : 32); - - Operand[] srcA = GetHalfSrcA(context); - Operand[] srcB = GetHalfSrcB(context); - - Operand[] res = new Operand[2]; - - for (int index = 0; index < res.Length; index++) - { - if (isAdd) - { - res[index] = context.FPAdd(srcA[index], srcB[index]); - } - else - { - res[index] = context.FPMultiply(srcA[index], srcB[index]); - } - - res[index] = context.FPSaturate(res[index], saturate); - } - - context.Copy(GetDest(context), GetHalfPacked(context, res)); - } - - public static void Mufu(EmitterContext context) - { - IOpCodeFArith op = (IOpCodeFArith)context.CurrOp; - - bool negateB = op.RawOpCode.Extract(48); - - Operand res = context.FPAbsNeg(GetSrcA(context), op.AbsoluteA, negateB); - - MufuOperation subOp = (MufuOperation)context.CurrOp.RawOpCode.Extract(20, 4); - - switch (subOp) - { - case MufuOperation.Cosine: - res = context.FPCosine(res); - break; - - case MufuOperation.Sine: - res = context.FPSine(res); - break; - - case MufuOperation.ExponentB2: - res = context.FPExponentB2(res); - break; - - case MufuOperation.LogarithmB2: - res = context.FPLogarithmB2(res); - break; - - case MufuOperation.Reciprocal: - res = context.FPReciprocal(res); - break; - - case MufuOperation.ReciprocalSquareRoot: - res = context.FPReciprocalSquareRoot(res); - break; - - case MufuOperation.SquareRoot: - res = context.FPSquareRoot(res); - break; - - default: /* TODO */ break; - } - - context.Copy(GetDest(context), context.FPSaturate(res, op.Saturate)); - } - - private static Operand GetFPComparison( - EmitterContext context, - Condition cond, - Operand srcA, - Operand srcB) - { - Operand res; - - if (cond == Condition.Always) - { - res = Const(IrConsts.True); - } - else if (cond == Condition.Never) - { - res = Const(IrConsts.False); - } - else if (cond == Condition.Nan || cond == Condition.Number) - { - res = context.BitwiseOr(context.IsNan(srcA), context.IsNan(srcB)); - - if (cond == Condition.Number) - { - res = context.BitwiseNot(res); - } - } - else - { - Instruction inst; - - switch (cond & ~Condition.Nan) - { - case Condition.Less: inst = Instruction.CompareLess; break; - case Condition.Equal: inst = Instruction.CompareEqual; break; - case Condition.LessOrEqual: inst = Instruction.CompareLessOrEqual; break; - case Condition.Greater: inst = Instruction.CompareGreater; break; - case Condition.NotEqual: inst = Instruction.CompareNotEqual; break; - case Condition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqual; break; - - default: throw new InvalidOperationException($"Unexpected condition \"{cond}\"."); - } - - res = context.Add(inst | Instruction.FP, Local(), srcA, srcB); - - if ((cond & Condition.Nan) != 0) - { - res = context.BitwiseOr(res, context.IsNan(srcA)); - res = context.BitwiseOr(res, context.IsNan(srcB)); - } - } - - return res; - } - - private static void SetFPZnFlags(EmitterContext context, Operand dest, bool setCC) - { - if (setCC) - { - context.Copy(GetZF(context), context.FPCompareEqual(dest, ConstF(0))); - context.Copy(GetNF(context), context.FPCompareLess (dest, ConstF(0))); - } - } - - private static Operand[] GetHfmaSrcA(EmitterContext context) - { - IOpCodeHfma op = (IOpCodeHfma)context.CurrOp; - - return GetHalfSources(context, GetSrcA(context), op.SwizzleA); - } - - private static Operand[] GetHfmaSrcB(EmitterContext context) - { - IOpCodeHfma op = (IOpCodeHfma)context.CurrOp; - - Operand[] operands = GetHalfSources(context, GetSrcB(context), op.SwizzleB); - - return FPAbsNeg(context, operands, false, op.NegateB); - } - - private static Operand[] GetHfmaSrcC(EmitterContext context) - { - IOpCodeHfma op = (IOpCodeHfma)context.CurrOp; - - Operand[] operands = GetHalfSources(context, GetSrcC(context), op.SwizzleC); - - return FPAbsNeg(context, operands, false, op.NegateC); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs deleted file mode 100644 index fb76e06a..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs +++ /dev/null @@ -1,107 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System.Collections.Generic; -using System.Linq; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Bra(EmitterContext context) - { - EmitBranch(context, context.CurrBlock.Branch.Address); - } - - public static void Exit(EmitterContext context) - { - OpCodeExit op = (OpCodeExit)context.CurrOp; - - // TODO: Figure out how this is supposed to work in the - // presence of other condition codes. - if (op.Condition == Condition.Always) - { - context.Return(); - } - } - - public static void Kil(EmitterContext context) - { - context.Discard(); - } - - public static void Ssy(EmitterContext context) - { - OpCodeSsy op = (OpCodeSsy)context.CurrOp; - - foreach (KeyValuePair<OpCodeSync, Operand> kv in op.Syncs) - { - OpCodeSync opSync = kv.Key; - - Operand local = kv.Value; - - int ssyIndex = opSync.Targets[op]; - - context.Copy(local, Const(ssyIndex)); - } - } - - public static void Sync(EmitterContext context) - { - OpCodeSync op = (OpCodeSync)context.CurrOp; - - if (op.Targets.Count == 1) - { - // If we have only one target, then the SSY is basically - // a branch, we can produce better codegen for this case. - OpCodeSsy opSsy = op.Targets.Keys.First(); - - EmitBranch(context, opSsy.GetAbsoluteAddress()); - } - else - { - foreach (KeyValuePair<OpCodeSsy, int> kv in op.Targets) - { - OpCodeSsy opSsy = kv.Key; - - Operand label = context.GetLabel(opSsy.GetAbsoluteAddress()); - - Operand local = opSsy.Syncs[op]; - - int ssyIndex = kv.Value; - - context.BranchIfTrue(label, context.ICompareEqual(local, Const(ssyIndex))); - } - } - } - - private static void EmitBranch(EmitterContext context, ulong address) - { - // If we're branching to the next instruction, then the branch - // is useless and we can ignore it. - if (address == context.CurrOp.Address + 8) - { - return; - } - - Operand label = context.GetLabel(address); - - Operand pred = Register(context.CurrOp.Predicate); - - if (context.CurrOp.Predicate.IsPT) - { - context.Branch(label); - } - else if (context.CurrOp.InvertPredicate) - { - context.BranchIfFalse(label, pred); - } - else - { - context.BranchIfTrue(label, pred); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs deleted file mode 100644 index c87e1789..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs +++ /dev/null @@ -1,267 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static class InstEmitHelper - { - public static Operand GetZF(EmitterContext context) - { - return Register(0, RegisterType.Flag); - } - - public static Operand GetNF(EmitterContext context) - { - return Register(1, RegisterType.Flag); - } - - public static Operand GetCF(EmitterContext context) - { - return Register(2, RegisterType.Flag); - } - - public static Operand GetVF(EmitterContext context) - { - return Register(3, RegisterType.Flag); - } - - public static Operand GetDest(EmitterContext context) - { - return Register(((IOpCodeRd)context.CurrOp).Rd); - } - - public static Operand GetSrcA(EmitterContext context) - { - return Register(((IOpCodeRa)context.CurrOp).Ra); - } - - public static Operand GetSrcB(EmitterContext context, FPType floatType) - { - if (floatType == FPType.FP32) - { - return GetSrcB(context); - } - else if (floatType == FPType.FP16) - { - int h = context.CurrOp.RawOpCode.Extract(41, 1); - - return GetHalfSources(context, GetSrcB(context), FPHalfSwizzle.FP16)[h]; - } - else if (floatType == FPType.FP64) - { - // TODO. - } - - throw new ArgumentException($"Invalid floating point type \"{floatType}\"."); - } - - public static Operand GetSrcB(EmitterContext context) - { - switch (context.CurrOp) - { - case IOpCodeCbuf op: - return Cbuf(op.Slot, op.Offset); - - case IOpCodeImm op: - return Const(op.Immediate); - - case IOpCodeImmF op: - return ConstF(op.Immediate); - - case IOpCodeReg op: - return Register(op.Rb); - - case IOpCodeRegCbuf op: - return Register(op.Rc); - } - - throw new InvalidOperationException($"Unexpected opcode type \"{context.CurrOp.GetType().Name}\"."); - } - - public static Operand GetSrcC(EmitterContext context) - { - switch (context.CurrOp) - { - case IOpCodeRegCbuf op: - return Cbuf(op.Slot, op.Offset); - - case IOpCodeRc op: - return Register(op.Rc); - } - - throw new InvalidOperationException($"Unexpected opcode type \"{context.CurrOp.GetType().Name}\"."); - } - - public static Operand[] GetHalfSrcA(EmitterContext context) - { - OpCode op = context.CurrOp; - - bool absoluteA = false, negateA = false; - - if (op is IOpCodeCbuf || op is IOpCodeImm) - { - negateA = op.RawOpCode.Extract(43); - absoluteA = op.RawOpCode.Extract(44); - } - else if (op is IOpCodeReg) - { - absoluteA = op.RawOpCode.Extract(44); - } - else if (op is OpCodeAluImm32 && op.Emitter == InstEmit.Hadd2) - { - negateA = op.RawOpCode.Extract(56); - } - - FPHalfSwizzle swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(47, 2); - - Operand[] operands = GetHalfSources(context, GetSrcA(context), swizzle); - - return FPAbsNeg(context, operands, absoluteA, negateA); - } - - public static Operand[] GetHalfSrcB(EmitterContext context) - { - OpCode op = context.CurrOp; - - FPHalfSwizzle swizzle = FPHalfSwizzle.FP16; - - bool absoluteB = false, negateB = false; - - if (op is IOpCodeReg) - { - swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(28, 2); - - absoluteB = op.RawOpCode.Extract(30); - negateB = op.RawOpCode.Extract(31); - } - else if (op is IOpCodeCbuf) - { - swizzle = FPHalfSwizzle.FP32; - - absoluteB = op.RawOpCode.Extract(54); - } - - Operand[] operands = GetHalfSources(context, GetSrcB(context), swizzle); - - return FPAbsNeg(context, operands, absoluteB, negateB); - } - - public static Operand[] FPAbsNeg(EmitterContext context, Operand[] operands, bool abs, bool neg) - { - for (int index = 0; index < operands.Length; index++) - { - operands[index] = context.FPAbsNeg(operands[index], abs, neg); - } - - return operands; - } - - public static Operand[] GetHalfSources(EmitterContext context, Operand src, FPHalfSwizzle swizzle) - { - switch (swizzle) - { - case FPHalfSwizzle.FP16: - return new Operand[] - { - context.UnpackHalf2x16Low (src), - context.UnpackHalf2x16High(src) - }; - - case FPHalfSwizzle.FP32: return new Operand[] { src, src }; - - case FPHalfSwizzle.DupH0: - return new Operand[] - { - context.UnpackHalf2x16Low(src), - context.UnpackHalf2x16Low(src) - }; - - case FPHalfSwizzle.DupH1: - return new Operand[] - { - context.UnpackHalf2x16High(src), - context.UnpackHalf2x16High(src) - }; - } - - throw new ArgumentException($"Invalid swizzle \"{swizzle}\"."); - } - - public static Operand GetHalfPacked(EmitterContext context, Operand[] results) - { - OpCode op = context.CurrOp; - - FPHalfSwizzle swizzle = FPHalfSwizzle.FP16; - - if (!(op is OpCodeAluImm32)) - { - swizzle = (FPHalfSwizzle)context.CurrOp.RawOpCode.Extract(49, 2); - } - - switch (swizzle) - { - case FPHalfSwizzle.FP16: return context.PackHalf2x16(results[0], results[1]); - - case FPHalfSwizzle.FP32: return results[0]; - - case FPHalfSwizzle.DupH0: - { - Operand h1 = GetHalfDest(context, isHigh: true); - - return context.PackHalf2x16(results[0], h1); - } - - case FPHalfSwizzle.DupH1: - { - Operand h0 = GetHalfDest(context, isHigh: false); - - return context.PackHalf2x16(h0, results[1]); - } - } - - throw new ArgumentException($"Invalid swizzle \"{swizzle}\"."); - } - - public static Operand GetHalfDest(EmitterContext context, bool isHigh) - { - if (isHigh) - { - return context.UnpackHalf2x16High(GetDest(context)); - } - else - { - return context.UnpackHalf2x16Low(GetDest(context)); - } - } - - public static Operand GetPredicate39(EmitterContext context) - { - IOpCodeAlu op = (IOpCodeAlu)context.CurrOp; - - Operand local = Register(op.Predicate39); - - if (op.InvertP) - { - local = context.BitwiseNot(local); - } - - return local; - } - - public static Operand SignExtendTo32(EmitterContext context, Operand src, int srcBits) - { - return context.BitfieldExtractS32(src, Const(0), Const(srcBits)); - } - - public static Operand ZeroExtendTo32(EmitterContext context, Operand src, int srcBits) - { - int mask = (int)(0xffffffffu >> (32 - srcBits)); - - return context.BitwiseAnd(src, Const(mask)); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs deleted file mode 100644 index a2a50fce..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs +++ /dev/null @@ -1,138 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Ald(EmitterContext context) - { - OpCodeAttribute op = (OpCodeAttribute)context.CurrOp; - - Operand[] elems = new Operand[op.Count]; - - for (int index = 0; index < op.Count; index++) - { - Operand src = Attribute(op.AttributeOffset + index * 4); - - context.Copy(elems[index] = Local(), src); - } - - for (int index = 0; index < op.Count; index++) - { - Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr); - - if (rd.IsRZ) - { - break; - } - - context.Copy(Register(rd), elems[index]); - } - } - - public static void Ast(EmitterContext context) - { - OpCodeAttribute op = (OpCodeAttribute)context.CurrOp; - - for (int index = 0; index < op.Count; index++) - { - if (op.Rd.Index + index > RegisterConsts.RegisterZeroIndex) - { - break; - } - - Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr); - - Operand dest = Attribute(op.AttributeOffset + index * 4); - - context.Copy(dest, Register(rd)); - } - } - - public static void Ipa(EmitterContext context) - { - OpCodeIpa op = (OpCodeIpa)context.CurrOp; - - Operand srcA = new Operand(OperandType.Attribute, op.AttributeOffset); - - Operand srcB = GetSrcB(context); - - context.Copy(GetDest(context), srcA); - } - - public static void Ldc(EmitterContext context) - { - OpCodeLdc op = (OpCodeLdc)context.CurrOp; - - if (op.Size > IntegerSize.B64) - { - // TODO: Warning. - } - - bool isSmallInt = op.Size < IntegerSize.B32; - - int count = op.Size == IntegerSize.B64 ? 2 : 1; - - Operand baseOffset = context.Copy(GetSrcA(context)); - - for (int index = 0; index < count; index++) - { - Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr); - - if (rd.IsRZ) - { - break; - } - - Operand offset = context.IAdd(baseOffset, Const((op.Offset + index) * 4)); - - Operand value = context.LoadConstant(Const(op.Slot), offset); - - if (isSmallInt) - { - Operand shift = context.BitwiseAnd(baseOffset, Const(3)); - - value = context.ShiftRightU32(value, shift); - - switch (op.Size) - { - case IntegerSize.U8: value = ZeroExtendTo32(context, value, 8); break; - case IntegerSize.U16: value = ZeroExtendTo32(context, value, 16); break; - case IntegerSize.S8: value = SignExtendTo32(context, value, 8); break; - case IntegerSize.S16: value = SignExtendTo32(context, value, 16); break; - } - } - - context.Copy(Register(rd), value); - } - } - - public static void Out(EmitterContext context) - { - OpCode op = context.CurrOp; - - bool emit = op.RawOpCode.Extract(39); - bool cut = op.RawOpCode.Extract(40); - - if (!(emit || cut)) - { - // TODO: Warning. - } - - if (emit) - { - context.EmitVertex(); - } - - if (cut) - { - context.EndPrimitive(); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs deleted file mode 100644 index b74dbfd7..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Mov(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - context.Copy(GetDest(context), GetSrcB(context)); - } - - public static void Sel(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - Operand pred = GetPredicate39(context); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - Operand res = context.ConditionalSelect(pred, srcA, srcB); - - context.Copy(GetDest(context), res); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs deleted file mode 100644 index a9b29f40..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs +++ /dev/null @@ -1,776 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Tex(EmitterContext context) - { - Tex(context, TextureFlags.None); - } - - public static void Tex_B(EmitterContext context) - { - Tex(context, TextureFlags.Bindless); - } - - public static void Tld(EmitterContext context) - { - Tex(context, TextureFlags.IntCoords); - } - - public static void Tld_B(EmitterContext context) - { - Tex(context, TextureFlags.IntCoords | TextureFlags.Bindless); - } - - public static void Texs(EmitterContext context) - { - OpCodeTextureScalar op = (OpCodeTextureScalar)context.CurrOp; - - if (op.Rd0.IsRZ && op.Rd1.IsRZ) - { - return; - } - - List<Operand> sourcesList = new List<Operand>(); - - int raIndex = op.Ra.Index; - int rbIndex = op.Rb.Index; - - Operand Ra() - { - if (raIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(raIndex++, RegisterType.Gpr)); - } - - Operand Rb() - { - if (rbIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(rbIndex++, RegisterType.Gpr)); - } - - void AddTextureOffset(int coordsCount, int stride, int size) - { - Operand packedOffs = Rb(); - - for (int index = 0; index < coordsCount; index++) - { - sourcesList.Add(context.BitfieldExtractS32(packedOffs, Const(index * stride), Const(size))); - } - } - - TextureType type; - TextureFlags flags; - - if (op is OpCodeTexs texsOp) - { - type = GetTextureType (texsOp.Type); - flags = GetTextureFlags(texsOp.Type); - - if ((type & TextureType.Array) != 0) - { - Operand arrayIndex = Ra(); - - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - - sourcesList.Add(arrayIndex); - - if ((type & TextureType.Shadow) != 0) - { - sourcesList.Add(Rb()); - } - - if ((flags & TextureFlags.LodLevel) != 0) - { - sourcesList.Add(ConstF(0)); - } - } - else - { - switch (texsOp.Type) - { - case TextureScalarType.Texture1DLodZero: - sourcesList.Add(Ra()); - break; - - case TextureScalarType.Texture2D: - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - break; - - case TextureScalarType.Texture2DLodZero: - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - sourcesList.Add(ConstF(0)); - break; - - case TextureScalarType.Texture2DLodLevel: - case TextureScalarType.Texture2DDepthCompare: - case TextureScalarType.Texture3D: - case TextureScalarType.TextureCube: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - break; - - case TextureScalarType.Texture2DLodZeroDepthCompare: - case TextureScalarType.Texture3DLodZero: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - sourcesList.Add(ConstF(0)); - break; - - case TextureScalarType.Texture2DLodLevelDepthCompare: - case TextureScalarType.TextureCubeLodLevel: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - sourcesList.Add(Rb()); - break; - } - } - } - else if (op is OpCodeTlds tldsOp) - { - type = GetTextureType (tldsOp.Type); - flags = GetTextureFlags(tldsOp.Type) | TextureFlags.IntCoords; - - switch (tldsOp.Type) - { - case TexelLoadScalarType.Texture1DLodZero: - sourcesList.Add(Ra()); - sourcesList.Add(Const(0)); - break; - - case TexelLoadScalarType.Texture1DLodLevel: - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - break; - - case TexelLoadScalarType.Texture2DLodZero: - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - sourcesList.Add(Const(0)); - break; - - case TexelLoadScalarType.Texture2DLodZeroOffset: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Const(0)); - break; - - case TexelLoadScalarType.Texture2DLodZeroMultisample: - case TexelLoadScalarType.Texture2DLodLevel: - case TexelLoadScalarType.Texture2DLodLevelOffset: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - break; - - case TexelLoadScalarType.Texture3DLodZero: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - sourcesList.Add(Const(0)); - break; - - case TexelLoadScalarType.Texture2DArrayLodZero: - sourcesList.Add(Rb()); - sourcesList.Add(Rb()); - sourcesList.Add(Ra()); - sourcesList.Add(Const(0)); - break; - } - - if ((flags & TextureFlags.Offset) != 0) - { - AddTextureOffset(type.GetCoordsCount(), 4, 4); - } - } - else if (op is OpCodeTld4s tld4sOp) - { - if (!(tld4sOp.HasDepthCompare || tld4sOp.HasOffset)) - { - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - } - else - { - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - } - - type = TextureType.Texture2D; - flags = TextureFlags.Gather; - - if (tld4sOp.HasDepthCompare) - { - sourcesList.Add(Rb()); - - type |= TextureType.Shadow; - } - - if (tld4sOp.HasOffset) - { - AddTextureOffset(type.GetCoordsCount(), 8, 6); - - flags |= TextureFlags.Offset; - } - - sourcesList.Add(Const(tld4sOp.GatherCompIndex)); - } - else - { - throw new InvalidOperationException($"Invalid opcode type \"{op.GetType().Name}\"."); - } - - Operand[] sources = sourcesList.ToArray(); - - Operand[] rd0 = new Operand[2] { ConstF(0), ConstF(0) }; - Operand[] rd1 = new Operand[2] { ConstF(0), ConstF(0) }; - - int destIncrement = 0; - - Operand GetDest() - { - int high = destIncrement >> 1; - int low = destIncrement & 1; - - destIncrement++; - - if (op.IsFp16) - { - return high != 0 - ? (rd1[low] = Local()) - : (rd0[low] = Local()); - } - else - { - int rdIndex = high != 0 ? op.Rd1.Index : op.Rd0.Index; - - if (rdIndex < RegisterConsts.RegisterZeroIndex) - { - rdIndex += low; - } - - return Register(rdIndex, RegisterType.Gpr); - } - } - - int handle = op.Immediate; - - for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) - { - if ((compMask & 1) != 0) - { - Operand dest = GetDest(); - - TextureOperation operation = new TextureOperation( - Instruction.TextureSample, - type, - flags, - handle, - compIndex, - dest, - sources); - - context.Add(operation); - } - } - - if (op.IsFp16) - { - context.Copy(Register(op.Rd0), context.PackHalf2x16(rd0[0], rd0[1])); - context.Copy(Register(op.Rd1), context.PackHalf2x16(rd1[0], rd1[1])); - } - } - - public static void Tld4(EmitterContext context) - { - OpCodeTld4 op = (OpCodeTld4)context.CurrOp; - - if (op.Rd.IsRZ) - { - return; - } - - int raIndex = op.Ra.Index; - int rbIndex = op.Rb.Index; - - Operand Ra() - { - if (raIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(raIndex++, RegisterType.Gpr)); - } - - Operand Rb() - { - if (rbIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(rbIndex++, RegisterType.Gpr)); - } - - Operand arrayIndex = op.IsArray ? Ra() : null; - - List<Operand> sourcesList = new List<Operand>(); - - TextureType type = GetTextureType(op.Dimensions); - - TextureFlags flags = TextureFlags.Gather; - - int coordsCount = type.GetCoordsCount(); - - for (int index = 0; index < coordsCount; index++) - { - sourcesList.Add(Ra()); - } - - if (op.IsArray) - { - sourcesList.Add(arrayIndex); - - type |= TextureType.Array; - } - - Operand[] packedOffs = new Operand[2]; - - packedOffs[0] = op.Offset != TextureGatherOffset.None ? Rb() : null; - packedOffs[1] = op.Offset == TextureGatherOffset.Offsets ? Rb() : null; - - if (op.HasDepthCompare) - { - sourcesList.Add(Rb()); - - type |= TextureType.Shadow; - } - - if (op.Offset != TextureGatherOffset.None) - { - int offsetTexelsCount = op.Offset == TextureGatherOffset.Offsets ? 4 : 1; - - for (int index = 0; index < coordsCount * offsetTexelsCount; index++) - { - Operand packed = packedOffs[(index >> 2) & 1]; - - sourcesList.Add(context.BitfieldExtractS32(packed, Const((index & 3) * 8), Const(6))); - } - - flags |= op.Offset == TextureGatherOffset.Offsets - ? TextureFlags.Offsets - : TextureFlags.Offset; - } - - sourcesList.Add(Const(op.GatherCompIndex)); - - Operand[] sources = sourcesList.ToArray(); - - int rdIndex = op.Rd.Index; - - Operand GetDest() - { - if (rdIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return Register(rdIndex++, RegisterType.Gpr); - } - - int handle = op.Immediate; - - for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) - { - if ((compMask & 1) != 0) - { - Operand dest = GetDest(); - - TextureOperation operation = new TextureOperation( - Instruction.TextureSample, - type, - flags, - handle, - compIndex, - dest, - sources); - - context.Add(operation); - } - } - } - - public static void Txq(EmitterContext context) - { - Txq(context, bindless: false); - } - - public static void Txq_B(EmitterContext context) - { - Txq(context, bindless: true); - } - - private static void Txq(EmitterContext context, bool bindless) - { - OpCodeTex op = (OpCodeTex)context.CurrOp; - - if (op.Rd.IsRZ) - { - return; - } - - TextureProperty property = (TextureProperty)op.RawOpCode.Extract(22, 6); - - // TODO: Validate and use property. - Instruction inst = Instruction.TextureSize; - - TextureType type = TextureType.Texture2D; - - TextureFlags flags = bindless ? TextureFlags.Bindless : TextureFlags.None; - - int raIndex = op.Ra.Index; - - Operand Ra() - { - if (raIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(raIndex++, RegisterType.Gpr)); - } - - List<Operand> sourcesList = new List<Operand>(); - - if (bindless) - { - sourcesList.Add(Ra()); - } - - sourcesList.Add(Ra()); - - Operand[] sources = sourcesList.ToArray(); - - int rdIndex = op.Rd.Index; - - Operand GetDest() - { - if (rdIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return Register(rdIndex++, RegisterType.Gpr); - } - - int handle = !bindless ? op.Immediate : 0; - - for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) - { - if ((compMask & 1) != 0) - { - Operand dest = GetDest(); - - TextureOperation operation = new TextureOperation( - inst, - type, - flags, - handle, - compIndex, - dest, - sources); - - context.Add(operation); - } - } - } - - private static void Tex(EmitterContext context, TextureFlags flags) - { - OpCodeTexture op = (OpCodeTexture)context.CurrOp; - - bool isBindless = (flags & TextureFlags.Bindless) != 0; - bool intCoords = (flags & TextureFlags.IntCoords) != 0; - - if (op.Rd.IsRZ) - { - return; - } - - int raIndex = op.Ra.Index; - int rbIndex = op.Rb.Index; - - Operand Ra() - { - if (raIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(raIndex++, RegisterType.Gpr)); - } - - Operand Rb() - { - if (rbIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(rbIndex++, RegisterType.Gpr)); - } - - Operand arrayIndex = op.IsArray ? Ra() : null; - - List<Operand> sourcesList = new List<Operand>(); - - if (isBindless) - { - sourcesList.Add(Rb()); - } - - TextureType type = GetTextureType(op.Dimensions); - - int coordsCount = type.GetCoordsCount(); - - for (int index = 0; index < coordsCount; index++) - { - sourcesList.Add(Ra()); - } - - if (op.IsArray) - { - sourcesList.Add(arrayIndex); - - type |= TextureType.Array; - } - - bool hasLod = op.LodMode > TextureLodMode.LodZero; - - Operand lodValue = hasLod ? Rb() : ConstF(0); - - Operand packedOffs = op.HasOffset ? Rb() : null; - - if (op.HasDepthCompare) - { - sourcesList.Add(Rb()); - - type |= TextureType.Shadow; - } - - if ((op.LodMode == TextureLodMode.LodZero || - op.LodMode == TextureLodMode.LodLevel || - op.LodMode == TextureLodMode.LodLevelA) && !op.IsMultisample) - { - sourcesList.Add(lodValue); - - flags |= TextureFlags.LodLevel; - } - - if (op.HasOffset) - { - for (int index = 0; index < coordsCount; index++) - { - sourcesList.Add(context.BitfieldExtractS32(packedOffs, Const(index * 4), Const(4))); - } - - flags |= TextureFlags.Offset; - } - - if (op.LodMode == TextureLodMode.LodBias || - op.LodMode == TextureLodMode.LodBiasA) - { - sourcesList.Add(lodValue); - - flags |= TextureFlags.LodBias; - } - - if (op.IsMultisample) - { - sourcesList.Add(Rb()); - - type |= TextureType.Multisample; - } - - Operand[] sources = sourcesList.ToArray(); - - int rdIndex = op.Rd.Index; - - Operand GetDest() - { - if (rdIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return Register(rdIndex++, RegisterType.Gpr); - } - - int handle = !isBindless ? op.Immediate : 0; - - for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) - { - if ((compMask & 1) != 0) - { - Operand dest = GetDest(); - - TextureOperation operation = new TextureOperation( - Instruction.TextureSample, - type, - flags, - handle, - compIndex, - dest, - sources); - - context.Add(operation); - } - } - } - - private static TextureType GetTextureType(TextureDimensions dimensions) - { - switch (dimensions) - { - case TextureDimensions.Texture1D: return TextureType.Texture1D; - case TextureDimensions.Texture2D: return TextureType.Texture2D; - case TextureDimensions.Texture3D: return TextureType.Texture3D; - case TextureDimensions.TextureCube: return TextureType.TextureCube; - } - - throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\"."); - } - - private static TextureType GetTextureType(TextureScalarType type) - { - switch (type) - { - case TextureScalarType.Texture1DLodZero: - return TextureType.Texture1D; - - case TextureScalarType.Texture2D: - case TextureScalarType.Texture2DLodZero: - case TextureScalarType.Texture2DLodLevel: - return TextureType.Texture2D; - - case TextureScalarType.Texture2DDepthCompare: - case TextureScalarType.Texture2DLodLevelDepthCompare: - case TextureScalarType.Texture2DLodZeroDepthCompare: - return TextureType.Texture2D | TextureType.Shadow; - - case TextureScalarType.Texture2DArray: - case TextureScalarType.Texture2DArrayLodZero: - return TextureType.Texture2D | TextureType.Array; - - case TextureScalarType.Texture2DArrayLodZeroDepthCompare: - return TextureType.Texture2D | TextureType.Array | TextureType.Shadow; - - case TextureScalarType.Texture3D: - case TextureScalarType.Texture3DLodZero: - return TextureType.Texture3D; - - case TextureScalarType.TextureCube: - case TextureScalarType.TextureCubeLodLevel: - return TextureType.TextureCube; - } - - throw new ArgumentException($"Invalid texture type \"{type}\"."); - } - - private static TextureType GetTextureType(TexelLoadScalarType type) - { - switch (type) - { - case TexelLoadScalarType.Texture1DLodZero: - case TexelLoadScalarType.Texture1DLodLevel: - return TextureType.Texture1D; - - case TexelLoadScalarType.Texture2DLodZero: - case TexelLoadScalarType.Texture2DLodZeroOffset: - case TexelLoadScalarType.Texture2DLodLevel: - case TexelLoadScalarType.Texture2DLodLevelOffset: - return TextureType.Texture2D; - - case TexelLoadScalarType.Texture2DLodZeroMultisample: - return TextureType.Texture2D | TextureType.Multisample; - - case TexelLoadScalarType.Texture3DLodZero: - return TextureType.Texture3D; - - case TexelLoadScalarType.Texture2DArrayLodZero: - return TextureType.Texture2D | TextureType.Array; - } - - throw new ArgumentException($"Invalid texture type \"{type}\"."); - } - - private static TextureFlags GetTextureFlags(TextureScalarType type) - { - switch (type) - { - case TextureScalarType.Texture1DLodZero: - case TextureScalarType.Texture2DLodZero: - case TextureScalarType.Texture2DLodLevel: - case TextureScalarType.Texture2DLodLevelDepthCompare: - case TextureScalarType.Texture2DLodZeroDepthCompare: - case TextureScalarType.Texture2DArrayLodZero: - case TextureScalarType.Texture2DArrayLodZeroDepthCompare: - case TextureScalarType.Texture3DLodZero: - case TextureScalarType.TextureCubeLodLevel: - return TextureFlags.LodLevel; - - case TextureScalarType.Texture2D: - case TextureScalarType.Texture2DDepthCompare: - case TextureScalarType.Texture2DArray: - case TextureScalarType.Texture3D: - case TextureScalarType.TextureCube: - return TextureFlags.None; - } - - throw new ArgumentException($"Invalid texture type \"{type}\"."); - } - - private static TextureFlags GetTextureFlags(TexelLoadScalarType type) - { - switch (type) - { - case TexelLoadScalarType.Texture1DLodZero: - case TexelLoadScalarType.Texture1DLodLevel: - case TexelLoadScalarType.Texture2DLodZero: - case TexelLoadScalarType.Texture2DLodLevel: - case TexelLoadScalarType.Texture2DLodZeroMultisample: - case TexelLoadScalarType.Texture3DLodZero: - case TexelLoadScalarType.Texture2DArrayLodZero: - return TextureFlags.LodLevel; - - case TexelLoadScalarType.Texture2DLodZeroOffset: - case TexelLoadScalarType.Texture2DLodLevelOffset: - return TextureFlags.LodLevel | TextureFlags.Offset; - } - - throw new ArgumentException($"Invalid texture type \"{type}\"."); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs deleted file mode 100644 index 91c740b6..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Ryujinx.Graphics.Shader.Translation; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - delegate void InstEmitter(EmitterContext context); -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs b/Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs deleted file mode 100644 index 67e24957..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs +++ /dev/null @@ -1,149 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static class Lop3Expression - { - public static Operand GetFromTruthTable( - EmitterContext context, - Operand srcA, - Operand srcB, - Operand srcC, - int imm) - { - Operand expr = null; - - // Handle some simple cases, or cases where - // the KMap would yield poor results (like XORs). - if (imm == 0x96 || imm == 0x69) - { - // XOR (0x96) and XNOR (0x69). - if (imm == 0x69) - { - srcA = context.BitwiseNot(srcA); - } - - expr = context.BitwiseExclusiveOr(srcA, srcB); - expr = context.BitwiseExclusiveOr(expr, srcC); - - return expr; - } - else if (imm == 0) - { - // Always false. - return Const(IrConsts.False); - } - else if (imm == 0xff) - { - // Always true. - return Const(IrConsts.True); - } - - int map; - - // Encode into gray code. - map = ((imm >> 0) & 1) << 0; - map |= ((imm >> 1) & 1) << 4; - map |= ((imm >> 2) & 1) << 1; - map |= ((imm >> 3) & 1) << 5; - map |= ((imm >> 4) & 1) << 3; - map |= ((imm >> 5) & 1) << 7; - map |= ((imm >> 6) & 1) << 2; - map |= ((imm >> 7) & 1) << 6; - - // Solve KMap, get sum of products. - int visited = 0; - - for (int index = 0; index < 8 && visited != 0xff; index++) - { - if ((map & (1 << index)) == 0) - { - continue; - } - - int mask = 0; - - for (int mSize = 4; mSize != 0; mSize >>= 1) - { - mask = RotateLeft4((1 << mSize) - 1, index & 3) << (index & 4); - - if ((map & mask) == mask) - { - break; - } - } - - // The mask should wrap, if we are on the high row, shift to low etc. - int mask2 = (index & 4) != 0 ? mask >> 4 : mask << 4; - - if ((map & mask2) == mask2) - { - mask |= mask2; - } - - if ((mask & visited) == mask) - { - continue; - } - - bool notA = (mask & 0x33) != 0; - bool notB = (mask & 0x99) != 0; - bool notC = (mask & 0x0f) != 0; - - bool aChanges = (mask & 0xcc) != 0 && notA; - bool bChanges = (mask & 0x66) != 0 && notB; - bool cChanges = (mask & 0xf0) != 0 && notC; - - Operand localExpr = null; - - void And(Operand source) - { - if (localExpr != null) - { - localExpr = context.BitwiseAnd(localExpr, source); - } - else - { - localExpr = source; - } - } - - if (!aChanges) - { - And(context.BitwiseNot(srcA, notA)); - } - - if (!bChanges) - { - And(context.BitwiseNot(srcB, notB)); - } - - if (!cChanges) - { - And(context.BitwiseNot(srcC, notC)); - } - - if (expr != null) - { - expr = context.BitwiseOr(expr, localExpr); - } - else - { - expr = localExpr; - } - - visited |= mask; - } - - return expr; - } - - private static int RotateLeft4(int value, int shift) - { - return ((value << shift) | (value >> (4 - shift))) & 0xf; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/BasicBlock.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/BasicBlock.cs deleted file mode 100644 index 94975337..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/BasicBlock.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - class BasicBlock - { - public int Index { get; set; } - - public LinkedList<INode> Operations { get; } - - private BasicBlock _next; - private BasicBlock _branch; - - public BasicBlock Next - { - get => _next; - set => _next = AddSuccessor(_next, value); - } - - public BasicBlock Branch - { - get => _branch; - set => _branch = AddSuccessor(_branch, value); - } - - public bool HasBranch => _branch != null; - - public List<BasicBlock> Predecessors { get; } - - public HashSet<BasicBlock> DominanceFrontiers { get; } - - public BasicBlock ImmediateDominator { get; set; } - - public BasicBlock() - { - Operations = new LinkedList<INode>(); - - Predecessors = new List<BasicBlock>(); - - DominanceFrontiers = new HashSet<BasicBlock>(); - } - - public BasicBlock(int index) : this() - { - Index = index; - } - - private BasicBlock AddSuccessor(BasicBlock oldBlock, BasicBlock newBlock) - { - oldBlock?.Predecessors.Remove(this); - newBlock?.Predecessors.Add(this); - - return newBlock; - } - - public INode GetLastOp() - { - return Operations.Last?.Value; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/INode.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/INode.cs deleted file mode 100644 index 48dda24b..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/INode.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - interface INode - { - Operand Dest { get; set; } - - int SourcesCount { get; } - - Operand GetSource(int index); - - void SetSource(int index, Operand operand); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Instruction.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/Instruction.cs deleted file mode 100644 index ac0ebc2b..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Instruction.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - [Flags] - enum Instruction - { - Absolute = 1, - Add, - BitfieldExtractS32, - BitfieldExtractU32, - BitfieldInsert, - BitfieldReverse, - BitwiseAnd, - BitwiseExclusiveOr, - BitwiseNot, - BitwiseOr, - Branch, - BranchIfFalse, - BranchIfTrue, - Ceiling, - Clamp, - ClampU32, - CompareEqual, - CompareGreater, - CompareGreaterOrEqual, - CompareGreaterOrEqualU32, - CompareGreaterU32, - CompareLess, - CompareLessOrEqual, - CompareLessOrEqualU32, - CompareLessU32, - CompareNotEqual, - ConditionalSelect, - ConvertFPToS32, - ConvertS32ToFP, - ConvertU32ToFP, - Copy, - Cosine, - Discard, - Divide, - EmitVertex, - EndPrimitive, - ExponentB2, - Floor, - FusedMultiplyAdd, - IsNan, - LoadConstant, - LoadGlobal, - LoadLocal, - LogarithmB2, - LogicalAnd, - LogicalExclusiveOr, - LogicalNot, - LogicalOr, - LoopBreak, - LoopContinue, - MarkLabel, - Maximum, - MaximumU32, - Minimum, - MinimumU32, - Multiply, - Negate, - PackDouble2x32, - PackHalf2x16, - ReciprocalSquareRoot, - Return, - ShiftLeft, - ShiftRightS32, - ShiftRightU32, - Sine, - SquareRoot, - StoreGlobal, - StoreLocal, - Subtract, - TextureSample, - TextureSize, - Truncate, - UnpackDouble2x32, - UnpackHalf2x16, - - Count, - FP = 1 << 16, - Mask = 0xffff - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/IrConsts.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/IrConsts.cs deleted file mode 100644 index c264e47d..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/IrConsts.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - static class IrConsts - { - public const int False = 0; - public const int True = -1; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operand.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operand.cs deleted file mode 100644 index 1df88a3d..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operand.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - class Operand - { - private const int CbufSlotBits = 5; - private const int CbufSlotLsb = 32 - CbufSlotBits; - private const int CbufSlotMask = (1 << CbufSlotBits) - 1; - - public OperandType Type { get; } - - public int Value { get; } - - public INode AsgOp { get; set; } - - public HashSet<INode> UseOps { get; } - - private Operand() - { - UseOps = new HashSet<INode>(); - } - - public Operand(OperandType type) : this() - { - Type = type; - } - - public Operand(OperandType type, int value) : this() - { - Type = type; - Value = value; - } - - public Operand(Register reg) : this() - { - Type = OperandType.Register; - Value = PackRegInfo(reg.Index, reg.Type); - } - - public Operand(int slot, int offset) : this() - { - Type = OperandType.ConstantBuffer; - Value = PackCbufInfo(slot, offset); - } - - private static int PackCbufInfo(int slot, int offset) - { - return (slot << CbufSlotLsb) | offset; - } - - private static int PackRegInfo(int index, RegisterType type) - { - return ((int)type << 24) | index; - } - - public int GetCbufSlot() - { - return (Value >> CbufSlotLsb) & CbufSlotMask; - } - - public int GetCbufOffset() - { - return Value & ~(CbufSlotMask << CbufSlotLsb); - } - - public Register GetRegister() - { - return new Register(Value & 0xffffff, (RegisterType)(Value >> 24)); - } - - public float AsFloat() - { - return BitConverter.Int32BitsToSingle(Value); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandHelper.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandHelper.cs deleted file mode 100644 index 6765f8a4..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandHelper.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using System; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - static class OperandHelper - { - public static Operand Attribute(int value) - { - return new Operand(OperandType.Attribute, value); - } - - public static Operand Cbuf(int slot, int offset) - { - return new Operand(slot, offset); - } - - public static Operand Const(int value) - { - return new Operand(OperandType.Constant, value); - } - - public static Operand ConstF(float value) - { - return new Operand(OperandType.Constant, BitConverter.SingleToInt32Bits(value)); - } - - public static Operand Label() - { - return new Operand(OperandType.Label); - } - - public static Operand Local() - { - return new Operand(OperandType.LocalVariable); - } - - public static Operand Register(int index, RegisterType type) - { - return Register(new Register(index, type)); - } - - public static Operand Register(Register reg) - { - if (reg.IsRZ) - { - return Const(0); - } - else if (reg.IsPT) - { - return Const(IrConsts.True); - } - - return new Operand(reg); - } - - public static Operand Undef() - { - return new Operand(OperandType.Undefined); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandType.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandType.cs deleted file mode 100644 index e0e2a667..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - enum OperandType - { - Attribute, - Constant, - ConstantBuffer, - GlobalMemory, - Label, - LocalMemory, - LocalVariable, - Register, - Undefined - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operation.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operation.cs deleted file mode 100644 index c60f393e..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operation.cs +++ /dev/null @@ -1,101 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - class Operation : INode - { - public Instruction Inst { get; private set; } - - private Operand _dest; - - public Operand Dest - { - get => _dest; - set => _dest = AssignDest(value); - } - - private Operand[] _sources; - - public int SourcesCount => _sources.Length; - - public int ComponentIndex { get; } - - public Operation(Instruction inst, Operand dest, params Operand[] sources) - { - Inst = inst; - Dest = dest; - - // The array may be modified externally, so we store a copy. - _sources = (Operand[])sources.Clone(); - - for (int index = 0; index < _sources.Length; index++) - { - Operand source = _sources[index]; - - if (source.Type == OperandType.LocalVariable) - { - source.UseOps.Add(this); - } - } - } - - public Operation( - Instruction inst, - int compIndex, - Operand dest, - params Operand[] sources) : this(inst, dest, sources) - { - ComponentIndex = compIndex; - } - - private Operand AssignDest(Operand dest) - { - if (dest != null && dest.Type == OperandType.LocalVariable) - { - dest.AsgOp = this; - } - - return dest; - } - - public Operand GetSource(int index) - { - return _sources[index]; - } - - public void SetSource(int index, Operand source) - { - Operand oldSrc = _sources[index]; - - if (oldSrc != null && oldSrc.Type == OperandType.LocalVariable) - { - oldSrc.UseOps.Remove(this); - } - - if (source.Type == OperandType.LocalVariable) - { - source.UseOps.Add(this); - } - - _sources[index] = source; - } - - public void TurnIntoCopy(Operand source) - { - Inst = Instruction.Copy; - - foreach (Operand oldSrc in _sources) - { - if (oldSrc.Type == OperandType.LocalVariable) - { - oldSrc.UseOps.Remove(this); - } - } - - if (source.Type == OperandType.LocalVariable) - { - source.UseOps.Add(this); - } - - _sources = new Operand[] { source }; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/PhiNode.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/PhiNode.cs deleted file mode 100644 index 13ff41bd..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/PhiNode.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - class PhiNode : INode - { - private Operand _dest; - - public Operand Dest - { - get => _dest; - set => _dest = AssignDest(value); - } - - private HashSet<BasicBlock> _blocks; - - private class PhiSource - { - public BasicBlock Block { get; } - public Operand Operand { get; set; } - - public PhiSource(BasicBlock block, Operand operand) - { - Block = block; - Operand = operand; - } - } - - private List<PhiSource> _sources; - - public int SourcesCount => _sources.Count; - - public PhiNode(Operand dest) - { - _blocks = new HashSet<BasicBlock>(); - - _sources = new List<PhiSource>(); - - dest.AsgOp = this; - - Dest = dest; - } - - private Operand AssignDest(Operand dest) - { - if (dest != null && dest.Type == OperandType.LocalVariable) - { - dest.AsgOp = this; - } - - return dest; - } - - public void AddSource(BasicBlock block, Operand operand) - { - if (_blocks.Add(block)) - { - if (operand.Type == OperandType.LocalVariable) - { - operand.UseOps.Add(this); - } - - _sources.Add(new PhiSource(block, operand)); - } - } - - public Operand GetSource(int index) - { - return _sources[index].Operand; - } - - public BasicBlock GetBlock(int index) - { - return _sources[index].Block; - } - - public void SetSource(int index, Operand source) - { - Operand oldSrc = _sources[index].Operand; - - if (oldSrc != null && oldSrc.Type == OperandType.LocalVariable) - { - oldSrc.UseOps.Remove(this); - } - - if (source.Type == OperandType.LocalVariable) - { - source.UseOps.Add(this); - } - - _sources[index].Operand = source; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureFlags.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureFlags.cs deleted file mode 100644 index 5f0a8427..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureFlags.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - [Flags] - enum TextureFlags - { - None = 0, - Bindless = 1 << 0, - Gather = 1 << 1, - IntCoords = 1 << 2, - LodBias = 1 << 3, - LodLevel = 1 << 4, - Offset = 1 << 5, - Offsets = 1 << 6 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureOperation.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureOperation.cs deleted file mode 100644 index f5f2cc5c..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureOperation.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - class TextureOperation : Operation - { - public TextureType Type { get; } - public TextureFlags Flags { get; } - - public int Handle { get; } - - public TextureOperation( - Instruction inst, - TextureType type, - TextureFlags flags, - int handle, - int compIndex, - Operand dest, - params Operand[] sources) : base(inst, compIndex, dest, sources) - { - Type = type; - Flags = flags; - Handle = handle; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureType.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureType.cs deleted file mode 100644 index bf207007..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureType.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - [Flags] - enum TextureType - { - Texture1D, - Texture2D, - Texture3D, - TextureCube, - - Mask = 0xff, - - Array = 1 << 8, - Multisample = 1 << 9, - Shadow = 1 << 10 - } - - static class TextureTypeExtensions - { - public static int GetCoordsCount(this TextureType type) - { - switch (type & TextureType.Mask) - { - case TextureType.Texture1D: return 1; - case TextureType.Texture2D: return 2; - case TextureType.Texture3D: return 3; - case TextureType.TextureCube: return 3; - } - - throw new ArgumentException($"Invalid texture type \"{type}\"."); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/ShaderConfig.cs b/Ryujinx.Graphics/Shader/ShaderConfig.cs deleted file mode 100644 index c2a94814..00000000 --- a/Ryujinx.Graphics/Shader/ShaderConfig.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Ryujinx.Graphics.Gal; -using System; - -namespace Ryujinx.Graphics.Shader -{ - public struct ShaderConfig - { - public GalShaderType Type { get; } - - public int MaxCBufferSize; - - public ShaderConfig(GalShaderType type, int maxCBufferSize) - { - if (maxCBufferSize <= 0) - { - throw new ArgumentOutOfRangeException(nameof(maxCBufferSize)); - } - - Type = type; - MaxCBufferSize = maxCBufferSize; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/ShaderHeader.cs b/Ryujinx.Graphics/Shader/ShaderHeader.cs deleted file mode 100644 index 379f3f35..00000000 --- a/Ryujinx.Graphics/Shader/ShaderHeader.cs +++ /dev/null @@ -1,166 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.Decoders; -using System; - -namespace Ryujinx.Graphics.Shader -{ - struct OutputMapTarget - { - public bool Red { get; } - public bool Green { get; } - public bool Blue { get; } - public bool Alpha { get; } - - public bool Enabled => Red || Green || Blue || Alpha; - - public OutputMapTarget(bool red, bool green, bool blue, bool alpha) - { - Red = red; - Green = green; - Blue = blue; - Alpha = alpha; - } - - public bool ComponentEnabled(int component) - { - switch (component) - { - case 0: return Red; - case 1: return Green; - case 2: return Blue; - case 3: return Alpha; - } - - throw new ArgumentOutOfRangeException(nameof(component)); - } - } - - class ShaderHeader - { - public int SphType { get; } - - public int Version { get; } - - public int ShaderType { get; } - - public bool MrtEnable { get; } - - public bool KillsPixels { get; } - - public bool DoesGlobalStore { get; } - - public int SassVersion { get; } - - public bool DoesLoadOrStore { get; } - - public bool DoesFp64 { get; } - - public int StreamOutMask{ get; } - - public int ShaderLocalMemoryLowSize { get; } - - public int PerPatchAttributeCount { get; } - - public int ShaderLocalMemoryHighSize { get; } - - public int ThreadsPerInputPrimitive { get; } - - public int ShaderLocalMemoryCrsSize { get; } - - public int OutputTopology { get; } - - public int MaxOutputVertexCount { get; } - - public int StoreReqStart { get; } - public int StoreReqEnd { get; } - - public OutputMapTarget[] OmapTargets { get; } - public bool OmapSampleMask { get; } - public bool OmapDepth { get; } - - public ShaderHeader(IGalMemory memory, ulong address) - { - int commonWord0 = memory.ReadInt32((long)address + 0); - int commonWord1 = memory.ReadInt32((long)address + 4); - int commonWord2 = memory.ReadInt32((long)address + 8); - int commonWord3 = memory.ReadInt32((long)address + 12); - int commonWord4 = memory.ReadInt32((long)address + 16); - - SphType = commonWord0.Extract(0, 5); - - Version = commonWord0.Extract(5, 5); - - ShaderType = commonWord0.Extract(10, 4); - - MrtEnable = commonWord0.Extract(14); - - KillsPixels = commonWord0.Extract(15); - - DoesGlobalStore = commonWord0.Extract(16); - - SassVersion = commonWord0.Extract(17, 4); - - DoesLoadOrStore = commonWord0.Extract(26); - - DoesFp64 = commonWord0.Extract(27); - - StreamOutMask = commonWord0.Extract(28, 4); - - ShaderLocalMemoryLowSize = commonWord1.Extract(0, 24); - - PerPatchAttributeCount = commonWord1.Extract(24, 8); - - ShaderLocalMemoryHighSize = commonWord2.Extract(0, 24); - - ThreadsPerInputPrimitive = commonWord2.Extract(24, 8); - - ShaderLocalMemoryCrsSize = commonWord3.Extract(0, 24); - - OutputTopology = commonWord3.Extract(24, 4); - - MaxOutputVertexCount = commonWord4.Extract(0, 12); - - StoreReqStart = commonWord4.Extract(12, 8); - StoreReqEnd = commonWord4.Extract(24, 8); - - int type2OmapTarget = memory.ReadInt32((long)address + 72); - int type2Omap = memory.ReadInt32((long)address + 76); - - OmapTargets = new OutputMapTarget[8]; - - for (int offset = 0; offset < OmapTargets.Length * 4; offset += 4) - { - OmapTargets[offset >> 2] = new OutputMapTarget( - type2OmapTarget.Extract(offset + 0), - type2OmapTarget.Extract(offset + 1), - type2OmapTarget.Extract(offset + 2), - type2OmapTarget.Extract(offset + 3)); - } - - OmapSampleMask = type2Omap.Extract(0); - OmapDepth = type2Omap.Extract(1); - } - - public int DepthRegister - { - get - { - int count = 0; - - for (int index = 0; index < OmapTargets.Length; index++) - { - for (int component = 0; component < 4; component++) - { - if (OmapTargets[index].ComponentEnabled(component)) - { - count++; - } - } - } - - // Depth register is always two registers after the last color output. - return count + 1; - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/ShaderProgram.cs b/Ryujinx.Graphics/Shader/ShaderProgram.cs deleted file mode 100644 index 9257fd26..00000000 --- a/Ryujinx.Graphics/Shader/ShaderProgram.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Shader -{ - public class ShaderProgram - { - public ShaderProgramInfo Info { get; } - - public string Code { get; } - - internal ShaderProgram(ShaderProgramInfo info, string code) - { - Info = info; - Code = code; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/ShaderProgramInfo.cs b/Ryujinx.Graphics/Shader/ShaderProgramInfo.cs deleted file mode 100644 index c529a353..00000000 --- a/Ryujinx.Graphics/Shader/ShaderProgramInfo.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.ObjectModel; - -namespace Ryujinx.Graphics.Shader -{ - public class ShaderProgramInfo - { - public ReadOnlyCollection<CBufferDescriptor> CBuffers { get; } - public ReadOnlyCollection<TextureDescriptor> Textures { get; } - - internal ShaderProgramInfo(CBufferDescriptor[] cBuffers, TextureDescriptor[] textures) - { - CBuffers = Array.AsReadOnly(cBuffers); - Textures = Array.AsReadOnly(textures); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstAssignment.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstAssignment.cs deleted file mode 100644 index bb3fe7af..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstAssignment.cs +++ /dev/null @@ -1,35 +0,0 @@ -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstAssignment : AstNode - { - public IAstNode Destination { get; } - - private IAstNode _source; - - public IAstNode Source - { - get - { - return _source; - } - set - { - RemoveUse(_source, this); - - AddUse(value, this); - - _source = value; - } - } - - public AstAssignment(IAstNode destination, IAstNode source) - { - Destination = destination; - Source = source; - - AddDef(destination, this); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstBlock.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstBlock.cs deleted file mode 100644 index fdef87de..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstBlock.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; -using System.Collections; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstBlock : AstNode, IEnumerable<IAstNode> - { - public AstBlockType Type { get; private set; } - - private IAstNode _condition; - - public IAstNode Condition - { - get - { - return _condition; - } - set - { - RemoveUse(_condition, this); - - AddUse(value, this); - - _condition = value; - } - } - - private LinkedList<IAstNode> _nodes; - - public IAstNode First => _nodes.First?.Value; - - public int Count => _nodes.Count; - - public AstBlock(AstBlockType type, IAstNode condition = null) - { - Type = type; - Condition = condition; - - _nodes = new LinkedList<IAstNode>(); - } - - public void Add(IAstNode node) - { - Add(node, _nodes.AddLast(node)); - } - - public void AddFirst(IAstNode node) - { - Add(node, _nodes.AddFirst(node)); - } - - public void AddBefore(IAstNode next, IAstNode node) - { - Add(node, _nodes.AddBefore(next.LLNode, node)); - } - - public void AddAfter(IAstNode prev, IAstNode node) - { - Add(node, _nodes.AddAfter(prev.LLNode, node)); - } - - private void Add(IAstNode node, LinkedListNode<IAstNode> newNode) - { - if (node.Parent != null) - { - throw new ArgumentException("Node already belongs to a block."); - } - - node.Parent = this; - node.LLNode = newNode; - } - - public void Remove(IAstNode node) - { - _nodes.Remove(node.LLNode); - - node.Parent = null; - node.LLNode = null; - } - - public void AndCondition(IAstNode cond) - { - Condition = new AstOperation(Instruction.LogicalAnd, Condition, cond); - } - - public void OrCondition(IAstNode cond) - { - Condition = new AstOperation(Instruction.LogicalOr, Condition, cond); - } - public void TurnIntoIf(IAstNode cond) - { - Condition = cond; - - Type = AstBlockType.If; - } - - public void TurnIntoElseIf() - { - Type = AstBlockType.ElseIf; - } - - public IEnumerator<IAstNode> GetEnumerator() - { - return _nodes.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstBlockType.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstBlockType.cs deleted file mode 100644 index c12efda9..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstBlockType.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - enum AstBlockType - { - DoWhile, - If, - Else, - ElseIf, - Main, - While - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstBlockVisitor.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstBlockVisitor.cs deleted file mode 100644 index 10d5dce0..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstBlockVisitor.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstBlockVisitor - { - public AstBlock Block { get; private set; } - - public class BlockVisitationEventArgs : EventArgs - { - public AstBlock Block { get; } - - public BlockVisitationEventArgs(AstBlock block) - { - Block = block; - } - } - - public event EventHandler<BlockVisitationEventArgs> BlockEntered; - public event EventHandler<BlockVisitationEventArgs> BlockLeft; - - public AstBlockVisitor(AstBlock mainBlock) - { - Block = mainBlock; - } - - public IEnumerable<IAstNode> Visit() - { - IAstNode node = Block.First; - - while (node != null) - { - // We reached a child block, visit the nodes inside. - while (node is AstBlock childBlock) - { - Block = childBlock; - - node = childBlock.First; - - BlockEntered?.Invoke(this, new BlockVisitationEventArgs(Block)); - } - - // Node may be null, if the block is empty. - if (node != null) - { - IAstNode next = Next(node); - - yield return node; - - node = next; - } - - // We reached the end of the list, go up on tree to the parent blocks. - while (node == null && Block.Type != AstBlockType.Main) - { - BlockLeft?.Invoke(this, new BlockVisitationEventArgs(Block)); - - node = Next(Block); - - Block = Block.Parent; - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstHelper.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstHelper.cs deleted file mode 100644 index 9d3148e1..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstHelper.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class AstHelper - { - public static void AddUse(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Uses.Add(parent); - } - } - - public static void AddDef(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Defs.Add(parent); - } - } - - public static void RemoveUse(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Uses.Remove(parent); - } - } - - public static void RemoveDef(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Defs.Remove(parent); - } - } - - public static AstAssignment Assign(IAstNode destination, IAstNode source) - { - return new AstAssignment(destination, source); - } - - public static AstOperand Const(int value) - { - return new AstOperand(OperandType.Constant, value); - } - - public static AstOperand Local(VariableType type) - { - AstOperand local = new AstOperand(OperandType.LocalVariable); - - local.VarType = type; - - return local; - } - - public static IAstNode InverseCond(IAstNode cond) - { - return new AstOperation(Instruction.LogicalNot, cond); - } - - public static IAstNode Next(IAstNode node) - { - return node.LLNode.Next?.Value; - } - - public static IAstNode Previous(IAstNode node) - { - return node.LLNode.Previous?.Value; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstNode.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstNode.cs deleted file mode 100644 index c667aac9..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstNode.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstNode : IAstNode - { - public AstBlock Parent { get; set; } - - public LinkedListNode<IAstNode> LLNode { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstOperand.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstOperand.cs deleted file mode 100644 index 97ff3ca9..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstOperand.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstOperand : AstNode - { - public HashSet<IAstNode> Defs { get; } - public HashSet<IAstNode> Uses { get; } - - public OperandType Type { get; } - - public VariableType VarType { get; set; } - - public int Value { get; } - - public int CbufSlot { get; } - public int CbufOffset { get; } - - private AstOperand() - { - Defs = new HashSet<IAstNode>(); - Uses = new HashSet<IAstNode>(); - - VarType = VariableType.S32; - } - - public AstOperand(Operand operand) : this() - { - Type = operand.Type; - - if (Type == OperandType.ConstantBuffer) - { - CbufSlot = operand.GetCbufSlot(); - CbufOffset = operand.GetCbufOffset(); - } - else - { - Value = operand.Value; - } - } - - public AstOperand(OperandType type, int value = 0) : this() - { - Type = type; - Value = value; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstOperation.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstOperation.cs deleted file mode 100644 index 1607ffec..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstOperation.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstOperation : AstNode - { - public Instruction Inst { get; } - - public int ComponentMask { get; } - - private IAstNode[] _sources; - - public int SourcesCount => _sources.Length; - - public AstOperation(Instruction inst, params IAstNode[] sources) - { - Inst = inst; - _sources = sources; - - foreach (IAstNode source in sources) - { - AddUse(source, this); - } - - ComponentMask = 1; - } - - public AstOperation(Instruction inst, int compMask, params IAstNode[] sources) : this(inst, sources) - { - ComponentMask = compMask; - } - - public IAstNode GetSource(int index) - { - return _sources[index]; - } - - public void SetSource(int index, IAstNode source) - { - RemoveUse(_sources[index], this); - - AddUse(source, this); - - _sources[index] = source; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstOptimizer.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstOptimizer.cs deleted file mode 100644 index 0f5392b7..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstOptimizer.cs +++ /dev/null @@ -1,149 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; -using System.Linq; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class AstOptimizer - { - public static void Optimize(StructuredProgramInfo info) - { - AstBlock mainBlock = info.MainBlock; - - AstBlockVisitor visitor = new AstBlockVisitor(mainBlock); - - foreach (IAstNode node in visitor.Visit()) - { - if (node is AstAssignment assignment && assignment.Destination is AstOperand propVar) - { - bool isWorthPropagating = propVar.Uses.Count == 1 || IsWorthPropagating(assignment.Source); - - if (propVar.Defs.Count == 1 && isWorthPropagating) - { - PropagateExpression(propVar, assignment.Source); - } - - if (propVar.Type == OperandType.LocalVariable && propVar.Uses.Count == 0) - { - visitor.Block.Remove(assignment); - - info.Locals.Remove(propVar); - } - } - } - - RemoveEmptyBlocks(mainBlock); - } - - private static bool IsWorthPropagating(IAstNode source) - { - if (!(source is AstOperation srcOp)) - { - return false; - } - - if (!InstructionInfo.IsUnary(srcOp.Inst)) - { - return false; - } - - return srcOp.GetSource(0) is AstOperand || srcOp.Inst == Instruction.Copy; - } - - private static void PropagateExpression(AstOperand propVar, IAstNode source) - { - IAstNode[] uses = propVar.Uses.ToArray(); - - foreach (IAstNode useNode in uses) - { - if (useNode is AstBlock useBlock) - { - useBlock.Condition = source; - } - else if (useNode is AstOperation useOperation) - { - for (int srcIndex = 0; srcIndex < useOperation.SourcesCount; srcIndex++) - { - if (useOperation.GetSource(srcIndex) == propVar) - { - useOperation.SetSource(srcIndex, source); - } - } - } - else if (useNode is AstAssignment useAssignment) - { - useAssignment.Source = source; - } - } - } - - private static void RemoveEmptyBlocks(AstBlock mainBlock) - { - Queue<AstBlock> pending = new Queue<AstBlock>(); - - pending.Enqueue(mainBlock); - - while (pending.TryDequeue(out AstBlock block)) - { - foreach (IAstNode node in block) - { - if (node is AstBlock childBlock) - { - pending.Enqueue(childBlock); - } - } - - AstBlock parent = block.Parent; - - if (parent == null) - { - continue; - } - - AstBlock nextBlock = Next(block) as AstBlock; - - bool hasElse = nextBlock != null && nextBlock.Type == AstBlockType.Else; - - bool isIf = block.Type == AstBlockType.If; - - if (block.Count == 0) - { - if (isIf) - { - if (hasElse) - { - nextBlock.TurnIntoIf(InverseCond(block.Condition)); - } - - parent.Remove(block); - } - else if (block.Type == AstBlockType.Else) - { - parent.Remove(block); - } - } - else if (isIf && parent.Type == AstBlockType.Else && parent.Count == (hasElse ? 2 : 1)) - { - AstBlock parentOfParent = parent.Parent; - - parent.Remove(block); - - parentOfParent.AddAfter(parent, block); - - if (hasElse) - { - parent.Remove(nextBlock); - - parentOfParent.AddAfter(block, nextBlock); - } - - parentOfParent.Remove(parent); - - block.TurnIntoElseIf(); - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstTextureOperation.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstTextureOperation.cs deleted file mode 100644 index e40f7b70..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstTextureOperation.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstTextureOperation : AstOperation - { - public TextureType Type { get; } - public TextureFlags Flags { get; } - - public int Handle { get; } - - public AstTextureOperation( - Instruction inst, - TextureType type, - TextureFlags flags, - int handle, - int compMask, - params IAstNode[] sources) : base(inst, compMask, sources) - { - Type = type; - Flags = flags; - Handle = handle; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/GotoElimination.cs b/Ryujinx.Graphics/Shader/StructuredIr/GotoElimination.cs deleted file mode 100644 index 8bcf9d9c..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/GotoElimination.cs +++ /dev/null @@ -1,459 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class GotoElimination - { - // This is a modified version of the algorithm presented on the paper - // "Taming Control Flow: A Structured Approach to Eliminating Goto Statements". - public static void Eliminate(GotoStatement[] gotos) - { - for (int index = gotos.Length - 1; index >= 0; index--) - { - GotoStatement stmt = gotos[index]; - - AstBlock gBlock = ParentBlock(stmt.Goto); - AstBlock lBlock = ParentBlock(stmt.Label); - - int gLevel = Level(gBlock); - int lLevel = Level(lBlock); - - if (IndirectlyRelated(gBlock, lBlock, gLevel, lLevel)) - { - AstBlock drBlock = gBlock; - - int drLevel = gLevel; - - do - { - drBlock = drBlock.Parent; - - drLevel--; - } - while (!DirectlyRelated(drBlock, lBlock, drLevel, lLevel)); - - MoveOutward(stmt, gLevel, drLevel); - - gBlock = drBlock; - gLevel = drLevel; - - if (Previous(stmt.Goto) is AstBlock elseBlock && elseBlock.Type == AstBlockType.Else) - { - // It's possible that the label was enclosed inside an else block, - // in this case we need to update the block and level. - // We also need to set the IsLoop for the case when the label is - // now before the goto, due to the newly introduced else block. - lBlock = ParentBlock(stmt.Label); - - lLevel = Level(lBlock); - - if (!IndirectlyRelated(elseBlock, lBlock, gLevel + 1, lLevel)) - { - stmt.IsLoop = true; - } - } - } - - if (DirectlyRelated(gBlock, lBlock, gLevel, lLevel)) - { - if (gLevel > lLevel) - { - MoveOutward(stmt, gLevel, lLevel); - } - else - { - if (stmt.IsLoop) - { - Lift(stmt); - } - - MoveInward(stmt); - } - } - - gBlock = ParentBlock(stmt.Goto); - - if (stmt.IsLoop) - { - EncloseDoWhile(stmt, gBlock, stmt.Label); - } - else - { - Enclose(gBlock, AstBlockType.If, stmt.Condition, Next(stmt.Goto), stmt.Label); - } - - gBlock.Remove(stmt.Goto); - } - } - - private static bool IndirectlyRelated(AstBlock lBlock, AstBlock rBlock, int lLevel, int rlevel) - { - return !(lBlock == rBlock || DirectlyRelated(lBlock, rBlock, lLevel, rlevel)); - } - - private static bool DirectlyRelated(AstBlock lBlock, AstBlock rBlock, int lLevel, int rLevel) - { - // If the levels are equal, they can be either siblings or indirectly related. - if (lLevel == rLevel) - { - return false; - } - - IAstNode block; - IAstNode other; - - int blockLvl, otherLvl; - - if (lLevel > rLevel) - { - block = lBlock; - blockLvl = lLevel; - other = rBlock; - otherLvl = rLevel; - } - else /* if (rLevel > lLevel) */ - { - block = rBlock; - blockLvl = rLevel; - other = lBlock; - otherLvl = lLevel; - } - - while (blockLvl >= otherLvl) - { - if (block == other) - { - return true; - } - - block = block.Parent; - - blockLvl--; - } - - return false; - } - - private static void Lift(GotoStatement stmt) - { - AstBlock block = ParentBlock(stmt.Goto); - - AstBlock[] path = BackwardsPath(block, ParentBlock(stmt.Label)); - - AstBlock loopFirstStmt = path[path.Length - 1]; - - if (loopFirstStmt.Type == AstBlockType.Else) - { - loopFirstStmt = Previous(loopFirstStmt) as AstBlock; - - if (loopFirstStmt == null || loopFirstStmt.Type != AstBlockType.If) - { - throw new InvalidOperationException("Found an else without a matching if."); - } - } - - AstBlock newBlock = EncloseDoWhile(stmt, block, loopFirstStmt); - - block.Remove(stmt.Goto); - - newBlock.AddFirst(stmt.Goto); - - stmt.IsLoop = false; - } - - private static void MoveOutward(GotoStatement stmt, int gLevel, int lLevel) - { - AstBlock origin = ParentBlock(stmt.Goto); - - AstBlock block = origin; - - // Check if a loop is enclosing the goto, and the block that is - // directly related to the label is above the loop block. - // In that case, we need to introduce a break to get out of the loop. - AstBlock loopBlock = origin; - - int loopLevel = gLevel; - - while (loopLevel > lLevel) - { - AstBlock child = loopBlock; - - loopBlock = loopBlock.Parent; - - loopLevel--; - - if (child.Type == AstBlockType.DoWhile) - { - EncloseSingleInst(stmt, Instruction.LoopBreak); - - block.Remove(stmt.Goto); - - loopBlock.AddAfter(child, stmt.Goto); - - block = loopBlock; - gLevel = loopLevel; - } - } - - // Insert ifs to skip the parts that shouldn't be executed due to the goto. - bool tryInsertElse = stmt.IsUnconditional && origin.Type == AstBlockType.If; - - while (gLevel > lLevel) - { - Enclose(block, AstBlockType.If, stmt.Condition, Next(stmt.Goto)); - - block.Remove(stmt.Goto); - - AstBlock child = block; - - // We can't move the goto in the middle of a if and a else block, in - // this case we need to move it after the else. - // IsLoop may need to be updated if the label is inside the else, as - // introducing a loop is the only way to ensure the else will be executed. - if (Next(child) is AstBlock elseBlock && elseBlock.Type == AstBlockType.Else) - { - child = elseBlock; - } - - block = block.Parent; - - block.AddAfter(child, stmt.Goto); - - gLevel--; - - if (tryInsertElse && child == origin) - { - AstBlock lBlock = ParentBlock(stmt.Label); - - IAstNode last = block == lBlock && !stmt.IsLoop ? stmt.Label : null; - - AstBlock newBlock = Enclose(block, AstBlockType.Else, null, Next(stmt.Goto), last); - - if (newBlock != null) - { - block.Remove(stmt.Goto); - - block.AddAfter(newBlock, stmt.Goto); - } - } - } - } - - private static void MoveInward(GotoStatement stmt) - { - AstBlock block = ParentBlock(stmt.Goto); - - AstBlock[] path = BackwardsPath(block, ParentBlock(stmt.Label)); - - for (int index = path.Length - 1; index >= 0; index--) - { - AstBlock child = path[index]; - AstBlock last = child; - - if (child.Type == AstBlockType.If) - { - // Modify the if condition to allow it to be entered by the goto. - if (!ContainsCondComb(child.Condition, Instruction.LogicalOr, stmt.Condition)) - { - child.OrCondition(stmt.Condition); - } - } - else if (child.Type == AstBlockType.Else) - { - // Modify the matching if condition to force the else to be entered by the goto. - if (!(Previous(child) is AstBlock ifBlock) || ifBlock.Type != AstBlockType.If) - { - throw new InvalidOperationException("Found an else without a matching if."); - } - - IAstNode cond = InverseCond(stmt.Condition); - - if (!ContainsCondComb(ifBlock.Condition, Instruction.LogicalAnd, cond)) - { - ifBlock.AndCondition(cond); - } - - last = ifBlock; - } - - Enclose(block, AstBlockType.If, stmt.Condition, Next(stmt.Goto), last); - - block.Remove(stmt.Goto); - - child.AddFirst(stmt.Goto); - - block = child; - } - } - - private static bool ContainsCondComb(IAstNode node, Instruction inst, IAstNode newCond) - { - while (node is AstOperation operation && operation.SourcesCount == 2) - { - if (operation.Inst == inst && IsSameCond(operation.GetSource(1), newCond)) - { - return true; - } - - node = operation.GetSource(0); - } - - return false; - } - - private static AstBlock EncloseDoWhile(GotoStatement stmt, AstBlock block, IAstNode first) - { - if (block.Type == AstBlockType.DoWhile && first == block.First) - { - // We only need to insert the continue if we're not at the end of the loop, - // or if our condition is different from the loop condition. - if (Next(stmt.Goto) != null || block.Condition != stmt.Condition) - { - EncloseSingleInst(stmt, Instruction.LoopContinue); - } - - // Modify the do-while condition to allow it to continue. - if (!ContainsCondComb(block.Condition, Instruction.LogicalOr, stmt.Condition)) - { - block.OrCondition(stmt.Condition); - } - - return block; - } - - return Enclose(block, AstBlockType.DoWhile, stmt.Condition, first, stmt.Goto); - } - - private static void EncloseSingleInst(GotoStatement stmt, Instruction inst) - { - AstBlock block = ParentBlock(stmt.Goto); - - AstBlock newBlock = new AstBlock(AstBlockType.If, stmt.Condition); - - block.AddAfter(stmt.Goto, newBlock); - - newBlock.AddFirst(new AstOperation(inst)); - } - - private static AstBlock Enclose( - AstBlock block, - AstBlockType type, - IAstNode cond, - IAstNode first, - IAstNode last = null) - { - if (first == last) - { - return null; - } - - if (type == AstBlockType.If) - { - cond = InverseCond(cond); - } - - // Do a quick check, if we are enclosing a single block, - // and the block type/condition matches the one we're going - // to create, then we don't need a new block, we can just - // return the old one. - bool hasSingleNode = Next(first) == last; - - if (hasSingleNode && BlockMatches(first, type, cond)) - { - return first as AstBlock; - } - - AstBlock newBlock = new AstBlock(type, cond); - - block.AddBefore(first, newBlock); - - while (first != last) - { - IAstNode next = Next(first); - - block.Remove(first); - - newBlock.Add(first); - - first = next; - } - - return newBlock; - } - - private static bool BlockMatches(IAstNode node, AstBlockType type, IAstNode cond) - { - if (!(node is AstBlock block)) - { - return false; - } - - return block.Type == type && IsSameCond(block.Condition, cond); - } - - private static bool IsSameCond(IAstNode lCond, IAstNode rCond) - { - if (lCond is AstOperation lCondOp && lCondOp.Inst == Instruction.LogicalNot) - { - if (!(rCond is AstOperation rCondOp) || rCondOp.Inst != lCondOp.Inst) - { - return false; - } - - lCond = lCondOp.GetSource(0); - rCond = rCondOp.GetSource(0); - } - - return lCond == rCond; - } - - private static AstBlock ParentBlock(IAstNode node) - { - if (node is AstBlock block) - { - return block.Parent; - } - - while (!(node is AstBlock)) - { - node = node.Parent; - } - - return node as AstBlock; - } - - private static AstBlock[] BackwardsPath(AstBlock top, AstBlock bottom) - { - AstBlock block = bottom; - - List<AstBlock> path = new List<AstBlock>(); - - while (block != top) - { - path.Add(block); - - block = block.Parent; - } - - return path.ToArray(); - } - - private static int Level(IAstNode node) - { - int level = 0; - - while (node != null) - { - level++; - - node = node.Parent; - } - - return level; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/GotoStatement.cs b/Ryujinx.Graphics/Shader/StructuredIr/GotoStatement.cs deleted file mode 100644 index 25216e55..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/GotoStatement.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class GotoStatement - { - public AstOperation Goto { get; } - public AstAssignment Label { get; } - - public IAstNode Condition => Label.Destination; - - public bool IsLoop { get; set; } - - public bool IsUnconditional => Goto.Inst == Instruction.Branch; - - public GotoStatement(AstOperation branch, AstAssignment label, bool isLoop) - { - Goto = branch; - Label = label; - IsLoop = isLoop; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/IAstNode.cs b/Ryujinx.Graphics/Shader/StructuredIr/IAstNode.cs deleted file mode 100644 index 5ececbb5..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/IAstNode.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - interface IAstNode - { - AstBlock Parent { get; set; } - - LinkedListNode<IAstNode> LLNode { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/InstructionInfo.cs b/Ryujinx.Graphics/Shader/StructuredIr/InstructionInfo.cs deleted file mode 100644 index 46a61553..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/InstructionInfo.cs +++ /dev/null @@ -1,142 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class InstructionInfo - { - private struct InstInfo - { - public VariableType DestType { get; } - - public VariableType[] SrcTypes { get; } - - public InstInfo(VariableType destType, params VariableType[] srcTypes) - { - DestType = destType; - SrcTypes = srcTypes; - } - } - - private static InstInfo[] _infoTbl; - - static InstructionInfo() - { - _infoTbl = new InstInfo[(int)Instruction.Count]; - - Add(Instruction.Absolute, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Add, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.BitfieldExtractS32, VariableType.S32, VariableType.S32, VariableType.S32, VariableType.S32); - Add(Instruction.BitfieldExtractU32, VariableType.U32, VariableType.U32, VariableType.S32, VariableType.S32); - Add(Instruction.BitfieldInsert, VariableType.Int, VariableType.Int, VariableType.Int, VariableType.S32, VariableType.S32); - Add(Instruction.BitfieldReverse, VariableType.Int, VariableType.Int); - Add(Instruction.BitwiseAnd, VariableType.Int, VariableType.Int, VariableType.Int); - Add(Instruction.BitwiseExclusiveOr, VariableType.Int, VariableType.Int, VariableType.Int); - Add(Instruction.BitwiseNot, VariableType.Int, VariableType.Int); - Add(Instruction.BitwiseOr, VariableType.Int, VariableType.Int, VariableType.Int); - Add(Instruction.BranchIfTrue, VariableType.None, VariableType.Bool); - Add(Instruction.BranchIfFalse, VariableType.None, VariableType.Bool); - Add(Instruction.Ceiling, VariableType.F32, VariableType.F32, VariableType.F32); - Add(Instruction.Clamp, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.ClampU32, VariableType.U32, VariableType.U32, VariableType.U32, VariableType.U32); - Add(Instruction.CompareEqual, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.CompareGreater, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.CompareGreaterOrEqual, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.CompareGreaterOrEqualU32, VariableType.Bool, VariableType.U32, VariableType.U32); - Add(Instruction.CompareGreaterU32, VariableType.Bool, VariableType.U32, VariableType.U32); - Add(Instruction.CompareLess, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.CompareLessOrEqual, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.CompareLessOrEqualU32, VariableType.Bool, VariableType.U32, VariableType.U32); - Add(Instruction.CompareLessU32, VariableType.Bool, VariableType.U32, VariableType.U32); - Add(Instruction.CompareNotEqual, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.ConditionalSelect, VariableType.Scalar, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.ConvertFPToS32, VariableType.S32, VariableType.F32); - Add(Instruction.ConvertS32ToFP, VariableType.F32, VariableType.S32); - Add(Instruction.ConvertU32ToFP, VariableType.F32, VariableType.U32); - Add(Instruction.Cosine, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Divide, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.ExponentB2, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Floor, VariableType.F32, VariableType.F32); - Add(Instruction.FusedMultiplyAdd, VariableType.F32, VariableType.F32, VariableType.F32, VariableType.F32); - Add(Instruction.IsNan, VariableType.Bool, VariableType.F32); - Add(Instruction.LoadConstant, VariableType.F32, VariableType.S32, VariableType.S32); - Add(Instruction.LogarithmB2, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.LogicalAnd, VariableType.Bool, VariableType.Bool, VariableType.Bool); - Add(Instruction.LogicalExclusiveOr, VariableType.Bool, VariableType.Bool, VariableType.Bool); - Add(Instruction.LogicalNot, VariableType.Bool, VariableType.Bool); - Add(Instruction.LogicalOr, VariableType.Bool, VariableType.Bool, VariableType.Bool); - Add(Instruction.ShiftLeft, VariableType.Int, VariableType.Int, VariableType.Int); - Add(Instruction.ShiftRightS32, VariableType.S32, VariableType.S32, VariableType.Int); - Add(Instruction.ShiftRightU32, VariableType.U32, VariableType.U32, VariableType.Int); - Add(Instruction.Maximum, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.MaximumU32, VariableType.U32, VariableType.U32, VariableType.U32); - Add(Instruction.Minimum, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.MinimumU32, VariableType.U32, VariableType.U32, VariableType.U32); - Add(Instruction.Multiply, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Negate, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.PackHalf2x16, VariableType.U32, VariableType.F32, VariableType.F32); - Add(Instruction.ReciprocalSquareRoot, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Sine, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.SquareRoot, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Subtract, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.TextureSample, VariableType.F32); - Add(Instruction.TextureSize, VariableType.S32, VariableType.S32, VariableType.S32); - Add(Instruction.Truncate, VariableType.F32, VariableType.F32); - Add(Instruction.UnpackHalf2x16, VariableType.F32, VariableType.U32); - } - - private static void Add(Instruction inst, VariableType destType, params VariableType[] srcTypes) - { - _infoTbl[(int)inst] = new InstInfo(destType, srcTypes); - } - - public static VariableType GetDestVarType(Instruction inst) - { - return GetFinalVarType(_infoTbl[(int)(inst & Instruction.Mask)].DestType, inst); - } - - public static VariableType GetSrcVarType(Instruction inst, int index) - { - if (inst == Instruction.TextureSample) - { - return VariableType.F32; - } - - return GetFinalVarType(_infoTbl[(int)(inst & Instruction.Mask)].SrcTypes[index], inst); - } - - private static VariableType GetFinalVarType(VariableType type, Instruction inst) - { - if (type == VariableType.Scalar) - { - return (inst & Instruction.FP) != 0 - ? VariableType.F32 - : VariableType.S32; - } - else if (type == VariableType.Int) - { - return VariableType.S32; - } - else if (type == VariableType.None) - { - throw new ArgumentException($"Invalid operand for instruction \"{inst}\"."); - } - - return type; - } - - public static bool IsUnary(Instruction inst) - { - if (inst == Instruction.Copy) - { - return true; - } - else if (inst == Instruction.TextureSample) - { - return false; - } - - return _infoTbl[(int)(inst & Instruction.Mask)].SrcTypes.Length == 1; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/OperandInfo.cs b/Ryujinx.Graphics/Shader/StructuredIr/OperandInfo.cs deleted file mode 100644 index a3a8d138..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/OperandInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class OperandInfo - { - public static VariableType GetVarType(AstOperand operand) - { - if (operand.Type == OperandType.LocalVariable) - { - return operand.VarType; - } - else - { - return GetVarType(operand.Type); - } - } - - public static VariableType GetVarType(OperandType type) - { - switch (type) - { - case OperandType.Attribute: return VariableType.F32; - case OperandType.Constant: return VariableType.S32; - case OperandType.ConstantBuffer: return VariableType.F32; - case OperandType.GlobalMemory: return VariableType.F32; - case OperandType.Undefined: return VariableType.S32; - } - - throw new ArgumentException($"Invalid operand type \"{type}\"."); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/PhiFunctions.cs b/Ryujinx.Graphics/Shader/StructuredIr/PhiFunctions.cs deleted file mode 100644 index 53391b62..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/PhiFunctions.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class PhiFunctions - { - public static void Remove(BasicBlock[] blocks) - { - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - BasicBlock block = blocks[blkIndex]; - - LinkedListNode<INode> node = block.Operations.First; - - while (node != null) - { - LinkedListNode<INode> nextNode = node.Next; - - if (!(node.Value is PhiNode phi)) - { - node = nextNode; - - continue; - } - - for (int index = 0; index < phi.SourcesCount; index++) - { - Operand src = phi.GetSource(index); - - BasicBlock srcBlock = phi.GetBlock(index); - - Operation copyOp = new Operation(Instruction.Copy, phi.Dest, src); - - AddBeforeBranch(srcBlock, copyOp); - } - - block.Operations.Remove(node); - - node = nextNode; - } - } - } - - private static void AddBeforeBranch(BasicBlock block, INode node) - { - INode lastOp = block.GetLastOp(); - - if (lastOp is Operation operation && IsControlFlowInst(operation.Inst)) - { - block.Operations.AddBefore(block.Operations.Last, node); - } - else - { - block.Operations.AddLast(node); - } - } - - private static bool IsControlFlowInst(Instruction inst) - { - switch (inst) - { - case Instruction.Branch: - case Instruction.BranchIfFalse: - case Instruction.BranchIfTrue: - case Instruction.Discard: - case Instruction.Return: - return true; - } - - return false; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgram.cs b/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgram.cs deleted file mode 100644 index 26faaf36..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgram.cs +++ /dev/null @@ -1,254 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class StructuredProgram - { - public static StructuredProgramInfo MakeStructuredProgram(BasicBlock[] blocks) - { - PhiFunctions.Remove(blocks); - - StructuredProgramContext context = new StructuredProgramContext(blocks.Length); - - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - BasicBlock block = blocks[blkIndex]; - - context.EnterBlock(block); - - foreach (INode node in block.Operations) - { - Operation operation = (Operation)node; - - if (IsBranchInst(operation.Inst)) - { - context.LeaveBlock(block, operation); - } - else - { - AddOperation(context, operation); - } - } - } - - GotoElimination.Eliminate(context.GetGotos()); - - AstOptimizer.Optimize(context.Info); - - return context.Info; - } - - private static void AddOperation(StructuredProgramContext context, Operation operation) - { - Instruction inst = operation.Inst; - - IAstNode[] sources = new IAstNode[operation.SourcesCount]; - - for (int index = 0; index < sources.Length; index++) - { - sources[index] = context.GetOperandUse(operation.GetSource(index)); - } - - if (operation.Dest != null) - { - AstOperand dest = context.GetOperandDef(operation.Dest); - - if (inst == Instruction.LoadConstant) - { - Operand ldcSource = operation.GetSource(0); - - if (ldcSource.Type != OperandType.Constant) - { - throw new InvalidOperationException("Found LDC with non-constant constant buffer slot."); - } - - context.Info.CBuffers.Add(ldcSource.Value); - } - - AstAssignment assignment; - - // If all the sources are bool, it's better to use short-circuiting - // logical operations, rather than forcing a cast to int and doing - // a bitwise operation with the value, as it is likely to be used as - // a bool in the end. - if (IsBitwiseInst(inst) && AreAllSourceTypesEqual(sources, VariableType.Bool)) - { - inst = GetLogicalFromBitwiseInst(inst); - } - - bool isCondSel = inst == Instruction.ConditionalSelect; - bool isCopy = inst == Instruction.Copy; - - if (isCondSel || isCopy) - { - VariableType type = GetVarTypeFromUses(operation.Dest); - - if (isCondSel && type == VariableType.F32) - { - inst |= Instruction.FP; - } - - dest.VarType = type; - } - else - { - dest.VarType = InstructionInfo.GetDestVarType(inst); - } - - int componentMask = 1 << operation.ComponentIndex; - - IAstNode source; - - if (operation is TextureOperation texOp) - { - AstTextureOperation astTexOp = new AstTextureOperation( - inst, - texOp.Type, - texOp.Flags, - texOp.Handle, - componentMask, - sources); - - context.Info.Samplers.Add(astTexOp); - - source = astTexOp; - } - else if (!isCopy) - { - source = new AstOperation(inst, componentMask, sources); - } - else - { - source = sources[0]; - } - - assignment = new AstAssignment(dest, source); - - context.AddNode(assignment); - } - else - { - context.AddNode(new AstOperation(inst, sources)); - } - } - - private static VariableType GetVarTypeFromUses(Operand dest) - { - HashSet<Operand> visited = new HashSet<Operand>(); - - Queue<Operand> pending = new Queue<Operand>(); - - bool Enqueue(Operand operand) - { - if (visited.Add(operand)) - { - pending.Enqueue(operand); - - return true; - } - - return false; - } - - Enqueue(dest); - - while (pending.TryDequeue(out Operand operand)) - { - foreach (INode useNode in operand.UseOps) - { - if (!(useNode is Operation operation)) - { - continue; - } - - if (operation.Inst == Instruction.Copy) - { - if (operation.Dest.Type == OperandType.LocalVariable) - { - if (Enqueue(operation.Dest)) - { - break; - } - } - else - { - return OperandInfo.GetVarType(operation.Dest.Type); - } - } - else - { - for (int index = 0; index < operation.SourcesCount; index++) - { - if (operation.GetSource(index) == operand) - { - return InstructionInfo.GetSrcVarType(operation.Inst, index); - } - } - } - } - } - - return VariableType.S32; - } - - private static bool AreAllSourceTypesEqual(IAstNode[] sources, VariableType type) - { - foreach (IAstNode node in sources) - { - if (!(node is AstOperand operand)) - { - return false; - } - - if (operand.VarType != type) - { - return false; - } - } - - return true; - } - - private static bool IsBranchInst(Instruction inst) - { - switch (inst) - { - case Instruction.Branch: - case Instruction.BranchIfFalse: - case Instruction.BranchIfTrue: - return true; - } - - return false; - } - - private static bool IsBitwiseInst(Instruction inst) - { - switch (inst) - { - case Instruction.BitwiseAnd: - case Instruction.BitwiseExclusiveOr: - case Instruction.BitwiseNot: - case Instruction.BitwiseOr: - return true; - } - - return false; - } - - private static Instruction GetLogicalFromBitwiseInst(Instruction inst) - { - switch (inst) - { - case Instruction.BitwiseAnd: return Instruction.LogicalAnd; - case Instruction.BitwiseExclusiveOr: return Instruction.LogicalExclusiveOr; - case Instruction.BitwiseNot: return Instruction.LogicalNot; - case Instruction.BitwiseOr: return Instruction.LogicalOr; - } - - throw new ArgumentException($"Unexpected instruction \"{inst}\"."); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramContext.cs b/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramContext.cs deleted file mode 100644 index 5d6ff890..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramContext.cs +++ /dev/null @@ -1,292 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; -using System.Linq; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class StructuredProgramContext - { - private HashSet<BasicBlock> _loopTails; - - private Stack<(AstBlock Block, int EndIndex)> _blockStack; - - private Dictionary<Operand, AstOperand> _localsMap; - - private Dictionary<int, AstAssignment> _gotoTempAsgs; - - private List<GotoStatement> _gotos; - - private AstBlock _currBlock; - - private int _currEndIndex; - - public StructuredProgramInfo Info { get; } - - public StructuredProgramContext(int blocksCount) - { - _loopTails = new HashSet<BasicBlock>(); - - _blockStack = new Stack<(AstBlock, int)>(); - - _localsMap = new Dictionary<Operand, AstOperand>(); - - _gotoTempAsgs = new Dictionary<int, AstAssignment>(); - - _gotos = new List<GotoStatement>(); - - _currBlock = new AstBlock(AstBlockType.Main); - - _currEndIndex = blocksCount; - - Info = new StructuredProgramInfo(_currBlock); - } - - public void EnterBlock(BasicBlock block) - { - while (_currEndIndex == block.Index) - { - (_currBlock, _currEndIndex) = _blockStack.Pop(); - } - - if (_gotoTempAsgs.TryGetValue(block.Index, out AstAssignment gotoTempAsg)) - { - AddGotoTempReset(block, gotoTempAsg); - } - - LookForDoWhileStatements(block); - } - - public void LeaveBlock(BasicBlock block, Operation branchOp) - { - LookForIfStatements(block, branchOp); - } - - private void LookForDoWhileStatements(BasicBlock block) - { - // Check if we have any predecessor whose index is greater than the - // current block, this indicates a loop. - bool done = false; - - foreach (BasicBlock predecessor in block.Predecessors.OrderByDescending(x => x.Index)) - { - if (predecessor.Index < block.Index) - { - break; - } - - if (predecessor.Index < _currEndIndex && !done) - { - Operation branchOp = (Operation)predecessor.GetLastOp(); - - NewBlock(AstBlockType.DoWhile, branchOp, predecessor.Index + 1); - - _loopTails.Add(predecessor); - - done = true; - } - else - { - AddGotoTempReset(block, GetGotoTempAsg(block.Index)); - - break; - } - } - } - - private void LookForIfStatements(BasicBlock block, Operation branchOp) - { - if (block.Branch == null) - { - return; - } - - bool isLoop = block.Branch.Index <= block.Index; - - if (block.Branch.Index <= _currEndIndex && !isLoop) - { - NewBlock(AstBlockType.If, branchOp, block.Branch.Index); - } - else if (!_loopTails.Contains(block)) - { - AstAssignment gotoTempAsg = GetGotoTempAsg(block.Branch.Index); - - IAstNode cond = GetBranchCond(AstBlockType.DoWhile, branchOp); - - AddNode(Assign(gotoTempAsg.Destination, cond)); - - AstOperation branch = new AstOperation(branchOp.Inst); - - AddNode(branch); - - GotoStatement gotoStmt = new GotoStatement(branch, gotoTempAsg, isLoop); - - _gotos.Add(gotoStmt); - } - } - - private AstAssignment GetGotoTempAsg(int index) - { - if (_gotoTempAsgs.TryGetValue(index, out AstAssignment gotoTempAsg)) - { - return gotoTempAsg; - } - - AstOperand gotoTemp = NewTemp(VariableType.Bool); - - gotoTempAsg = Assign(gotoTemp, Const(IrConsts.False)); - - _gotoTempAsgs.Add(index, gotoTempAsg); - - return gotoTempAsg; - } - - private void AddGotoTempReset(BasicBlock block, AstAssignment gotoTempAsg) - { - AddNode(gotoTempAsg); - - // For block 0, we don't need to add the extra "reset" at the beginning, - // because it is already the first node to be executed on the shader, - // so it is reset to false by the "local" assignment anyway. - if (block.Index != 0) - { - Info.MainBlock.AddFirst(Assign(gotoTempAsg.Destination, Const(IrConsts.False))); - } - } - - private void NewBlock(AstBlockType type, Operation branchOp, int endIndex) - { - NewBlock(type, GetBranchCond(type, branchOp), endIndex); - } - - private void NewBlock(AstBlockType type, IAstNode cond, int endIndex) - { - AstBlock childBlock = new AstBlock(type, cond); - - AddNode(childBlock); - - _blockStack.Push((_currBlock, _currEndIndex)); - - _currBlock = childBlock; - _currEndIndex = endIndex; - } - - private IAstNode GetBranchCond(AstBlockType type, Operation branchOp) - { - IAstNode cond; - - if (branchOp.Inst == Instruction.Branch) - { - cond = Const(type == AstBlockType.If ? IrConsts.False : IrConsts.True); - } - else - { - cond = GetOperandUse(branchOp.GetSource(0)); - - Instruction invInst = type == AstBlockType.If - ? Instruction.BranchIfTrue - : Instruction.BranchIfFalse; - - if (branchOp.Inst == invInst) - { - cond = new AstOperation(Instruction.LogicalNot, cond); - } - } - - return cond; - } - - public void AddNode(IAstNode node) - { - _currBlock.Add(node); - } - - public GotoStatement[] GetGotos() - { - return _gotos.ToArray(); - } - - private AstOperand NewTemp(VariableType type) - { - AstOperand newTemp = Local(type); - - Info.Locals.Add(newTemp); - - return newTemp; - } - - public AstOperand GetOperandDef(Operand operand) - { - if (TryGetUserAttributeIndex(operand, out int attrIndex)) - { - Info.OAttributes.Add(attrIndex); - } - - return GetOperand(operand); - } - - public AstOperand GetOperandUse(Operand operand) - { - if (TryGetUserAttributeIndex(operand, out int attrIndex)) - { - Info.IAttributes.Add(attrIndex); - } - else if (operand.Type == OperandType.ConstantBuffer) - { - Info.CBuffers.Add(operand.GetCbufSlot()); - } - - return GetOperand(operand); - } - - private AstOperand GetOperand(Operand operand) - { - if (operand == null) - { - return null; - } - - if (operand.Type != OperandType.LocalVariable) - { - return new AstOperand(operand); - } - - if (!_localsMap.TryGetValue(operand, out AstOperand astOperand)) - { - astOperand = new AstOperand(operand); - - _localsMap.Add(operand, astOperand); - - Info.Locals.Add(astOperand); - } - - return astOperand; - } - - private static bool TryGetUserAttributeIndex(Operand operand, out int attrIndex) - { - if (operand.Type == OperandType.Attribute) - { - if (operand.Value >= AttributeConsts.UserAttributeBase && - operand.Value < AttributeConsts.UserAttributeEnd) - { - attrIndex = (operand.Value - AttributeConsts.UserAttributeBase) >> 4; - - return true; - } - else if (operand.Value >= AttributeConsts.FragmentOutputColorBase && - operand.Value < AttributeConsts.FragmentOutputColorEnd) - { - attrIndex = (operand.Value - AttributeConsts.FragmentOutputColorBase) >> 4; - - return true; - } - } - - attrIndex = 0; - - return false; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramInfo.cs b/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramInfo.cs deleted file mode 100644 index d368ef00..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramInfo.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class StructuredProgramInfo - { - public AstBlock MainBlock { get; } - - public HashSet<AstOperand> Locals { get; } - - public HashSet<int> CBuffers { get; } - - public HashSet<int> IAttributes { get; } - public HashSet<int> OAttributes { get; } - - public HashSet<AstTextureOperation> Samplers { get; } - - public StructuredProgramInfo(AstBlock mainBlock) - { - MainBlock = mainBlock; - - Locals = new HashSet<AstOperand>(); - - CBuffers = new HashSet<int>(); - - IAttributes = new HashSet<int>(); - OAttributes = new HashSet<int>(); - - Samplers = new HashSet<AstTextureOperation>(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/VariableType.cs b/Ryujinx.Graphics/Shader/StructuredIr/VariableType.cs deleted file mode 100644 index 4c7f3849..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/VariableType.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - enum VariableType - { - None, - Bool, - Scalar, - Int, - F32, - S32, - U32 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/TextureDescriptor.cs b/Ryujinx.Graphics/Shader/TextureDescriptor.cs deleted file mode 100644 index 96f0f5b1..00000000 --- a/Ryujinx.Graphics/Shader/TextureDescriptor.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace Ryujinx.Graphics.Shader -{ - public struct TextureDescriptor - { - public string Name { get; } - - public int HandleIndex { get; } - - public bool IsBindless { get; } - - public int CbufSlot { get; } - public int CbufOffset { get; } - - public TextureDescriptor(string name, int hIndex) - { - Name = name; - HandleIndex = hIndex; - - IsBindless = false; - - CbufSlot = 0; - CbufOffset = 0; - } - - public TextureDescriptor(string name, int cbufSlot, int cbufOffset) - { - Name = name; - HandleIndex = 0; - - IsBindless = true; - - CbufSlot = cbufSlot; - CbufOffset = cbufOffset; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/AttributeConsts.cs b/Ryujinx.Graphics/Shader/Translation/AttributeConsts.cs deleted file mode 100644 index f21a6252..00000000 --- a/Ryujinx.Graphics/Shader/Translation/AttributeConsts.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - static class AttributeConsts - { - public const int Layer = 0x064; - public const int PointSize = 0x06c; - public const int PositionX = 0x070; - public const int PositionY = 0x074; - public const int PositionZ = 0x078; - public const int PositionW = 0x07c; - public const int ClipDistance0 = 0x2c0; - public const int ClipDistance1 = 0x2c4; - public const int ClipDistance2 = 0x2c8; - public const int ClipDistance3 = 0x2cc; - public const int ClipDistance4 = 0x2d0; - public const int ClipDistance5 = 0x2d4; - public const int ClipDistance6 = 0x2d8; - public const int ClipDistance7 = 0x2dc; - public const int PointCoordX = 0x2e0; - public const int PointCoordY = 0x2e4; - public const int TessCoordX = 0x2f0; - public const int TessCoordY = 0x2f4; - public const int InstanceId = 0x2f8; - public const int VertexId = 0x2fc; - public const int FrontFacing = 0x3fc; - - public const int UserAttributesCount = 32; - public const int UserAttributeBase = 0x80; - public const int UserAttributeEnd = UserAttributeBase + UserAttributesCount * 16; - - - // Note: Those attributes are used internally by the translator - // only, they don't exist on Maxwell. - public const int FragmentOutputDepth = 0x1000000; - public const int FragmentOutputColorBase = 0x1000010; - public const int FragmentOutputColorEnd = FragmentOutputColorBase + 8 * 16; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/ControlFlowGraph.cs b/Ryujinx.Graphics/Shader/Translation/ControlFlowGraph.cs deleted file mode 100644 index e2ca74a4..00000000 --- a/Ryujinx.Graphics/Shader/Translation/ControlFlowGraph.cs +++ /dev/null @@ -1,108 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.Translation -{ - static class ControlFlowGraph - { - public static BasicBlock[] MakeCfg(Operation[] operations) - { - Dictionary<Operand, BasicBlock> labels = new Dictionary<Operand, BasicBlock>(); - - List<BasicBlock> blocks = new List<BasicBlock>(); - - BasicBlock currentBlock = null; - - void NextBlock(BasicBlock nextBlock) - { - if (currentBlock != null && !EndsWithUnconditionalInst(currentBlock.GetLastOp())) - { - currentBlock.Next = nextBlock; - } - - currentBlock = nextBlock; - } - - void NewNextBlock() - { - BasicBlock block = new BasicBlock(blocks.Count); - - blocks.Add(block); - - NextBlock(block); - } - - bool needsNewBlock = true; - - for (int index = 0; index < operations.Length; index++) - { - Operation operation = operations[index]; - - if (operation.Inst == Instruction.MarkLabel) - { - Operand label = operation.Dest; - - if (labels.TryGetValue(label, out BasicBlock nextBlock)) - { - nextBlock.Index = blocks.Count; - - blocks.Add(nextBlock); - - NextBlock(nextBlock); - } - else - { - NewNextBlock(); - - labels.Add(label, currentBlock); - } - } - else - { - if (needsNewBlock) - { - NewNextBlock(); - } - - currentBlock.Operations.AddLast(operation); - } - - needsNewBlock = operation.Inst == Instruction.Branch || - operation.Inst == Instruction.BranchIfTrue || - operation.Inst == Instruction.BranchIfFalse; - - if (needsNewBlock) - { - Operand label = operation.Dest; - - if (!labels.TryGetValue(label, out BasicBlock branchBlock)) - { - branchBlock = new BasicBlock(); - - labels.Add(label, branchBlock); - } - - currentBlock.Branch = branchBlock; - } - } - - return blocks.ToArray(); - } - - private static bool EndsWithUnconditionalInst(INode node) - { - if (node is Operation operation) - { - switch (operation.Inst) - { - case Instruction.Branch: - case Instruction.Discard: - case Instruction.Return: - return true; - } - } - - return false; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Dominance.cs b/Ryujinx.Graphics/Shader/Translation/Dominance.cs deleted file mode 100644 index 6a3ff35f..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Dominance.cs +++ /dev/null @@ -1,127 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.Translation -{ - static class Dominance - { - // Those methods are an implementation of the algorithms on "A Simple, Fast Dominance Algorithm". - // https://www.cs.rice.edu/~keith/EMBED/dom.pdf - public static void FindDominators(BasicBlock entry, int blocksCount) - { - HashSet<BasicBlock> visited = new HashSet<BasicBlock>(); - - Stack<BasicBlock> blockStack = new Stack<BasicBlock>(); - - List<BasicBlock> postOrderBlocks = new List<BasicBlock>(blocksCount); - - int[] postOrderMap = new int[blocksCount]; - - visited.Add(entry); - - blockStack.Push(entry); - - while (blockStack.TryPop(out BasicBlock block)) - { - if (block.Next != null && visited.Add(block.Next)) - { - blockStack.Push(block); - blockStack.Push(block.Next); - } - else if (block.Branch != null && visited.Add(block.Branch)) - { - blockStack.Push(block); - blockStack.Push(block.Branch); - } - else - { - postOrderMap[block.Index] = postOrderBlocks.Count; - - postOrderBlocks.Add(block); - } - } - - BasicBlock Intersect(BasicBlock block1, BasicBlock block2) - { - while (block1 != block2) - { - while (postOrderMap[block1.Index] < postOrderMap[block2.Index]) - { - block1 = block1.ImmediateDominator; - } - - while (postOrderMap[block2.Index] < postOrderMap[block1.Index]) - { - block2 = block2.ImmediateDominator; - } - } - - return block1; - } - - entry.ImmediateDominator = entry; - - bool modified; - - do - { - modified = false; - - for (int blkIndex = postOrderBlocks.Count - 2; blkIndex >= 0; blkIndex--) - { - BasicBlock block = postOrderBlocks[blkIndex]; - - BasicBlock newIDom = null; - - foreach (BasicBlock predecessor in block.Predecessors) - { - if (predecessor.ImmediateDominator != null) - { - if (newIDom != null) - { - newIDom = Intersect(predecessor, newIDom); - } - else - { - newIDom = predecessor; - } - } - } - - if (block.ImmediateDominator != newIDom) - { - block.ImmediateDominator = newIDom; - - modified = true; - } - } - } - while (modified); - } - - public static void FindDominanceFrontiers(BasicBlock[] blocks) - { - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - BasicBlock block = blocks[blkIndex]; - - if (block.Predecessors.Count < 2) - { - continue; - } - - for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++) - { - BasicBlock current = block.Predecessors[pBlkIndex]; - - while (current != block.ImmediateDominator) - { - current.DominanceFrontiers.Add(block); - - current = current.ImmediateDominator; - } - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/EmitterContext.cs b/Ryujinx.Graphics/Shader/Translation/EmitterContext.cs deleted file mode 100644 index 6c2bf6e4..00000000 --- a/Ryujinx.Graphics/Shader/Translation/EmitterContext.cs +++ /dev/null @@ -1,105 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation -{ - class EmitterContext - { - public Block CurrBlock { get; set; } - public OpCode CurrOp { get; set; } - - private GalShaderType _shaderType; - - private ShaderHeader _header; - - private List<Operation> _operations; - - private Dictionary<ulong, Operand> _labels; - - public EmitterContext(GalShaderType shaderType, ShaderHeader header) - { - _shaderType = shaderType; - _header = header; - - _operations = new List<Operation>(); - - _labels = new Dictionary<ulong, Operand>(); - } - - public Operand Add(Instruction inst, Operand dest = null, params Operand[] sources) - { - Operation operation = new Operation(inst, dest, sources); - - Add(operation); - - return dest; - } - - public void Add(Operation operation) - { - _operations.Add(operation); - } - - public void MarkLabel(Operand label) - { - Add(Instruction.MarkLabel, label); - } - - public Operand GetLabel(ulong address) - { - if (!_labels.TryGetValue(address, out Operand label)) - { - label = Label(); - - _labels.Add(address, label); - } - - return label; - } - - public void PrepareForReturn() - { - if (_shaderType == GalShaderType.Fragment) - { - if (_header.OmapDepth) - { - Operand dest = Attribute(AttributeConsts.FragmentOutputDepth); - - Operand src = Register(_header.DepthRegister, RegisterType.Gpr); - - this.Copy(dest, src); - } - - int regIndex = 0; - - for (int attachment = 0; attachment < 8; attachment++) - { - OutputMapTarget target = _header.OmapTargets[attachment]; - - for (int component = 0; component < 4; component++) - { - if (target.ComponentEnabled(component)) - { - Operand dest = Attribute(AttributeConsts.FragmentOutputColorBase + regIndex * 4); - - Operand src = Register(regIndex, RegisterType.Gpr); - - this.Copy(dest, src); - - regIndex++; - } - } - } - } - } - - public Operation[] GetOperations() - { - return _operations.ToArray(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/EmitterContextInsts.cs b/Ryujinx.Graphics/Shader/Translation/EmitterContextInsts.cs deleted file mode 100644 index 604aa67d..00000000 --- a/Ryujinx.Graphics/Shader/Translation/EmitterContextInsts.cs +++ /dev/null @@ -1,420 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation -{ - static class EmitterContextInsts - { - public static Operand BitfieldExtractS32(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.BitfieldExtractS32, Local(), a, b, c); - } - - public static Operand BitfieldExtractU32(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.BitfieldExtractU32, Local(), a, b, c); - } - - public static Operand BitfieldInsert(this EmitterContext context, Operand a, Operand b, Operand c, Operand d) - { - return context.Add(Instruction.BitfieldInsert, Local(), a, b, c, d); - } - - public static Operand BitfieldReverse(this EmitterContext context, Operand a) - { - return context.Add(Instruction.BitfieldReverse, Local(), a); - } - - public static Operand BitwiseAnd(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.BitwiseAnd, Local(), a, b); - } - - public static Operand BitwiseExclusiveOr(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.BitwiseExclusiveOr, Local(), a, b); - } - - public static Operand BitwiseNot(this EmitterContext context, Operand a, bool invert) - { - if (invert) - { - a = context.BitwiseNot(a); - } - - return a; - } - - public static Operand BitwiseNot(this EmitterContext context, Operand a) - { - return context.Add(Instruction.BitwiseNot, Local(), a); - } - - public static Operand BitwiseOr(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.BitwiseOr, Local(), a, b); - } - - public static Operand Branch(this EmitterContext context, Operand d) - { - return context.Add(Instruction.Branch, d); - } - - public static Operand BranchIfFalse(this EmitterContext context, Operand d, Operand a) - { - return context.Add(Instruction.BranchIfFalse, d, a); - } - - public static Operand BranchIfTrue(this EmitterContext context, Operand d, Operand a) - { - return context.Add(Instruction.BranchIfTrue, d, a); - } - - public static Operand ConditionalSelect(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.ConditionalSelect, Local(), a, b, c); - } - - public static Operand Copy(this EmitterContext context, Operand a) - { - return context.Add(Instruction.Copy, Local(), a); - } - - public static void Copy(this EmitterContext context, Operand d, Operand a) - { - if (d.Type == OperandType.Constant) - { - return; - } - - context.Add(Instruction.Copy, d, a); - } - - public static Operand Discard(this EmitterContext context) - { - return context.Add(Instruction.Discard); - } - - public static Operand EmitVertex(this EmitterContext context) - { - return context.Add(Instruction.EmitVertex); - } - - public static Operand EndPrimitive(this EmitterContext context) - { - return context.Add(Instruction.EndPrimitive); - } - - public static Operand FPAbsNeg(this EmitterContext context, Operand a, bool abs, bool neg) - { - return context.FPNegate(context.FPAbsolute(a, abs), neg); - } - - public static Operand FPAbsolute(this EmitterContext context, Operand a, bool abs) - { - if (abs) - { - a = context.FPAbsolute(a); - } - - return a; - } - - public static Operand FPAbsolute(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Absolute, Local(), a); - } - - public static Operand FPAdd(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.Add, Local(), a, b); - } - - public static Operand FPCeiling(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Ceiling, Local(), a); - } - - public static Operand FPCompareEqual(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.CompareEqual, Local(), a, b); - } - - public static Operand FPCompareLess(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.CompareLess, Local(), a, b); - } - - public static Operand FPConvertToS32(this EmitterContext context, Operand a) - { - return context.Add(Instruction.ConvertFPToS32, Local(), a); - } - - public static Operand FPCosine(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Cosine, Local(), a); - } - - public static Operand FPDivide(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.Divide, Local(), a, b); - } - - public static Operand FPExponentB2(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.ExponentB2, Local(), a); - } - - public static Operand FPFloor(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Floor, Local(), a); - } - - public static Operand FPLogarithmB2(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.LogarithmB2, Local(), a); - } - - public static Operand FPMaximum(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.Maximum, Local(), a, b); - } - - public static Operand FPMinimum(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.Minimum, Local(), a, b); - } - - public static Operand FPMultiply(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.Multiply, Local(), a, b); - } - - public static Operand FPFusedMultiplyAdd(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.FusedMultiplyAdd, Local(), a, b, c); - } - - public static Operand FPNegate(this EmitterContext context, Operand a, bool neg) - { - if (neg) - { - a = context.FPNegate(a); - } - - return a; - } - - public static Operand FPNegate(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Negate, Local(), a); - } - - public static Operand FPReciprocal(this EmitterContext context, Operand a) - { - return context.FPDivide(ConstF(1), a); - } - - public static Operand FPReciprocalSquareRoot(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.ReciprocalSquareRoot, Local(), a); - } - - public static Operand FPSaturate(this EmitterContext context, Operand a, bool sat) - { - if (sat) - { - a = context.FPSaturate(a); - } - - return a; - } - - public static Operand FPSaturate(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Clamp, Local(), a, ConstF(0), ConstF(1)); - } - - public static Operand FPSine(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Sine, Local(), a); - } - - public static Operand FPSquareRoot(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.SquareRoot, Local(), a); - } - - public static Operand FPTruncate(this EmitterContext context, Operand a) - { - return context.Add(Instruction.Truncate, Local(), a); - } - - public static Operand IAbsNeg(this EmitterContext context, Operand a, bool abs, bool neg) - { - return context.INegate(context.IAbsolute(a, abs), neg); - } - - public static Operand IAbsolute(this EmitterContext context, Operand a, bool abs) - { - if (abs) - { - a = context.IAbsolute(a); - } - - return a; - } - - public static Operand IAbsolute(this EmitterContext context, Operand a) - { - return context.Add(Instruction.Absolute, Local(), a); - } - - public static Operand IAdd(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.Add, Local(), a, b); - } - - public static Operand IClampS32(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.Clamp, Local(), a, b, c); - } - - public static Operand IClampU32(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.ClampU32, Local(), a, b, c); - } - - public static Operand ICompareEqual(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.CompareEqual, Local(), a, b); - } - - public static Operand ICompareLess(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.CompareLess, Local(), a, b); - } - - public static Operand ICompareLessUnsigned(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.CompareLessU32, Local(), a, b); - } - - public static Operand ICompareNotEqual(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.CompareNotEqual, Local(), a, b); - } - - public static Operand IConvertS32ToFP(this EmitterContext context, Operand a) - { - return context.Add(Instruction.ConvertS32ToFP, Local(), a); - } - - public static Operand IConvertU32ToFP(this EmitterContext context, Operand a) - { - return context.Add(Instruction.ConvertU32ToFP, Local(), a); - } - - public static Operand IMaximumS32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.Maximum, Local(), a, b); - } - - public static Operand IMaximumU32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.MaximumU32, Local(), a, b); - } - - public static Operand IMinimumS32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.Minimum, Local(), a, b); - } - - public static Operand IMinimumU32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.MinimumU32, Local(), a, b); - } - - public static Operand IMultiply(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.Multiply, Local(), a, b); - } - - public static Operand INegate(this EmitterContext context, Operand a, bool neg) - { - if (neg) - { - a = context.INegate(a); - } - - return a; - } - - public static Operand INegate(this EmitterContext context, Operand a) - { - return context.Add(Instruction.Negate, Local(), a); - } - - public static Operand ISubtract(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.Subtract, Local(), a, b); - } - - public static Operand IsNan(this EmitterContext context, Operand a) - { - return context.Add(Instruction.IsNan, Local(), a); - } - - public static Operand LoadConstant(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.LoadConstant, Local(), a, b); - } - - public static Operand PackHalf2x16(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.PackHalf2x16, Local(), a, b); - } - - public static Operand Return(this EmitterContext context) - { - context.PrepareForReturn(); - - return context.Add(Instruction.Return); - } - - public static Operand ShiftLeft(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.ShiftLeft, Local(), a, b); - } - - public static Operand ShiftRightS32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.ShiftRightS32, Local(), a, b); - } - - public static Operand ShiftRightU32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.ShiftRightU32, Local(), a, b); - } - - public static Operand UnpackHalf2x16High(this EmitterContext context, Operand a) - { - return UnpackHalf2x16(context, a, 1); - } - - public static Operand UnpackHalf2x16Low(this EmitterContext context, Operand a) - { - return UnpackHalf2x16(context, a, 0); - } - - private static Operand UnpackHalf2x16(this EmitterContext context, Operand a, int index) - { - Operand dest = Local(); - - context.Add(new Operation(Instruction.UnpackHalf2x16, index, dest, a)); - - return dest; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Optimizations/BranchElimination.cs b/Ryujinx.Graphics/Shader/Translation/Optimizations/BranchElimination.cs deleted file mode 100644 index 070f07a4..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Optimizations/BranchElimination.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class BranchElimination - { - public static bool Eliminate(BasicBlock block) - { - if (block.HasBranch && IsRedundantBranch((Operation)block.GetLastOp(), Next(block))) - { - block.Branch = null; - - return true; - } - - return false; - } - - private static bool IsRedundantBranch(Operation current, BasicBlock nextBlock) - { - // Here we check that: - // - The current block ends with a branch. - // - The next block only contains a branch. - // - The branch on the next block is unconditional. - // - Both branches are jumping to the same location. - // In this case, the branch on the current block can be removed, - // as the next block is going to jump to the same place anyway. - if (nextBlock == null) - { - return false; - } - - if (!(nextBlock.Operations.First?.Value is Operation next)) - { - return false; - } - - if (next.Inst != Instruction.Branch) - { - return false; - } - - return current.Dest == next.Dest; - } - - private static BasicBlock Next(BasicBlock block) - { - block = block.Next; - - while (block != null && block.Operations.Count == 0) - { - if (block.HasBranch) - { - throw new InvalidOperationException("Found a bogus empty block that \"ends with a branch\"."); - } - - block = block.Next; - } - - return block; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Optimizations/ConstantFolding.cs b/Ryujinx.Graphics/Shader/Translation/Optimizations/ConstantFolding.cs deleted file mode 100644 index a2e05ef1..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Optimizations/ConstantFolding.cs +++ /dev/null @@ -1,323 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class ConstantFolding - { - public static void Fold(Operation operation) - { - if (!AreAllSourcesConstant(operation)) - { - return; - } - - switch (operation.Inst) - { - case Instruction.Add: - EvaluateBinary(operation, (x, y) => x + y); - break; - - case Instruction.BitwiseAnd: - EvaluateBinary(operation, (x, y) => x & y); - break; - - case Instruction.BitwiseExclusiveOr: - EvaluateBinary(operation, (x, y) => x ^ y); - break; - - case Instruction.BitwiseNot: - EvaluateUnary(operation, (x) => ~x); - break; - - case Instruction.BitwiseOr: - EvaluateBinary(operation, (x, y) => x | y); - break; - - case Instruction.BitfieldExtractS32: - BitfieldExtractS32(operation); - break; - - case Instruction.BitfieldExtractU32: - BitfieldExtractU32(operation); - break; - - case Instruction.Clamp: - EvaluateTernary(operation, (x, y, z) => Math.Clamp(x, y, z)); - break; - - case Instruction.ClampU32: - EvaluateTernary(operation, (x, y, z) => (int)Math.Clamp((uint)x, (uint)y, (uint)z)); - break; - - case Instruction.CompareEqual: - EvaluateBinary(operation, (x, y) => x == y); - break; - - case Instruction.CompareGreater: - EvaluateBinary(operation, (x, y) => x > y); - break; - - case Instruction.CompareGreaterOrEqual: - EvaluateBinary(operation, (x, y) => x >= y); - break; - - case Instruction.CompareGreaterOrEqualU32: - EvaluateBinary(operation, (x, y) => (uint)x >= (uint)y); - break; - - case Instruction.CompareGreaterU32: - EvaluateBinary(operation, (x, y) => (uint)x > (uint)y); - break; - - case Instruction.CompareLess: - EvaluateBinary(operation, (x, y) => x < y); - break; - - case Instruction.CompareLessOrEqual: - EvaluateBinary(operation, (x, y) => x <= y); - break; - - case Instruction.CompareLessOrEqualU32: - EvaluateBinary(operation, (x, y) => (uint)x <= (uint)y); - break; - - case Instruction.CompareLessU32: - EvaluateBinary(operation, (x, y) => (uint)x < (uint)y); - break; - - case Instruction.CompareNotEqual: - EvaluateBinary(operation, (x, y) => x != y); - break; - - case Instruction.Divide: - EvaluateBinary(operation, (x, y) => y != 0 ? x / y : 0); - break; - - case Instruction.FP | Instruction.Add: - EvaluateFPBinary(operation, (x, y) => x + y); - break; - - case Instruction.FP | Instruction.Clamp: - EvaluateFPTernary(operation, (x, y, z) => Math.Clamp(x, y, z)); - break; - - case Instruction.FP | Instruction.CompareEqual: - EvaluateFPBinary(operation, (x, y) => x == y); - break; - - case Instruction.FP | Instruction.CompareGreater: - EvaluateFPBinary(operation, (x, y) => x > y); - break; - - case Instruction.FP | Instruction.CompareGreaterOrEqual: - EvaluateFPBinary(operation, (x, y) => x >= y); - break; - - case Instruction.FP | Instruction.CompareLess: - EvaluateFPBinary(operation, (x, y) => x < y); - break; - - case Instruction.FP | Instruction.CompareLessOrEqual: - EvaluateFPBinary(operation, (x, y) => x <= y); - break; - - case Instruction.FP | Instruction.CompareNotEqual: - EvaluateFPBinary(operation, (x, y) => x != y); - break; - - case Instruction.FP | Instruction.Divide: - EvaluateFPBinary(operation, (x, y) => x / y); - break; - - case Instruction.FP | Instruction.Multiply: - EvaluateFPBinary(operation, (x, y) => x * y); - break; - - case Instruction.FP | Instruction.Negate: - EvaluateFPUnary(operation, (x) => -x); - break; - - case Instruction.FP | Instruction.Subtract: - EvaluateFPBinary(operation, (x, y) => x - y); - break; - - case Instruction.IsNan: - EvaluateFPUnary(operation, (x) => float.IsNaN(x)); - break; - - case Instruction.Maximum: - EvaluateBinary(operation, (x, y) => Math.Max(x, y)); - break; - - case Instruction.MaximumU32: - EvaluateBinary(operation, (x, y) => (int)Math.Max((uint)x, (uint)y)); - break; - - case Instruction.Minimum: - EvaluateBinary(operation, (x, y) => Math.Min(x, y)); - break; - - case Instruction.MinimumU32: - EvaluateBinary(operation, (x, y) => (int)Math.Min((uint)x, (uint)y)); - break; - - case Instruction.Multiply: - EvaluateBinary(operation, (x, y) => x * y); - break; - - case Instruction.Negate: - EvaluateUnary(operation, (x) => -x); - break; - - case Instruction.ShiftLeft: - EvaluateBinary(operation, (x, y) => x << y); - break; - - case Instruction.ShiftRightS32: - EvaluateBinary(operation, (x, y) => x >> y); - break; - - case Instruction.ShiftRightU32: - EvaluateBinary(operation, (x, y) => (int)((uint)x >> y)); - break; - - case Instruction.Subtract: - EvaluateBinary(operation, (x, y) => x - y); - break; - - case Instruction.UnpackHalf2x16: - UnpackHalf2x16(operation); - break; - } - } - - private static bool AreAllSourcesConstant(Operation operation) - { - for (int index = 0; index < operation.SourcesCount; index++) - { - if (operation.GetSource(index).Type != OperandType.Constant) - { - return false; - } - } - - return true; - } - - private static void BitfieldExtractS32(Operation operation) - { - int value = GetBitfieldExtractValue(operation); - - int shift = 32 - operation.GetSource(2).Value; - - value = (value << shift) >> shift; - - operation.TurnIntoCopy(Const(value)); - } - - private static void BitfieldExtractU32(Operation operation) - { - operation.TurnIntoCopy(Const(GetBitfieldExtractValue(operation))); - } - - private static int GetBitfieldExtractValue(Operation operation) - { - int value = operation.GetSource(0).Value; - int lsb = operation.GetSource(1).Value; - int length = operation.GetSource(2).Value; - - return value.Extract(lsb, length); - } - - private static void UnpackHalf2x16(Operation operation) - { - int value = operation.GetSource(0).Value; - - value = (value >> operation.ComponentIndex * 16) & 0xffff; - - operation.TurnIntoCopy(ConstF(HalfConversion.HalfToSingle(value))); - } - - private static void FPNegate(Operation operation) - { - float value = operation.GetSource(0).AsFloat(); - - operation.TurnIntoCopy(ConstF(-value)); - } - - private static void EvaluateUnary(Operation operation, Func<int, int> op) - { - int x = operation.GetSource(0).Value; - - operation.TurnIntoCopy(Const(op(x))); - } - - private static void EvaluateFPUnary(Operation operation, Func<float, float> op) - { - float x = operation.GetSource(0).AsFloat(); - - operation.TurnIntoCopy(ConstF(op(x))); - } - - private static void EvaluateFPUnary(Operation operation, Func<float, bool> op) - { - float x = operation.GetSource(0).AsFloat(); - - operation.TurnIntoCopy(Const(op(x) ? IrConsts.True : IrConsts.False)); - } - - private static void EvaluateBinary(Operation operation, Func<int, int, int> op) - { - int x = operation.GetSource(0).Value; - int y = operation.GetSource(1).Value; - - operation.TurnIntoCopy(Const(op(x, y))); - } - - private static void EvaluateBinary(Operation operation, Func<int, int, bool> op) - { - int x = operation.GetSource(0).Value; - int y = operation.GetSource(1).Value; - - operation.TurnIntoCopy(Const(op(x, y) ? IrConsts.True : IrConsts.False)); - } - - private static void EvaluateFPBinary(Operation operation, Func<float, float, float> op) - { - float x = operation.GetSource(0).AsFloat(); - float y = operation.GetSource(1).AsFloat(); - - operation.TurnIntoCopy(ConstF(op(x, y))); - } - - private static void EvaluateFPBinary(Operation operation, Func<float, float, bool> op) - { - float x = operation.GetSource(0).AsFloat(); - float y = operation.GetSource(1).AsFloat(); - - operation.TurnIntoCopy(Const(op(x, y) ? IrConsts.True : IrConsts.False)); - } - - private static void EvaluateTernary(Operation operation, Func<int, int, int, int> op) - { - int x = operation.GetSource(0).Value; - int y = operation.GetSource(1).Value; - int z = operation.GetSource(2).Value; - - operation.TurnIntoCopy(Const(op(x, y, z))); - } - - private static void EvaluateFPTernary(Operation operation, Func<float, float, float, float> op) - { - float x = operation.GetSource(0).AsFloat(); - float y = operation.GetSource(1).AsFloat(); - float z = operation.GetSource(2).AsFloat(); - - operation.TurnIntoCopy(ConstF(op(x, y, z))); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Optimizations/HalfConversion.cs b/Ryujinx.Graphics/Shader/Translation/Optimizations/HalfConversion.cs deleted file mode 100644 index 96060272..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Optimizations/HalfConversion.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class HalfConversion - { - public static float HalfToSingle(int value) - { - int mantissa = (value >> 0) & 0x3ff; - int exponent = (value >> 10) & 0x1f; - int sign = (value >> 15) & 0x1; - - if (exponent == 0x1f) - { - // NaN or Infinity. - mantissa <<= 13; - exponent = 0xff; - } - else if (exponent != 0 || mantissa != 0 ) - { - if (exponent == 0) - { - // Denormal. - int e = -1; - int m = mantissa; - - do - { - e++; - m <<= 1; - } - while ((m & 0x400) == 0); - - mantissa = m & 0x3ff; - exponent = e; - } - - mantissa <<= 13; - exponent = 127 - 15 + exponent; - } - - int output = (sign << 31) | (exponent << 23) | mantissa; - - return BitConverter.Int32BitsToSingle(output); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Optimizations/Optimizer.cs b/Ryujinx.Graphics/Shader/Translation/Optimizations/Optimizer.cs deleted file mode 100644 index 8cce0e74..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Optimizations/Optimizer.cs +++ /dev/null @@ -1,172 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; -using System.Linq; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class Optimizer - { - public static void Optimize(BasicBlock[] blocks) - { - bool modified; - - do - { - modified = false; - - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - BasicBlock block = blocks[blkIndex]; - - LinkedListNode<INode> node = block.Operations.First; - - while (node != null) - { - LinkedListNode<INode> nextNode = node.Next; - - bool isUnused = IsUnused(node.Value); - - if (!(node.Value is Operation operation) || isUnused) - { - if (isUnused) - { - RemoveNode(block, node); - - modified = true; - } - - node = nextNode; - - continue; - } - - ConstantFolding.Fold(operation); - - Simplification.Simplify(operation); - - if (DestIsLocalVar(operation)) - { - if (operation.Inst == Instruction.Copy) - { - PropagateCopy(operation); - - RemoveNode(block, node); - - modified = true; - } - else if (operation.Inst == Instruction.PackHalf2x16 && PropagatePack(operation)) - { - if (operation.Dest.UseOps.Count == 0) - { - RemoveNode(block, node); - } - - modified = true; - } - } - - node = nextNode; - } - - if (BranchElimination.Eliminate(block)) - { - RemoveNode(block, block.Operations.Last); - - modified = true; - } - } - } - while (modified); - } - - private static void PropagateCopy(Operation copyOp) - { - // Propagate copy source operand to all uses of - // the destination operand. - Operand dest = copyOp.Dest; - Operand src = copyOp.GetSource(0); - - INode[] uses = dest.UseOps.ToArray(); - - foreach (INode useNode in uses) - { - for (int index = 0; index < useNode.SourcesCount; index++) - { - if (useNode.GetSource(index) == dest) - { - useNode.SetSource(index, src); - } - } - } - } - - private static bool PropagatePack(Operation packOp) - { - // Propagate pack source operands to uses by unpack - // instruction. The source depends on the unpack instruction. - bool modified = false; - - Operand dest = packOp.Dest; - Operand src0 = packOp.GetSource(0); - Operand src1 = packOp.GetSource(1); - - INode[] uses = dest.UseOps.ToArray(); - - foreach (INode useNode in uses) - { - if (!(useNode is Operation operation) || operation.Inst != Instruction.UnpackHalf2x16) - { - continue; - } - - if (operation.GetSource(0) == dest) - { - operation.TurnIntoCopy(operation.ComponentIndex == 1 ? src1 : src0); - - modified = true; - } - } - - return modified; - } - - private static void RemoveNode(BasicBlock block, LinkedListNode<INode> llNode) - { - // Remove a node from the nodes list, and also remove itself - // from all the use lists on the operands that this node uses. - block.Operations.Remove(llNode); - - Queue<INode> nodes = new Queue<INode>(); - - nodes.Enqueue(llNode.Value); - - while (nodes.TryDequeue(out INode node)) - { - for (int index = 0; index < node.SourcesCount; index++) - { - Operand src = node.GetSource(index); - - if (src.Type != OperandType.LocalVariable) - { - continue; - } - - if (src.UseOps.Remove(node) && src.UseOps.Count == 0) - { - nodes.Enqueue(src.AsgOp); - } - } - } - } - - private static bool IsUnused(INode node) - { - return DestIsLocalVar(node) && node.Dest.UseOps.Count == 0; - } - - private static bool DestIsLocalVar(INode node) - { - return node.Dest != null && node.Dest.Type == OperandType.LocalVariable; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Optimizations/Simplification.cs b/Ryujinx.Graphics/Shader/Translation/Optimizations/Simplification.cs deleted file mode 100644 index d6366dfe..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Optimizations/Simplification.cs +++ /dev/null @@ -1,147 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class Simplification - { - private const int AllOnes = ~0; - - public static void Simplify(Operation operation) - { - switch (operation.Inst) - { - case Instruction.Add: - case Instruction.BitwiseExclusiveOr: - TryEliminateBinaryOpCommutative(operation, 0); - break; - - case Instruction.BitwiseAnd: - TryEliminateBitwiseAnd(operation); - break; - - case Instruction.BitwiseOr: - TryEliminateBitwiseOr(operation); - break; - - case Instruction.ConditionalSelect: - TryEliminateConditionalSelect(operation); - break; - - case Instruction.Divide: - TryEliminateBinaryOpY(operation, 1); - break; - - case Instruction.Multiply: - TryEliminateBinaryOpCommutative(operation, 1); - break; - - case Instruction.ShiftLeft: - case Instruction.ShiftRightS32: - case Instruction.ShiftRightU32: - case Instruction.Subtract: - TryEliminateBinaryOpY(operation, 0); - break; - } - } - - private static void TryEliminateBitwiseAnd(Operation operation) - { - // Try to recognize and optimize those 3 patterns (in order): - // x & 0xFFFFFFFF == x, 0xFFFFFFFF & y == y, - // x & 0x00000000 == 0x00000000, 0x00000000 & y == 0x00000000 - Operand x = operation.GetSource(0); - Operand y = operation.GetSource(1); - - if (IsConstEqual(x, AllOnes)) - { - operation.TurnIntoCopy(y); - } - else if (IsConstEqual(y, AllOnes)) - { - operation.TurnIntoCopy(x); - } - else if (IsConstEqual(x, 0) || IsConstEqual(y, 0)) - { - operation.TurnIntoCopy(Const(0)); - } - } - - private static void TryEliminateBitwiseOr(Operation operation) - { - // Try to recognize and optimize those 3 patterns (in order): - // x | 0x00000000 == x, 0x00000000 | y == y, - // x | 0xFFFFFFFF == 0xFFFFFFFF, 0xFFFFFFFF | y == 0xFFFFFFFF - Operand x = operation.GetSource(0); - Operand y = operation.GetSource(1); - - if (IsConstEqual(x, 0)) - { - operation.TurnIntoCopy(y); - } - else if (IsConstEqual(y, 0)) - { - operation.TurnIntoCopy(x); - } - else if (IsConstEqual(x, AllOnes) || IsConstEqual(y, AllOnes)) - { - operation.TurnIntoCopy(Const(AllOnes)); - } - } - - private static void TryEliminateBinaryOpY(Operation operation, int comparand) - { - Operand x = operation.GetSource(0); - Operand y = operation.GetSource(1); - - if (IsConstEqual(y, comparand)) - { - operation.TurnIntoCopy(x); - } - } - - private static void TryEliminateBinaryOpCommutative(Operation operation, int comparand) - { - Operand x = operation.GetSource(0); - Operand y = operation.GetSource(1); - - if (IsConstEqual(x, comparand)) - { - operation.TurnIntoCopy(y); - } - else if (IsConstEqual(y, comparand)) - { - operation.TurnIntoCopy(x); - } - } - - private static void TryEliminateConditionalSelect(Operation operation) - { - Operand cond = operation.GetSource(0); - - if (cond.Type != OperandType.Constant) - { - return; - } - - // The condition is constant, we can turn it into a copy, and select - // the source based on the condition value. - int srcIndex = cond.Value != 0 ? 1 : 2; - - Operand source = operation.GetSource(srcIndex); - - operation.TurnIntoCopy(source); - } - - private static bool IsConstEqual(Operand operand, int comparand) - { - if (operand.Type != OperandType.Constant) - { - return false; - } - - return operand.Value == comparand; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Ssa.cs b/Ryujinx.Graphics/Shader/Translation/Ssa.cs deleted file mode 100644 index a4d763be..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Ssa.cs +++ /dev/null @@ -1,330 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation -{ - static class Ssa - { - private const int GprsAndPredsCount = RegisterConsts.GprsCount + RegisterConsts.PredsCount; - - private class DefMap - { - private Dictionary<Register, Operand> _map; - - private long[] _phiMasks; - - public DefMap() - { - _map = new Dictionary<Register, Operand>(); - - _phiMasks = new long[(RegisterConsts.TotalCount + 63) / 64]; - } - - public bool TryAddOperand(Register reg, Operand operand) - { - return _map.TryAdd(reg, operand); - } - - public bool TryGetOperand(Register reg, out Operand operand) - { - return _map.TryGetValue(reg, out operand); - } - - public bool AddPhi(Register reg) - { - int key = GetKeyFromRegister(reg); - - int index = key / 64; - int bit = key & 63; - - long mask = 1L << bit; - - if ((_phiMasks[index] & mask) != 0) - { - return false; - } - - _phiMasks[index] |= mask; - - return true; - } - - public bool HasPhi(Register reg) - { - int key = GetKeyFromRegister(reg); - - int index = key / 64; - int bit = key & 63; - - return (_phiMasks[index] & (1L << bit)) != 0; - } - } - - private struct Definition - { - public BasicBlock Block { get; } - public Operand Local { get; } - - public Definition(BasicBlock block, Operand local) - { - Block = block; - Local = local; - } - } - - public static void Rename(BasicBlock[] blocks) - { - DefMap[] globalDefs = new DefMap[blocks.Length]; - - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - globalDefs[blkIndex] = new DefMap(); - } - - Queue<BasicBlock> dfPhiBlocks = new Queue<BasicBlock>(); - - // First pass, get all defs and locals uses. - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - Operand[] localDefs = new Operand[RegisterConsts.TotalCount]; - - Operand RenameLocal(Operand operand) - { - if (operand != null && operand.Type == OperandType.Register) - { - Operand local = localDefs[GetKeyFromRegister(operand.GetRegister())]; - - operand = local ?? operand; - } - - return operand; - } - - BasicBlock block = blocks[blkIndex]; - - LinkedListNode<INode> node = block.Operations.First; - - while (node != null) - { - if (node.Value is Operation operation) - { - for (int index = 0; index < operation.SourcesCount; index++) - { - operation.SetSource(index, RenameLocal(operation.GetSource(index))); - } - - if (operation.Dest != null && operation.Dest.Type == OperandType.Register) - { - Operand local = Local(); - - localDefs[GetKeyFromRegister(operation.Dest.GetRegister())] = local; - - operation.Dest = local; - } - } - - node = node.Next; - } - - for (int index = 0; index < RegisterConsts.TotalCount; index++) - { - Operand local = localDefs[index]; - - if (local == null) - { - continue; - } - - Register reg = GetRegisterFromKey(index); - - globalDefs[block.Index].TryAddOperand(reg, local); - - dfPhiBlocks.Enqueue(block); - - while (dfPhiBlocks.TryDequeue(out BasicBlock dfPhiBlock)) - { - foreach (BasicBlock domFrontier in dfPhiBlock.DominanceFrontiers) - { - if (globalDefs[domFrontier.Index].AddPhi(reg)) - { - dfPhiBlocks.Enqueue(domFrontier); - } - } - } - } - } - - // Second pass, rename variables with definitions on different blocks. - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - Operand[] localDefs = new Operand[RegisterConsts.TotalCount]; - - BasicBlock block = blocks[blkIndex]; - - Operand RenameGlobal(Operand operand) - { - if (operand != null && operand.Type == OperandType.Register) - { - int key = GetKeyFromRegister(operand.GetRegister()); - - Operand local = localDefs[key]; - - if (local != null) - { - return local; - } - - operand = FindDefinitionForCurr(globalDefs, block, operand.GetRegister()); - - localDefs[key] = operand; - } - - return operand; - } - - LinkedListNode<INode> node = block.Operations.First; - - while (node != null) - { - if (node.Value is Operation operation) - { - for (int index = 0; index < operation.SourcesCount; index++) - { - operation.SetSource(index, RenameGlobal(operation.GetSource(index))); - } - } - - node = node.Next; - } - } - } - - private static Operand FindDefinitionForCurr(DefMap[] globalDefs, BasicBlock current, Register reg) - { - if (globalDefs[current.Index].HasPhi(reg)) - { - return InsertPhi(globalDefs, current, reg); - } - - if (current != current.ImmediateDominator) - { - return FindDefinition(globalDefs, current.ImmediateDominator, reg).Local; - } - - return Undef(); - } - - private static Definition FindDefinition(DefMap[] globalDefs, BasicBlock current, Register reg) - { - foreach (BasicBlock block in SelfAndImmediateDominators(current)) - { - DefMap defMap = globalDefs[block.Index]; - - if (defMap.TryGetOperand(reg, out Operand lastDef)) - { - return new Definition(block, lastDef); - } - - if (defMap.HasPhi(reg)) - { - return new Definition(block, InsertPhi(globalDefs, block, reg)); - } - } - - return new Definition(current, Undef()); - } - - private static IEnumerable<BasicBlock> SelfAndImmediateDominators(BasicBlock block) - { - while (block != block.ImmediateDominator) - { - yield return block; - - block = block.ImmediateDominator; - } - - yield return block; - } - - private static Operand InsertPhi(DefMap[] globalDefs, BasicBlock block, Register reg) - { - // This block has a Phi that has not been materialized yet, but that - // would define a new version of the variable we're looking for. We need - // to materialize the Phi, add all the block/operand pairs into the Phi, and - // then use the definition from that Phi. - Operand local = Local(); - - PhiNode phi = new PhiNode(local); - - AddPhi(block, phi); - - globalDefs[block.Index].TryAddOperand(reg, local); - - foreach (BasicBlock predecessor in block.Predecessors) - { - Definition def = FindDefinition(globalDefs, predecessor, reg); - - phi.AddSource(def.Block, def.Local); - } - - return local; - } - - private static void AddPhi(BasicBlock block, PhiNode phi) - { - LinkedListNode<INode> node = block.Operations.First; - - if (node != null) - { - while (node.Next?.Value is PhiNode) - { - node = node.Next; - } - } - - if (node?.Value is PhiNode) - { - block.Operations.AddAfter(node, phi); - } - else - { - block.Operations.AddFirst(phi); - } - } - - private static int GetKeyFromRegister(Register reg) - { - if (reg.Type == RegisterType.Gpr) - { - return reg.Index; - } - else if (reg.Type == RegisterType.Predicate) - { - return RegisterConsts.GprsCount + reg.Index; - } - else /* if (reg.Type == RegisterType.Flag) */ - { - return GprsAndPredsCount + reg.Index; - } - } - - private static Register GetRegisterFromKey(int key) - { - if (key < RegisterConsts.GprsCount) - { - return new Register(key, RegisterType.Gpr); - } - else if (key < GprsAndPredsCount) - { - return new Register(key - RegisterConsts.GprsCount, RegisterType.Predicate); - } - else /* if (key < RegisterConsts.TotalCount) */ - { - return new Register(key - GprsAndPredsCount, RegisterType.Flag); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Translator.cs b/Ryujinx.Graphics/Shader/Translation/Translator.cs deleted file mode 100644 index fcebe913..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Translator.cs +++ /dev/null @@ -1,219 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.CodeGen.Glsl; -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.Instructions; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation.Optimizations; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation -{ - public static class Translator - { - public static ShaderProgram Translate(IGalMemory memory, ulong address, ShaderConfig config) - { - return Translate(memory, address, 0, config); - } - - public static ShaderProgram Translate( - IGalMemory memory, - ulong address, - ulong addressB, - ShaderConfig config) - { - Operation[] shaderOps = DecodeShader(memory, address, config.Type); - - if (addressB != 0) - { - // Dual vertex shader. - Operation[] shaderOpsB = DecodeShader(memory, addressB, config.Type); - - shaderOps = Combine(shaderOps, shaderOpsB); - } - - BasicBlock[] irBlocks = ControlFlowGraph.MakeCfg(shaderOps); - - Dominance.FindDominators(irBlocks[0], irBlocks.Length); - - Dominance.FindDominanceFrontiers(irBlocks); - - Ssa.Rename(irBlocks); - - Optimizer.Optimize(irBlocks); - - StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram(irBlocks); - - GlslProgram program = GlslGenerator.Generate(sInfo, config); - - ShaderProgramInfo spInfo = new ShaderProgramInfo( - program.CBufferDescriptors, - program.TextureDescriptors); - - return new ShaderProgram(spInfo, program.Code); - } - - private static Operation[] DecodeShader(IGalMemory memory, ulong address, GalShaderType shaderType) - { - ShaderHeader header = new ShaderHeader(memory, address); - - Block[] cfg = Decoder.Decode(memory, address); - - EmitterContext context = new EmitterContext(shaderType, header); - - for (int blkIndex = 0; blkIndex < cfg.Length; blkIndex++) - { - Block block = cfg[blkIndex]; - - context.CurrBlock = block; - - context.MarkLabel(context.GetLabel(block.Address)); - - for (int opIndex = 0; opIndex < block.OpCodes.Count; opIndex++) - { - OpCode op = block.OpCodes[opIndex]; - - if (op.NeverExecute) - { - continue; - } - - Operand predSkipLbl = null; - - bool skipPredicateCheck = op.Emitter == InstEmit.Bra; - - if (op is OpCodeSync opSync) - { - // If the instruction is a SYNC instruction with only one - // possible target address, then the instruction is basically - // just a simple branch, we can generate code similar to branch - // instructions, with the condition check on the branch itself. - skipPredicateCheck |= opSync.Targets.Count < 2; - } - - if (!(op.Predicate.IsPT || skipPredicateCheck)) - { - Operand label; - - if (opIndex == block.OpCodes.Count - 1 && block.Next != null) - { - label = context.GetLabel(block.Next.Address); - } - else - { - label = Label(); - - predSkipLbl = label; - } - - Operand pred = Register(op.Predicate); - - if (op.InvertPredicate) - { - context.BranchIfTrue(label, pred); - } - else - { - context.BranchIfFalse(label, pred); - } - } - - context.CurrOp = op; - - op.Emitter(context); - - if (predSkipLbl != null) - { - context.MarkLabel(predSkipLbl); - } - } - } - - return context.GetOperations(); - } - - private static Operation[] Combine(Operation[] a, Operation[] b) - { - // Here we combine two shaders. - // For shader A: - // - All user attribute stores on shader A are turned into copies to a - // temporary variable. It's assumed that shader B will consume them. - // - All return instructions are turned into branch instructions, the - // branch target being the start of the shader B code. - // For shader B: - // - All user attribute loads on shader B are turned into copies from a - // temporary variable, as long that attribute is written by shader A. - List<Operation> output = new List<Operation>(a.Length + b.Length); - - Operand[] temps = new Operand[AttributeConsts.UserAttributesCount * 4]; - - Operand lblB = Label(); - - for (int index = 0; index < a.Length; index++) - { - Operation operation = a[index]; - - if (IsUserAttribute(operation.Dest)) - { - int tIndex = (operation.Dest.Value - AttributeConsts.UserAttributeBase) / 4; - - Operand temp = temps[tIndex]; - - if (temp == null) - { - temp = Local(); - - temps[tIndex] = temp; - } - - operation.Dest = temp; - } - - if (operation.Inst == Instruction.Return) - { - output.Add(new Operation(Instruction.Branch, lblB)); - } - else - { - output.Add(operation); - } - } - - output.Add(new Operation(Instruction.MarkLabel, lblB)); - - for (int index = 0; index < b.Length; index++) - { - Operation operation = b[index]; - - for (int srcIndex = 0; srcIndex < operation.SourcesCount; srcIndex++) - { - Operand src = operation.GetSource(srcIndex); - - if (IsUserAttribute(src)) - { - Operand temp = temps[(src.Value - AttributeConsts.UserAttributeBase) / 4]; - - if (temp != null) - { - operation.SetSource(srcIndex, temp); - } - } - } - - output.Add(operation); - } - - return output.ToArray(); - } - - private static bool IsUserAttribute(Operand operand) - { - return operand != null && - operand.Type == OperandType.Attribute && - operand.Value >= AttributeConsts.UserAttributeBase && - operand.Value < AttributeConsts.UserAttributeEnd; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/BitStreamWriter.cs b/Ryujinx.Graphics/VDec/BitStreamWriter.cs deleted file mode 100644 index db2d39e5..00000000 --- a/Ryujinx.Graphics/VDec/BitStreamWriter.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.IO; - -namespace Ryujinx.Graphics.VDec -{ - class BitStreamWriter - { - private const int BufferSize = 8; - - private Stream _baseStream; - - private int _buffer; - private int _bufferPos; - - public BitStreamWriter(Stream baseStream) - { - _baseStream = baseStream; - } - - public void WriteBit(bool value) - { - WriteBits(value ? 1 : 0, 1); - } - - public void WriteBits(int value, int valueSize) - { - int valuePos = 0; - - int remaining = valueSize; - - while (remaining > 0) - { - int copySize = remaining; - - int free = GetFreeBufferBits(); - - if (copySize > free) - { - copySize = free; - } - - int mask = (1 << copySize) - 1; - - int srcShift = (valueSize - valuePos) - copySize; - int dstShift = (BufferSize - _bufferPos) - copySize; - - _buffer |= ((value >> srcShift) & mask) << dstShift; - - valuePos += copySize; - _bufferPos += copySize; - remaining -= copySize; - } - } - - private int GetFreeBufferBits() - { - if (_bufferPos == BufferSize) - { - Flush(); - } - - return BufferSize - _bufferPos; - } - - public void Flush() - { - if (_bufferPos != 0) - { - _baseStream.WriteByte((byte)_buffer); - - _buffer = 0; - _bufferPos = 0; - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/DecoderHelper.cs b/Ryujinx.Graphics/VDec/DecoderHelper.cs deleted file mode 100644 index 4f17d8d1..00000000 --- a/Ryujinx.Graphics/VDec/DecoderHelper.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.VDec -{ - static class DecoderHelper - { - public static byte[] Combine(byte[] arr0, byte[] arr1) - { - byte[] output = new byte[arr0.Length + arr1.Length]; - - Buffer.BlockCopy(arr0, 0, output, 0, arr0.Length); - Buffer.BlockCopy(arr1, 0, output, arr0.Length, arr1.Length); - - return output; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/FFmpeg.cs b/Ryujinx.Graphics/VDec/FFmpeg.cs deleted file mode 100644 index ccd01f0d..00000000 --- a/Ryujinx.Graphics/VDec/FFmpeg.cs +++ /dev/null @@ -1,168 +0,0 @@ -using FFmpeg.AutoGen; -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.Graphics.VDec -{ - static unsafe class FFmpegWrapper - { - private static AVCodec* _codec; - private static AVCodecContext* _context; - private static AVFrame* _frame; - private static SwsContext* _scalerCtx; - - private static int _scalerWidth; - private static int _scalerHeight; - - public static bool IsInitialized { get; private set; } - - public static void H264Initialize() - { - EnsureCodecInitialized(AVCodecID.AV_CODEC_ID_H264); - } - - public static void Vp9Initialize() - { - EnsureCodecInitialized(AVCodecID.AV_CODEC_ID_VP9); - } - - private static void EnsureCodecInitialized(AVCodecID codecId) - { - if (IsInitialized) - { - Uninitialize(); - } - - _codec = ffmpeg.avcodec_find_decoder(codecId); - _context = ffmpeg.avcodec_alloc_context3(_codec); - _frame = ffmpeg.av_frame_alloc(); - - ffmpeg.avcodec_open2(_context, _codec, null); - - IsInitialized = true; - } - - public static int DecodeFrame(byte[] data) - { - if (!IsInitialized) - { - throw new InvalidOperationException("Tried to use uninitialized codec!"); - } - - AVPacket packet; - - ffmpeg.av_init_packet(&packet); - - fixed (byte* ptr = data) - { - packet.data = ptr; - packet.size = data.Length; - - ffmpeg.avcodec_send_packet(_context, &packet); - } - - return ffmpeg.avcodec_receive_frame(_context, _frame); - } - - public static FFmpegFrame GetFrame() - { - if (!IsInitialized) - { - throw new InvalidOperationException("Tried to use uninitialized codec!"); - } - - AVFrame managedFrame = Marshal.PtrToStructure<AVFrame>((IntPtr)_frame); - - byte*[] data = managedFrame.data.ToArray(); - - return new FFmpegFrame() - { - Width = managedFrame.width, - Height = managedFrame.height, - - LumaPtr = data[0], - ChromaBPtr = data[1], - ChromaRPtr = data[2] - }; - } - - public static FFmpegFrame GetFrameRgba() - { - if (!IsInitialized) - { - throw new InvalidOperationException("Tried to use uninitialized codec!"); - } - - AVFrame managedFrame = Marshal.PtrToStructure<AVFrame>((IntPtr)_frame); - - EnsureScalerSetup(managedFrame.width, managedFrame.height); - - byte*[] data = managedFrame.data.ToArray(); - - int[] lineSizes = managedFrame.linesize.ToArray(); - - byte[] dst = new byte[managedFrame.width * managedFrame.height * 4]; - - fixed (byte* ptr = dst) - { - byte*[] dstData = new byte*[] { ptr }; - - int[] dstLineSizes = new int[] { managedFrame.width * 4 }; - - ffmpeg.sws_scale(_scalerCtx, data, lineSizes, 0, managedFrame.height, dstData, dstLineSizes); - } - - return new FFmpegFrame() - { - Width = managedFrame.width, - Height = managedFrame.height, - - Data = dst - }; - } - - private static void EnsureScalerSetup(int width, int height) - { - if (width == 0 || height == 0) - { - return; - } - - if (_scalerCtx == null || _scalerWidth != width || _scalerHeight != height) - { - FreeScaler(); - - _scalerCtx = ffmpeg.sws_getContext( - width, height, AVPixelFormat.AV_PIX_FMT_YUV420P, - width, height, AVPixelFormat.AV_PIX_FMT_RGBA, 0, null, null, null); - - _scalerWidth = width; - _scalerHeight = height; - } - } - - public static void Uninitialize() - { - if (IsInitialized) - { - ffmpeg.av_frame_unref(_frame); - ffmpeg.av_free(_frame); - ffmpeg.avcodec_close(_context); - - FreeScaler(); - - IsInitialized = false; - } - } - - private static void FreeScaler() - { - if (_scalerCtx != null) - { - ffmpeg.sws_freeContext(_scalerCtx); - - _scalerCtx = null; - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/FFmpegFrame.cs b/Ryujinx.Graphics/VDec/FFmpegFrame.cs deleted file mode 100644 index 535a70c9..00000000 --- a/Ryujinx.Graphics/VDec/FFmpegFrame.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.Graphics.VDec -{ - unsafe struct FFmpegFrame - { - public int Width; - public int Height; - - public byte* LumaPtr; - public byte* ChromaBPtr; - public byte* ChromaRPtr; - - public byte[] Data; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/H264BitStreamWriter.cs b/Ryujinx.Graphics/VDec/H264BitStreamWriter.cs deleted file mode 100644 index b4fad59b..00000000 --- a/Ryujinx.Graphics/VDec/H264BitStreamWriter.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System.IO; - -namespace Ryujinx.Graphics.VDec -{ - class H264BitStreamWriter : BitStreamWriter - { - public H264BitStreamWriter(Stream baseStream) : base(baseStream) { } - - public void WriteU(int value, int valueSize) - { - WriteBits(value, valueSize); - } - - public void WriteSe(int value) - { - WriteExpGolombCodedInt(value); - } - - public void WriteUe(int value) - { - WriteExpGolombCodedUInt((uint)value); - } - - public void End() - { - WriteBit(true); - - Flush(); - } - - private void WriteExpGolombCodedInt(int value) - { - int sign = value <= 0 ? 0 : 1; - - if (value < 0) - { - value = -value; - } - - value = (value << 1) - sign; - - WriteExpGolombCodedUInt((uint)value); - } - - private void WriteExpGolombCodedUInt(uint value) - { - int size = 32 - CountLeadingZeros((int)value + 1); - - WriteBits(1, size); - - value -= (1u << (size - 1)) - 1; - - WriteBits((int)value, size - 1); - } - - private static readonly byte[] ClzNibbleTbl = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; - - private static int CountLeadingZeros(int value) - { - if (value == 0) - { - return 32; - } - - int nibbleIdx = 32; - int preCount, count = 0; - - do - { - nibbleIdx -= 4; - preCount = ClzNibbleTbl[(value >> nibbleIdx) & 0b1111]; - count += preCount; - } - while (preCount == 4); - - return count; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/H264Decoder.cs b/Ryujinx.Graphics/VDec/H264Decoder.cs deleted file mode 100644 index 24c7e0b9..00000000 --- a/Ryujinx.Graphics/VDec/H264Decoder.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System.IO; - -namespace Ryujinx.Graphics.VDec -{ - class H264Decoder - { - private int _log2MaxPicOrderCntLsbMinus4; - private bool _deltaPicOrderAlwaysZeroFlag; - private bool _frameMbsOnlyFlag; - private int _picWidthInMbs; - private int _picHeightInMapUnits; - private bool _entropyCodingModeFlag; - private bool _bottomFieldPicOrderInFramePresentFlag; - private int _numRefIdxL0DefaultActiveMinus1; - private int _numRefIdxL1DefaultActiveMinus1; - private bool _deblockingFilterControlPresentFlag; - private bool _redundantPicCntPresentFlag; - private bool _transform8x8ModeFlag; - private bool _mbAdaptiveFrameFieldFlag; - private bool _direct8x8InferenceFlag; - private bool _weightedPredFlag; - private bool _constrainedIntraPredFlag; - private bool _fieldPicFlag; - private bool _bottomFieldFlag; - private int _log2MaxFrameNumMinus4; - private int _chromaFormatIdc; - private int _picOrderCntType; - private int _picInitQpMinus26; - private int _chromaQpIndexOffset; - private int _chromaQpIndexOffset2; - private int _weightedBipredIdc; - private int _frameNumber; - private byte[] _scalingMatrix4; - private byte[] _scalingMatrix8; - - public void Decode(H264ParameterSets Params, H264Matrices matrices, byte[] frameData) - { - _log2MaxPicOrderCntLsbMinus4 = Params.Log2MaxPicOrderCntLsbMinus4; - _deltaPicOrderAlwaysZeroFlag = Params.DeltaPicOrderAlwaysZeroFlag; - _frameMbsOnlyFlag = Params.FrameMbsOnlyFlag; - _picWidthInMbs = Params.PicWidthInMbs; - _picHeightInMapUnits = Params.PicHeightInMapUnits; - _entropyCodingModeFlag = Params.EntropyCodingModeFlag; - _bottomFieldPicOrderInFramePresentFlag = Params.BottomFieldPicOrderInFramePresentFlag; - _numRefIdxL0DefaultActiveMinus1 = Params.NumRefIdxL0DefaultActiveMinus1; - _numRefIdxL1DefaultActiveMinus1 = Params.NumRefIdxL1DefaultActiveMinus1; - _deblockingFilterControlPresentFlag = Params.DeblockingFilterControlPresentFlag; - _redundantPicCntPresentFlag = Params.RedundantPicCntPresentFlag; - _transform8x8ModeFlag = Params.Transform8x8ModeFlag; - - _mbAdaptiveFrameFieldFlag = ((Params.Flags >> 0) & 1) != 0; - _direct8x8InferenceFlag = ((Params.Flags >> 1) & 1) != 0; - _weightedPredFlag = ((Params.Flags >> 2) & 1) != 0; - _constrainedIntraPredFlag = ((Params.Flags >> 3) & 1) != 0; - _fieldPicFlag = ((Params.Flags >> 5) & 1) != 0; - _bottomFieldFlag = ((Params.Flags >> 6) & 1) != 0; - - _log2MaxFrameNumMinus4 = (int)(Params.Flags >> 8) & 0xf; - _chromaFormatIdc = (int)(Params.Flags >> 12) & 0x3; - _picOrderCntType = (int)(Params.Flags >> 14) & 0x3; - _picInitQpMinus26 = (int)(Params.Flags >> 16) & 0x3f; - _chromaQpIndexOffset = (int)(Params.Flags >> 22) & 0x1f; - _chromaQpIndexOffset2 = (int)(Params.Flags >> 27) & 0x1f; - _weightedBipredIdc = (int)(Params.Flags >> 32) & 0x3; - _frameNumber = (int)(Params.Flags >> 46) & 0x1ffff; - - _picInitQpMinus26 = (_picInitQpMinus26 << 26) >> 26; - _chromaQpIndexOffset = (_chromaQpIndexOffset << 27) >> 27; - _chromaQpIndexOffset2 = (_chromaQpIndexOffset2 << 27) >> 27; - - _scalingMatrix4 = matrices.ScalingMatrix4; - _scalingMatrix8 = matrices.ScalingMatrix8; - - if (FFmpegWrapper.IsInitialized) - { - FFmpegWrapper.DecodeFrame(frameData); - } - else - { - FFmpegWrapper.H264Initialize(); - - FFmpegWrapper.DecodeFrame(DecoderHelper.Combine(EncodeHeader(), frameData)); - } - } - - private byte[] EncodeHeader() - { - using (MemoryStream data = new MemoryStream()) - { - H264BitStreamWriter writer = new H264BitStreamWriter(data); - - // Sequence Parameter Set. - writer.WriteU(1, 24); - writer.WriteU(0, 1); - writer.WriteU(3, 2); - writer.WriteU(7, 5); - writer.WriteU(100, 8); - writer.WriteU(0, 8); - writer.WriteU(31, 8); - writer.WriteUe(0); - writer.WriteUe(_chromaFormatIdc); - - if (_chromaFormatIdc == 3) - { - writer.WriteBit(false); - } - - writer.WriteUe(0); - writer.WriteUe(0); - writer.WriteBit(false); - writer.WriteBit(false); //Scaling matrix present flag - - writer.WriteUe(_log2MaxFrameNumMinus4); - writer.WriteUe(_picOrderCntType); - - if (_picOrderCntType == 0) - { - writer.WriteUe(_log2MaxPicOrderCntLsbMinus4); - } - else if (_picOrderCntType == 1) - { - writer.WriteBit(_deltaPicOrderAlwaysZeroFlag); - - writer.WriteSe(0); - writer.WriteSe(0); - writer.WriteUe(0); - } - - int picHeightInMbs = _picHeightInMapUnits / (_frameMbsOnlyFlag ? 1 : 2); - - writer.WriteUe(16); - writer.WriteBit(false); - writer.WriteUe(_picWidthInMbs - 1); - writer.WriteUe(picHeightInMbs - 1); - writer.WriteBit(_frameMbsOnlyFlag); - - if (!_frameMbsOnlyFlag) - { - writer.WriteBit(_mbAdaptiveFrameFieldFlag); - } - - writer.WriteBit(_direct8x8InferenceFlag); - writer.WriteBit(false); //Frame cropping flag - writer.WriteBit(false); //VUI parameter present flag - - writer.End(); - - // Picture Parameter Set. - writer.WriteU(1, 24); - writer.WriteU(0, 1); - writer.WriteU(3, 2); - writer.WriteU(8, 5); - - writer.WriteUe(0); - writer.WriteUe(0); - - writer.WriteBit(_entropyCodingModeFlag); - writer.WriteBit(false); - writer.WriteUe(0); - writer.WriteUe(_numRefIdxL0DefaultActiveMinus1); - writer.WriteUe(_numRefIdxL1DefaultActiveMinus1); - writer.WriteBit(_weightedPredFlag); - writer.WriteU(_weightedBipredIdc, 2); - writer.WriteSe(_picInitQpMinus26); - writer.WriteSe(0); - writer.WriteSe(_chromaQpIndexOffset); - writer.WriteBit(_deblockingFilterControlPresentFlag); - writer.WriteBit(_constrainedIntraPredFlag); - writer.WriteBit(_redundantPicCntPresentFlag); - writer.WriteBit(_transform8x8ModeFlag); - - writer.WriteBit(true); - - for (int index = 0; index < 6; index++) - { - writer.WriteBit(true); - - WriteScalingList(writer, _scalingMatrix4, index * 16, 16); - } - - if (_transform8x8ModeFlag) - { - for (int index = 0; index < 2; index++) - { - writer.WriteBit(true); - - WriteScalingList(writer, _scalingMatrix8, index * 64, 64); - } - } - - writer.WriteSe(_chromaQpIndexOffset2); - - writer.End(); - - return data.ToArray(); - } - } - - // ZigZag LUTs from libavcodec. - private static readonly byte[] ZigZagDirect = new byte[] - { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63 - }; - - private static readonly byte[] ZigZagScan = new byte[] - { - 0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4, - 1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4, - 1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4, - 3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4 - }; - - private static void WriteScalingList(H264BitStreamWriter writer, byte[] list, int start, int count) - { - byte[] scan = count == 16 ? ZigZagScan : ZigZagDirect; - - int lastScale = 8; - - for (int index = 0; index < count; index++) - { - byte value = list[start + scan[index]]; - - int deltaScale = value - lastScale; - - writer.WriteSe(deltaScale); - - lastScale = value; - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/H264Matrices.cs b/Ryujinx.Graphics/VDec/H264Matrices.cs deleted file mode 100644 index a1524214..00000000 --- a/Ryujinx.Graphics/VDec/H264Matrices.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.VDec -{ - struct H264Matrices - { - public byte[] ScalingMatrix4; - public byte[] ScalingMatrix8; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/H264ParameterSets.cs b/Ryujinx.Graphics/VDec/H264ParameterSets.cs deleted file mode 100644 index f242f0f2..00000000 --- a/Ryujinx.Graphics/VDec/H264ParameterSets.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.Graphics.VDec -{ - [StructLayout(LayoutKind.Sequential, Pack = 4)] - struct H264ParameterSets - { - public int Log2MaxPicOrderCntLsbMinus4; - public bool DeltaPicOrderAlwaysZeroFlag; - public bool FrameMbsOnlyFlag; - public int PicWidthInMbs; - public int PicHeightInMapUnits; - public int Reserved6C; - public bool EntropyCodingModeFlag; - public bool BottomFieldPicOrderInFramePresentFlag; - public int NumRefIdxL0DefaultActiveMinus1; - public int NumRefIdxL1DefaultActiveMinus1; - public bool DeblockingFilterControlPresentFlag; - public bool RedundantPicCntPresentFlag; - public bool Transform8x8ModeFlag; - public int Unknown8C; - public int Unknown90; - public int Reserved94; - public int Unknown98; - public int Reserved9C; - public int ReservedA0; - public int UnknownA4; - public int ReservedA8; - public int UnknownAC; - public long Flags; - public int FrameNumber; - public int FrameNumber2; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/VideoCodec.cs b/Ryujinx.Graphics/VDec/VideoCodec.cs deleted file mode 100644 index f031919d..00000000 --- a/Ryujinx.Graphics/VDec/VideoCodec.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.VDec -{ - enum VideoCodec - { - H264 = 3, - Vp8 = 5, - H265 = 7, - Vp9 = 9 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/VideoDecoder.cs b/Ryujinx.Graphics/VDec/VideoDecoder.cs deleted file mode 100644 index 9bf60c31..00000000 --- a/Ryujinx.Graphics/VDec/VideoDecoder.cs +++ /dev/null @@ -1,281 +0,0 @@ -using ARMeilleure.Memory; -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Memory; -using Ryujinx.Graphics.Texture; -using Ryujinx.Graphics.Vic; -using System; - -namespace Ryujinx.Graphics.VDec -{ - unsafe class VideoDecoder - { - private NvGpu _gpu; - - private H264Decoder _h264Decoder; - private Vp9Decoder _vp9Decoder; - - private VideoCodec _currentVideoCodec; - - private long _decoderContextAddress; - private long _frameDataAddress; - private long _vpxCurrLumaAddress; - private long _vpxRef0LumaAddress; - private long _vpxRef1LumaAddress; - private long _vpxRef2LumaAddress; - private long _vpxCurrChromaAddress; - private long _vpxRef0ChromaAddress; - private long _vpxRef1ChromaAddress; - private long _vpxRef2ChromaAddress; - private long _vpxProbTablesAddress; - - public VideoDecoder(NvGpu gpu) - { - _gpu = gpu; - - _h264Decoder = new H264Decoder(); - _vp9Decoder = new Vp9Decoder(); - } - - public void Process(NvGpuVmm vmm, int methodOffset, int[] arguments) - { - VideoDecoderMeth method = (VideoDecoderMeth)methodOffset; - - switch (method) - { - case VideoDecoderMeth.SetVideoCodec: SetVideoCodec (vmm, arguments); break; - case VideoDecoderMeth.Execute: Execute (vmm, arguments); break; - case VideoDecoderMeth.SetDecoderCtxAddr: SetDecoderCtxAddr (vmm, arguments); break; - case VideoDecoderMeth.SetFrameDataAddr: SetFrameDataAddr (vmm, arguments); break; - case VideoDecoderMeth.SetVpxCurrLumaAddr: SetVpxCurrLumaAddr (vmm, arguments); break; - case VideoDecoderMeth.SetVpxRef0LumaAddr: SetVpxRef0LumaAddr (vmm, arguments); break; - case VideoDecoderMeth.SetVpxRef1LumaAddr: SetVpxRef1LumaAddr (vmm, arguments); break; - case VideoDecoderMeth.SetVpxRef2LumaAddr: SetVpxRef2LumaAddr (vmm, arguments); break; - case VideoDecoderMeth.SetVpxCurrChromaAddr: SetVpxCurrChromaAddr(vmm, arguments); break; - case VideoDecoderMeth.SetVpxRef0ChromaAddr: SetVpxRef0ChromaAddr(vmm, arguments); break; - case VideoDecoderMeth.SetVpxRef1ChromaAddr: SetVpxRef1ChromaAddr(vmm, arguments); break; - case VideoDecoderMeth.SetVpxRef2ChromaAddr: SetVpxRef2ChromaAddr(vmm, arguments); break; - case VideoDecoderMeth.SetVpxProbTablesAddr: SetVpxProbTablesAddr(vmm, arguments); break; - } - } - - private void SetVideoCodec(NvGpuVmm vmm, int[] arguments) - { - _currentVideoCodec = (VideoCodec)arguments[0]; - } - - private void Execute(NvGpuVmm vmm, int[] arguments) - { - if (_currentVideoCodec == VideoCodec.H264) - { - int frameDataSize = vmm.ReadInt32(_decoderContextAddress + 0x48); - - H264ParameterSets Params = MemoryHelper.Read<H264ParameterSets>(vmm.Memory, vmm.GetPhysicalAddress(_decoderContextAddress + 0x58)); - - H264Matrices matrices = new H264Matrices() - { - ScalingMatrix4 = vmm.ReadBytes(_decoderContextAddress + 0x1c0, 6 * 16), - ScalingMatrix8 = vmm.ReadBytes(_decoderContextAddress + 0x220, 2 * 64) - }; - - byte[] frameData = vmm.ReadBytes(_frameDataAddress, frameDataSize); - - _h264Decoder.Decode(Params, matrices, frameData); - } - else if (_currentVideoCodec == VideoCodec.Vp9) - { - int frameDataSize = vmm.ReadInt32(_decoderContextAddress + 0x30); - - Vp9FrameKeys keys = new Vp9FrameKeys() - { - CurrKey = vmm.GetPhysicalAddress(_vpxCurrLumaAddress), - Ref0Key = vmm.GetPhysicalAddress(_vpxRef0LumaAddress), - Ref1Key = vmm.GetPhysicalAddress(_vpxRef1LumaAddress), - Ref2Key = vmm.GetPhysicalAddress(_vpxRef2LumaAddress) - }; - - Vp9FrameHeader header = MemoryHelper.Read<Vp9FrameHeader>(vmm.Memory, vmm.GetPhysicalAddress(_decoderContextAddress + 0x48)); - - Vp9ProbabilityTables probs = new Vp9ProbabilityTables() - { - SegmentationTreeProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x387, 0x7), - SegmentationPredProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x38e, 0x3), - Tx8x8Probs = vmm.ReadBytes(_vpxProbTablesAddress + 0x470, 0x2), - Tx16x16Probs = vmm.ReadBytes(_vpxProbTablesAddress + 0x472, 0x4), - Tx32x32Probs = vmm.ReadBytes(_vpxProbTablesAddress + 0x476, 0x6), - CoefProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x5a0, 0x900), - SkipProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x537, 0x3), - InterModeProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x400, 0x1c), - InterpFilterProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x52a, 0x8), - IsInterProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x41c, 0x4), - CompModeProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x532, 0x5), - SingleRefProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x580, 0xa), - CompRefProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x58a, 0x5), - YModeProbs0 = vmm.ReadBytes(_vpxProbTablesAddress + 0x480, 0x20), - YModeProbs1 = vmm.ReadBytes(_vpxProbTablesAddress + 0x47c, 0x4), - PartitionProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x4e0, 0x40), - MvJointProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x53b, 0x3), - MvSignProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x53e, 0x3), - MvClassProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x54c, 0x14), - MvClass0BitProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x540, 0x3), - MvBitsProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x56c, 0x14), - MvClass0FrProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x560, 0xc), - MvFrProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x542, 0x6), - MvClass0HpProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x548, 0x2), - MvHpProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x54a, 0x2) - }; - - byte[] frameData = vmm.ReadBytes(_frameDataAddress, frameDataSize); - - _vp9Decoder.Decode(keys, header, probs, frameData); - } - else - { - ThrowUnimplementedCodec(); - } - } - - private void SetDecoderCtxAddr(NvGpuVmm vmm, int[] arguments) - { - _decoderContextAddress = GetAddress(arguments); - } - - private void SetFrameDataAddr(NvGpuVmm vmm, int[] arguments) - { - _frameDataAddress = GetAddress(arguments); - } - - private void SetVpxCurrLumaAddr(NvGpuVmm vmm, int[] arguments) - { - _vpxCurrLumaAddress = GetAddress(arguments); - } - - private void SetVpxRef0LumaAddr(NvGpuVmm vmm, int[] arguments) - { - _vpxRef0LumaAddress = GetAddress(arguments); - } - - private void SetVpxRef1LumaAddr(NvGpuVmm vmm, int[] arguments) - { - _vpxRef1LumaAddress = GetAddress(arguments); - } - - private void SetVpxRef2LumaAddr(NvGpuVmm vmm, int[] arguments) - { - _vpxRef2LumaAddress = GetAddress(arguments); - } - - private void SetVpxCurrChromaAddr(NvGpuVmm vmm, int[] arguments) - { - _vpxCurrChromaAddress = GetAddress(arguments); - } - - private void SetVpxRef0ChromaAddr(NvGpuVmm vmm, int[] arguments) - { - _vpxRef0ChromaAddress = GetAddress(arguments); - } - - private void SetVpxRef1ChromaAddr(NvGpuVmm vmm, int[] arguments) - { - _vpxRef1ChromaAddress = GetAddress(arguments); - } - - private void SetVpxRef2ChromaAddr(NvGpuVmm vmm, int[] arguments) - { - _vpxRef2ChromaAddress = GetAddress(arguments); - } - - private void SetVpxProbTablesAddr(NvGpuVmm vmm, int[] arguments) - { - _vpxProbTablesAddress = GetAddress(arguments); - } - - private static long GetAddress(int[] arguments) - { - return (long)(uint)arguments[0] << 8; - } - - internal void CopyPlanes(NvGpuVmm vmm, SurfaceOutputConfig outputConfig) - { - switch (outputConfig.PixelFormat) - { - case SurfacePixelFormat.Rgba8: CopyPlanesRgba8 (vmm, outputConfig); break; - case SurfacePixelFormat.Yuv420P: CopyPlanesYuv420P(vmm, outputConfig); break; - - default: ThrowUnimplementedPixelFormat(outputConfig.PixelFormat); break; - } - } - - private void CopyPlanesRgba8(NvGpuVmm vmm, SurfaceOutputConfig outputConfig) - { - FFmpegFrame frame = FFmpegWrapper.GetFrameRgba(); - - if ((frame.Width | frame.Height) == 0) - { - return; - } - - GalImage image = new GalImage( - outputConfig.SurfaceWidth, - outputConfig.SurfaceHeight, 1, 1, 1, - outputConfig.GobBlockHeight, 1, - GalMemoryLayout.BlockLinear, - GalImageFormat.Rgba8 | GalImageFormat.Unorm, - GalTextureTarget.TwoD); - - ImageUtils.WriteTexture(vmm, image, vmm.GetPhysicalAddress(outputConfig.SurfaceLumaAddress), frame.Data); - } - - private void CopyPlanesYuv420P(NvGpuVmm vmm, SurfaceOutputConfig outputConfig) - { - FFmpegFrame frame = FFmpegWrapper.GetFrame(); - - if ((frame.Width | frame.Height) == 0) - { - return; - } - - int halfSrcWidth = frame.Width / 2; - - int halfWidth = frame.Width / 2; - int halfHeight = frame.Height / 2; - - int alignedWidth = (outputConfig.SurfaceWidth + 0xff) & ~0xff; - - for (int y = 0; y < frame.Height; y++) - { - int src = y * frame.Width; - int dst = y * alignedWidth; - - int size = frame.Width; - - for (int offset = 0; offset < size; offset++) - { - vmm.WriteByte(outputConfig.SurfaceLumaAddress + dst + offset, *(frame.LumaPtr + src + offset)); - } - } - - // Copy chroma data from both channels with interleaving. - for (int y = 0; y < halfHeight; y++) - { - int src = y * halfSrcWidth; - int dst = y * alignedWidth; - - for (int x = 0; x < halfWidth; x++) - { - vmm.WriteByte(outputConfig.SurfaceChromaUAddress + dst + x * 2 + 0, *(frame.ChromaBPtr + src + x)); - vmm.WriteByte(outputConfig.SurfaceChromaUAddress + dst + x * 2 + 1, *(frame.ChromaRPtr + src + x)); - } - } - } - - private void ThrowUnimplementedCodec() - { - throw new NotImplementedException("Codec \"" + _currentVideoCodec + "\" is not supported!"); - } - - private void ThrowUnimplementedPixelFormat(SurfacePixelFormat pixelFormat) - { - throw new NotImplementedException("Pixel format \"" + pixelFormat + "\" is not supported!"); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/VideoDecoderMeth.cs b/Ryujinx.Graphics/VDec/VideoDecoderMeth.cs deleted file mode 100644 index 12286386..00000000 --- a/Ryujinx.Graphics/VDec/VideoDecoderMeth.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Ryujinx.Graphics.VDec -{ - enum VideoDecoderMeth - { - SetVideoCodec = 0x80, - Execute = 0xc0, - SetDecoderCtxAddr = 0x101, - SetFrameDataAddr = 0x102, - SetVpxRef0LumaAddr = 0x10c, - SetVpxRef1LumaAddr = 0x10d, - SetVpxRef2LumaAddr = 0x10e, - SetVpxCurrLumaAddr = 0x10f, - SetVpxRef0ChromaAddr = 0x11d, - SetVpxRef1ChromaAddr = 0x11e, - SetVpxRef2ChromaAddr = 0x11f, - SetVpxCurrChromaAddr = 0x120, - SetVpxProbTablesAddr = 0x170 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/Vp9Decoder.cs b/Ryujinx.Graphics/VDec/Vp9Decoder.cs deleted file mode 100644 index b20a40be..00000000 --- a/Ryujinx.Graphics/VDec/Vp9Decoder.cs +++ /dev/null @@ -1,879 +0,0 @@ -using System.Collections.Generic; -using System.IO; - -namespace Ryujinx.Graphics.VDec -{ - class Vp9Decoder - { - private const int DiffUpdateProbability = 252; - - private const int FrameSyncCode = 0x498342; - - private static readonly int[] MapLut = new int[] - { - 20, 21, 22, 23, 24, 25, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 2, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 3, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 4, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 5, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 6, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 7, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 8, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 9, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 10, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 11, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 12, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 13, - 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 14, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 15, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 16, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 17, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 18, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 19 - }; - - private byte[] DefaultTx8x8Probs = new byte[] { 100, 66 }; - private byte[] DefaultTx16x16Probs = new byte[] { 20, 152, 15, 101 }; - private byte[] DefaultTx32x32Probs = new byte[] { 3, 136, 37, 5, 52, 13 }; - - private byte[] _defaultCoefProbs = new byte[] - { - 195, 29, 183, 0, 84, 49, 136, 0, 8, 42, 71, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 31, 107, 169, 0, 35, 99, 159, 0, - 17, 82, 140, 0, 8, 66, 114, 0, 2, 44, 76, 0, 1, 19, 32, 0, - 40, 132, 201, 0, 29, 114, 187, 0, 13, 91, 157, 0, 7, 75, 127, 0, - 3, 58, 95, 0, 1, 28, 47, 0, 69, 142, 221, 0, 42, 122, 201, 0, - 15, 91, 159, 0, 6, 67, 121, 0, 1, 42, 77, 0, 1, 17, 31, 0, - 102, 148, 228, 0, 67, 117, 204, 0, 17, 82, 154, 0, 6, 59, 114, 0, - 2, 39, 75, 0, 1, 15, 29, 0, 156, 57, 233, 0, 119, 57, 212, 0, - 58, 48, 163, 0, 29, 40, 124, 0, 12, 30, 81, 0, 3, 12, 31, 0, - 191, 107, 226, 0, 124, 117, 204, 0, 25, 99, 155, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 29, 148, 210, 0, 37, 126, 194, 0, - 8, 93, 157, 0, 2, 68, 118, 0, 1, 39, 69, 0, 1, 17, 33, 0, - 41, 151, 213, 0, 27, 123, 193, 0, 3, 82, 144, 0, 1, 58, 105, 0, - 1, 32, 60, 0, 1, 13, 26, 0, 59, 159, 220, 0, 23, 126, 198, 0, - 4, 88, 151, 0, 1, 66, 114, 0, 1, 38, 71, 0, 1, 18, 34, 0, - 114, 136, 232, 0, 51, 114, 207, 0, 11, 83, 155, 0, 3, 56, 105, 0, - 1, 33, 65, 0, 1, 17, 34, 0, 149, 65, 234, 0, 121, 57, 215, 0, - 61, 49, 166, 0, 28, 36, 114, 0, 12, 25, 76, 0, 3, 16, 42, 0, - 214, 49, 220, 0, 132, 63, 188, 0, 42, 65, 137, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 85, 137, 221, 0, 104, 131, 216, 0, - 49, 111, 192, 0, 21, 87, 155, 0, 2, 49, 87, 0, 1, 16, 28, 0, - 89, 163, 230, 0, 90, 137, 220, 0, 29, 100, 183, 0, 10, 70, 135, 0, - 2, 42, 81, 0, 1, 17, 33, 0, 108, 167, 237, 0, 55, 133, 222, 0, - 15, 97, 179, 0, 4, 72, 135, 0, 1, 45, 85, 0, 1, 19, 38, 0, - 124, 146, 240, 0, 66, 124, 224, 0, 17, 88, 175, 0, 4, 58, 122, 0, - 1, 36, 75, 0, 1, 18, 37, 0, 141, 79, 241, 0, 126, 70, 227, 0, - 66, 58, 182, 0, 30, 44, 136, 0, 12, 34, 96, 0, 2, 20, 47, 0, - 229, 99, 249, 0, 143, 111, 235, 0, 46, 109, 192, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 158, 236, 0, 94, 146, 224, 0, - 25, 117, 191, 0, 9, 87, 149, 0, 3, 56, 99, 0, 1, 33, 57, 0, - 83, 167, 237, 0, 68, 145, 222, 0, 10, 103, 177, 0, 2, 72, 131, 0, - 1, 41, 79, 0, 1, 20, 39, 0, 99, 167, 239, 0, 47, 141, 224, 0, - 10, 104, 178, 0, 2, 73, 133, 0, 1, 44, 85, 0, 1, 22, 47, 0, - 127, 145, 243, 0, 71, 129, 228, 0, 17, 93, 177, 0, 3, 61, 124, 0, - 1, 41, 84, 0, 1, 21, 52, 0, 157, 78, 244, 0, 140, 72, 231, 0, - 69, 58, 184, 0, 31, 44, 137, 0, 14, 38, 105, 0, 8, 23, 61, 0, - 125, 34, 187, 0, 52, 41, 133, 0, 6, 31, 56, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 37, 109, 153, 0, 51, 102, 147, 0, - 23, 87, 128, 0, 8, 67, 101, 0, 1, 41, 63, 0, 1, 19, 29, 0, - 31, 154, 185, 0, 17, 127, 175, 0, 6, 96, 145, 0, 2, 73, 114, 0, - 1, 51, 82, 0, 1, 28, 45, 0, 23, 163, 200, 0, 10, 131, 185, 0, - 2, 93, 148, 0, 1, 67, 111, 0, 1, 41, 69, 0, 1, 14, 24, 0, - 29, 176, 217, 0, 12, 145, 201, 0, 3, 101, 156, 0, 1, 69, 111, 0, - 1, 39, 63, 0, 1, 14, 23, 0, 57, 192, 233, 0, 25, 154, 215, 0, - 6, 109, 167, 0, 3, 78, 118, 0, 1, 48, 69, 0, 1, 21, 29, 0, - 202, 105, 245, 0, 108, 106, 216, 0, 18, 90, 144, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 33, 172, 219, 0, 64, 149, 206, 0, - 14, 117, 177, 0, 5, 90, 141, 0, 2, 61, 95, 0, 1, 37, 57, 0, - 33, 179, 220, 0, 11, 140, 198, 0, 1, 89, 148, 0, 1, 60, 104, 0, - 1, 33, 57, 0, 1, 12, 21, 0, 30, 181, 221, 0, 8, 141, 198, 0, - 1, 87, 145, 0, 1, 58, 100, 0, 1, 31, 55, 0, 1, 12, 20, 0, - 32, 186, 224, 0, 7, 142, 198, 0, 1, 86, 143, 0, 1, 58, 100, 0, - 1, 31, 55, 0, 1, 12, 22, 0, 57, 192, 227, 0, 20, 143, 204, 0, - 3, 96, 154, 0, 1, 68, 112, 0, 1, 42, 69, 0, 1, 19, 32, 0, - 212, 35, 215, 0, 113, 47, 169, 0, 29, 48, 105, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 74, 129, 203, 0, 106, 120, 203, 0, - 49, 107, 178, 0, 19, 84, 144, 0, 4, 50, 84, 0, 1, 15, 25, 0, - 71, 172, 217, 0, 44, 141, 209, 0, 15, 102, 173, 0, 6, 76, 133, 0, - 2, 51, 89, 0, 1, 24, 42, 0, 64, 185, 231, 0, 31, 148, 216, 0, - 8, 103, 175, 0, 3, 74, 131, 0, 1, 46, 81, 0, 1, 18, 30, 0, - 65, 196, 235, 0, 25, 157, 221, 0, 5, 105, 174, 0, 1, 67, 120, 0, - 1, 38, 69, 0, 1, 15, 30, 0, 65, 204, 238, 0, 30, 156, 224, 0, - 7, 107, 177, 0, 2, 70, 124, 0, 1, 42, 73, 0, 1, 18, 34, 0, - 225, 86, 251, 0, 144, 104, 235, 0, 42, 99, 181, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 85, 175, 239, 0, 112, 165, 229, 0, - 29, 136, 200, 0, 12, 103, 162, 0, 6, 77, 123, 0, 2, 53, 84, 0, - 75, 183, 239, 0, 30, 155, 221, 0, 3, 106, 171, 0, 1, 74, 128, 0, - 1, 44, 76, 0, 1, 17, 28, 0, 73, 185, 240, 0, 27, 159, 222, 0, - 2, 107, 172, 0, 1, 75, 127, 0, 1, 42, 73, 0, 1, 17, 29, 0, - 62, 190, 238, 0, 21, 159, 222, 0, 2, 107, 172, 0, 1, 72, 122, 0, - 1, 40, 71, 0, 1, 18, 32, 0, 61, 199, 240, 0, 27, 161, 226, 0, - 4, 113, 180, 0, 1, 76, 129, 0, 1, 46, 80, 0, 1, 23, 41, 0, - 7, 27, 153, 0, 5, 30, 95, 0, 1, 16, 30, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 75, 127, 0, 57, 75, 124, 0, - 27, 67, 108, 0, 10, 54, 86, 0, 1, 33, 52, 0, 1, 12, 18, 0, - 43, 125, 151, 0, 26, 108, 148, 0, 7, 83, 122, 0, 2, 59, 89, 0, - 1, 38, 60, 0, 1, 17, 27, 0, 23, 144, 163, 0, 13, 112, 154, 0, - 2, 75, 117, 0, 1, 50, 81, 0, 1, 31, 51, 0, 1, 14, 23, 0, - 18, 162, 185, 0, 6, 123, 171, 0, 1, 78, 125, 0, 1, 51, 86, 0, - 1, 31, 54, 0, 1, 14, 23, 0, 15, 199, 227, 0, 3, 150, 204, 0, - 1, 91, 146, 0, 1, 55, 95, 0, 1, 30, 53, 0, 1, 11, 20, 0, - 19, 55, 240, 0, 19, 59, 196, 0, 3, 52, 105, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 41, 166, 207, 0, 104, 153, 199, 0, - 31, 123, 181, 0, 14, 101, 152, 0, 5, 72, 106, 0, 1, 36, 52, 0, - 35, 176, 211, 0, 12, 131, 190, 0, 2, 88, 144, 0, 1, 60, 101, 0, - 1, 36, 60, 0, 1, 16, 28, 0, 28, 183, 213, 0, 8, 134, 191, 0, - 1, 86, 142, 0, 1, 56, 96, 0, 1, 30, 53, 0, 1, 12, 20, 0, - 20, 190, 215, 0, 4, 135, 192, 0, 1, 84, 139, 0, 1, 53, 91, 0, - 1, 28, 49, 0, 1, 11, 20, 0, 13, 196, 216, 0, 2, 137, 192, 0, - 1, 86, 143, 0, 1, 57, 99, 0, 1, 32, 56, 0, 1, 13, 24, 0, - 211, 29, 217, 0, 96, 47, 156, 0, 22, 43, 87, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 78, 120, 193, 0, 111, 116, 186, 0, - 46, 102, 164, 0, 15, 80, 128, 0, 2, 49, 76, 0, 1, 18, 28, 0, - 71, 161, 203, 0, 42, 132, 192, 0, 10, 98, 150, 0, 3, 69, 109, 0, - 1, 44, 70, 0, 1, 18, 29, 0, 57, 186, 211, 0, 30, 140, 196, 0, - 4, 93, 146, 0, 1, 62, 102, 0, 1, 38, 65, 0, 1, 16, 27, 0, - 47, 199, 217, 0, 14, 145, 196, 0, 1, 88, 142, 0, 1, 57, 98, 0, - 1, 36, 62, 0, 1, 15, 26, 0, 26, 219, 229, 0, 5, 155, 207, 0, - 1, 94, 151, 0, 1, 60, 104, 0, 1, 36, 62, 0, 1, 16, 28, 0, - 233, 29, 248, 0, 146, 47, 220, 0, 43, 52, 140, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 100, 163, 232, 0, 179, 161, 222, 0, - 63, 142, 204, 0, 37, 113, 174, 0, 26, 89, 137, 0, 18, 68, 97, 0, - 85, 181, 230, 0, 32, 146, 209, 0, 7, 100, 164, 0, 3, 71, 121, 0, - 1, 45, 77, 0, 1, 18, 30, 0, 65, 187, 230, 0, 20, 148, 207, 0, - 2, 97, 159, 0, 1, 68, 116, 0, 1, 40, 70, 0, 1, 14, 29, 0, - 40, 194, 227, 0, 8, 147, 204, 0, 1, 94, 155, 0, 1, 65, 112, 0, - 1, 39, 66, 0, 1, 14, 26, 0, 16, 208, 228, 0, 3, 151, 207, 0, - 1, 98, 160, 0, 1, 67, 117, 0, 1, 41, 74, 0, 1, 17, 31, 0, - 17, 38, 140, 0, 7, 34, 80, 0, 1, 17, 29, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 37, 75, 128, 0, 41, 76, 128, 0, - 26, 66, 116, 0, 12, 52, 94, 0, 2, 32, 55, 0, 1, 10, 16, 0, - 50, 127, 154, 0, 37, 109, 152, 0, 16, 82, 121, 0, 5, 59, 85, 0, - 1, 35, 54, 0, 1, 13, 20, 0, 40, 142, 167, 0, 17, 110, 157, 0, - 2, 71, 112, 0, 1, 44, 72, 0, 1, 27, 45, 0, 1, 11, 17, 0, - 30, 175, 188, 0, 9, 124, 169, 0, 1, 74, 116, 0, 1, 48, 78, 0, - 1, 30, 49, 0, 1, 11, 18, 0, 10, 222, 223, 0, 2, 150, 194, 0, - 1, 83, 128, 0, 1, 48, 79, 0, 1, 27, 45, 0, 1, 11, 17, 0, - 36, 41, 235, 0, 29, 36, 193, 0, 10, 27, 111, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 85, 165, 222, 0, 177, 162, 215, 0, - 110, 135, 195, 0, 57, 113, 168, 0, 23, 83, 120, 0, 10, 49, 61, 0, - 85, 190, 223, 0, 36, 139, 200, 0, 5, 90, 146, 0, 1, 60, 103, 0, - 1, 38, 65, 0, 1, 18, 30, 0, 72, 202, 223, 0, 23, 141, 199, 0, - 2, 86, 140, 0, 1, 56, 97, 0, 1, 36, 61, 0, 1, 16, 27, 0, - 55, 218, 225, 0, 13, 145, 200, 0, 1, 86, 141, 0, 1, 57, 99, 0, - 1, 35, 61, 0, 1, 13, 22, 0, 15, 235, 212, 0, 1, 132, 184, 0, - 1, 84, 139, 0, 1, 57, 97, 0, 1, 34, 56, 0, 1, 14, 23, 0, - 181, 21, 201, 0, 61, 37, 123, 0, 10, 38, 71, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 47, 106, 172, 0, 95, 104, 173, 0, - 42, 93, 159, 0, 18, 77, 131, 0, 4, 50, 81, 0, 1, 17, 23, 0, - 62, 147, 199, 0, 44, 130, 189, 0, 28, 102, 154, 0, 18, 75, 115, 0, - 2, 44, 65, 0, 1, 12, 19, 0, 55, 153, 210, 0, 24, 130, 194, 0, - 3, 93, 146, 0, 1, 61, 97, 0, 1, 31, 50, 0, 1, 10, 16, 0, - 49, 186, 223, 0, 17, 148, 204, 0, 1, 96, 142, 0, 1, 53, 83, 0, - 1, 26, 44, 0, 1, 11, 17, 0, 13, 217, 212, 0, 2, 136, 180, 0, - 1, 78, 124, 0, 1, 50, 83, 0, 1, 29, 49, 0, 1, 14, 23, 0, - 197, 13, 247, 0, 82, 17, 222, 0, 25, 17, 162, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 126, 186, 247, 0, 234, 191, 243, 0, - 176, 177, 234, 0, 104, 158, 220, 0, 66, 128, 186, 0, 55, 90, 137, 0, - 111, 197, 242, 0, 46, 158, 219, 0, 9, 104, 171, 0, 2, 65, 125, 0, - 1, 44, 80, 0, 1, 17, 91, 0, 104, 208, 245, 0, 39, 168, 224, 0, - 3, 109, 162, 0, 1, 79, 124, 0, 1, 50, 102, 0, 1, 43, 102, 0, - 84, 220, 246, 0, 31, 177, 231, 0, 2, 115, 180, 0, 1, 79, 134, 0, - 1, 55, 77, 0, 1, 60, 79, 0, 43, 243, 240, 0, 8, 180, 217, 0, - 1, 115, 166, 0, 1, 84, 121, 0, 1, 51, 67, 0, 1, 16, 6, 0 - }; - - private byte[] _defaultSkipProbs = new byte[] { 192, 128, 64 }; - - private byte[] _defaultInterModeProbs = new byte[] - { - 2, 173, 34, 0, 7, 145, 85, 0, 7, 166, 63, 0, 7, 94, 66, 0, - 8, 64, 46, 0, 17, 81, 31, 0, 25, 29, 30, 0 - }; - - private byte[] _defaultInterpFilterProbs = new byte[] - { - 235, 162, 36, 255, 34, 3, 149, 144 - }; - - private byte[] _defaultIsInterProbs = new byte[] { 9, 102, 187, 225 }; - - private byte[] _defaultCompModeProbs = new byte[] { 239, 183, 119, 96, 41 }; - - private byte[] _defaultSingleRefProbs = new byte[] - { - 33, 16, 77, 74, 142, 142, 172, 170, 238, 247 - }; - - private byte[] _defaultCompRefProbs = new byte[] { 50, 126, 123, 221, 226 }; - - private byte[] _defaultYModeProbs0 = new byte[] - { - 65, 32, 18, 144, 162, 194, 41, 51, 132, 68, 18, 165, 217, 196, 45, 40, - 173, 80, 19, 176, 240, 193, 64, 35, 221, 135, 38, 194, 248, 121, 96, 85 - }; - - private byte[] _defaultYModeProbs1 = new byte[] { 98, 78, 46, 29 }; - - private byte[] _defaultPartitionProbs = new byte[] - { - 199, 122, 141, 0, 147, 63, 159, 0, 148, 133, 118, 0, 121, 104, 114, 0, - 174, 73, 87, 0, 92, 41, 83, 0, 82, 99, 50, 0, 53, 39, 39, 0, - 177, 58, 59, 0, 68, 26, 63, 0, 52, 79, 25, 0, 17, 14, 12, 0, - 222, 34, 30, 0, 72, 16, 44, 0, 58, 32, 12, 0, 10, 7, 6, 0 - }; - - private byte[] _defaultMvJointProbs = new byte[] { 32, 64, 96 }; - - private byte[] _defaultMvSignProbs = new byte[] { 128, 128 }; - - private byte[] _defaultMvClassProbs = new byte[] - { - 224, 144, 192, 168, 192, 176, 192, 198, 198, 245, 216, 128, 176, 160, 176, 176, - 192, 198, 198, 208 - }; - - private byte[] _defaultMvClass0BitProbs = new byte[] { 216, 208 }; - - private byte[] _defaultMvBitsProbs = new byte[] - { - 136, 140, 148, 160, 176, 192, 224, 234, 234, 240, 136, 140, 148, 160, 176, 192, - 224, 234, 234, 240 - }; - - private byte[] _defaultMvClass0FrProbs = new byte[] - { - 128, 128, 64, 96, 112, 64, 128, 128, 64, 96, 112, 64 - }; - - private byte[] _defaultMvFrProbs = new byte[] { 64, 96, 64, 64, 96, 64 }; - - private byte[] _defaultMvClass0HpProbs = new byte[] { 160, 160 }; - - private byte[] _defaultMvHpProbs = new byte[] { 128, 128 }; - - private sbyte[] _loopFilterRefDeltas; - private sbyte[] _loopFilterModeDeltas; - - private LinkedList<int> _frameSlotByLastUse; - - private Dictionary<long, LinkedListNode<int>> _cachedRefFrames; - - public Vp9Decoder() - { - _loopFilterRefDeltas = new sbyte[4]; - _loopFilterModeDeltas = new sbyte[2]; - - _frameSlotByLastUse = new LinkedList<int>(); - - for (int slot = 0; slot < 8; slot++) - { - _frameSlotByLastUse.AddFirst(slot); - } - - _cachedRefFrames = new Dictionary<long, LinkedListNode<int>>(); - } - - public void Decode( - Vp9FrameKeys keys, - Vp9FrameHeader header, - Vp9ProbabilityTables probs, - byte[] frameData) - { - bool isKeyFrame = ((header.Flags >> 0) & 1) != 0; - bool lastIsKeyFrame = ((header.Flags >> 1) & 1) != 0; - bool frameSizeChanged = ((header.Flags >> 2) & 1) != 0; - bool errorResilientMode = ((header.Flags >> 3) & 1) != 0; - bool lastShowFrame = ((header.Flags >> 4) & 1) != 0; - bool isFrameIntra = ((header.Flags >> 5) & 1) != 0; - - bool showFrame = !isFrameIntra; - - // Write compressed header. - byte[] compressedHeaderData; - - using (MemoryStream compressedHeader = new MemoryStream()) - { - VpxRangeEncoder writer = new VpxRangeEncoder(compressedHeader); - - if (!header.Lossless) - { - if ((uint)header.TxMode >= 3) - { - writer.Write(3, 2); - writer.Write(header.TxMode == 4); - } - else - { - writer.Write(header.TxMode, 2); - } - } - - if (header.TxMode == 4) - { - WriteProbabilityUpdate(writer, probs.Tx8x8Probs, DefaultTx8x8Probs); - WriteProbabilityUpdate(writer, probs.Tx16x16Probs, DefaultTx16x16Probs); - WriteProbabilityUpdate(writer, probs.Tx32x32Probs, DefaultTx32x32Probs); - } - - WriteCoefProbabilityUpdate(writer, header.TxMode, probs.CoefProbs, _defaultCoefProbs); - - WriteProbabilityUpdate(writer, probs.SkipProbs, _defaultSkipProbs); - - if (!isFrameIntra) - { - WriteProbabilityUpdateAligned4(writer, probs.InterModeProbs, _defaultInterModeProbs); - - if (header.RawInterpolationFilter == 4) - { - WriteProbabilityUpdate(writer, probs.InterpFilterProbs, _defaultInterpFilterProbs); - } - - WriteProbabilityUpdate(writer, probs.IsInterProbs, _defaultIsInterProbs); - - if ((header.RefFrameSignBias[1] & 1) != (header.RefFrameSignBias[2] & 1) || - (header.RefFrameSignBias[1] & 1) != (header.RefFrameSignBias[3] & 1)) - { - if ((uint)header.CompPredMode >= 1) - { - writer.Write(1, 1); - writer.Write(header.CompPredMode == 2); - } - else - { - writer.Write(0, 1); - } - } - - if (header.CompPredMode == 2) - { - WriteProbabilityUpdate(writer, probs.CompModeProbs, _defaultCompModeProbs); - } - - if (header.CompPredMode != 1) - { - WriteProbabilityUpdate(writer, probs.SingleRefProbs, _defaultSingleRefProbs); - } - - if (header.CompPredMode != 0) - { - WriteProbabilityUpdate(writer, probs.CompRefProbs, _defaultCompRefProbs); - } - - for (int index = 0; index < 4; index++) - { - int i = index * 8; - int j = index; - - WriteProbabilityUpdate(writer, probs.YModeProbs0[i + 0], _defaultYModeProbs0[i + 0]); - WriteProbabilityUpdate(writer, probs.YModeProbs0[i + 1], _defaultYModeProbs0[i + 1]); - WriteProbabilityUpdate(writer, probs.YModeProbs0[i + 2], _defaultYModeProbs0[i + 2]); - WriteProbabilityUpdate(writer, probs.YModeProbs0[i + 3], _defaultYModeProbs0[i + 3]); - WriteProbabilityUpdate(writer, probs.YModeProbs0[i + 4], _defaultYModeProbs0[i + 4]); - WriteProbabilityUpdate(writer, probs.YModeProbs0[i + 5], _defaultYModeProbs0[i + 5]); - WriteProbabilityUpdate(writer, probs.YModeProbs0[i + 6], _defaultYModeProbs0[i + 6]); - WriteProbabilityUpdate(writer, probs.YModeProbs0[i + 7], _defaultYModeProbs0[i + 7]); - WriteProbabilityUpdate(writer, probs.YModeProbs1[j + 0], _defaultYModeProbs1[j + 0]); - } - - WriteProbabilityUpdateAligned4(writer, probs.PartitionProbs, _defaultPartitionProbs); - - for (int i = 0; i < 3; i++) - { - WriteMvProbabilityUpdate(writer, probs.MvJointProbs[i], _defaultMvJointProbs[i]); - } - - for (int i = 0; i < 2; i++) - { - WriteMvProbabilityUpdate(writer, probs.MvSignProbs[i], _defaultMvSignProbs[i]); - - for (int j = 0; j < 10; j++) - { - int index = i * 10 + j; - - WriteMvProbabilityUpdate(writer, probs.MvClassProbs[index], _defaultMvClassProbs[index]); - } - - WriteMvProbabilityUpdate(writer, probs.MvClass0BitProbs[i], _defaultMvClass0BitProbs[i]); - - for (int j = 0; j < 10; j++) - { - int index = i * 10 + j; - - WriteMvProbabilityUpdate(writer, probs.MvBitsProbs[index], _defaultMvBitsProbs[index]); - } - } - - for (int i = 0; i < 2; i++) - { - for (int j = 0; j < 2; j++) - { - for (int k = 0; k < 3; k++) - { - int index = i * 2 * 3 + j * 3 + k; - - WriteMvProbabilityUpdate(writer, probs.MvClass0FrProbs[index], _defaultMvClass0FrProbs[index]); - } - } - - for (int j = 0; j < 3; j++) - { - int index = i * 3 + j; - - WriteMvProbabilityUpdate(writer, probs.MvFrProbs[index], _defaultMvFrProbs[index]); - } - } - - if (header.AllowHighPrecisionMv) - { - for (int index = 0; index < 2; index++) - { - WriteMvProbabilityUpdate(writer, probs.MvClass0HpProbs[index], _defaultMvClass0HpProbs[index]); - WriteMvProbabilityUpdate(writer, probs.MvHpProbs[index], _defaultMvHpProbs[index]); - } - } - } - - writer.End(); - - compressedHeaderData = compressedHeader.ToArray(); - } - - // Write uncompressed header. - using (MemoryStream encodedHeader = new MemoryStream()) - { - VpxBitStreamWriter writer = new VpxBitStreamWriter(encodedHeader); - - writer.WriteU(2, 2); //Frame marker. - writer.WriteU(0, 2); //Profile. - writer.WriteBit(false); //Show existing frame. - writer.WriteBit(!isKeyFrame); - writer.WriteBit(showFrame); - writer.WriteBit(errorResilientMode); - - if (isKeyFrame) - { - writer.WriteU(FrameSyncCode, 24); - writer.WriteU(0, 3); //Color space. - writer.WriteU(0, 1); //Color range. - writer.WriteU(header.CurrentFrame.Width - 1, 16); - writer.WriteU(header.CurrentFrame.Height - 1, 16); - writer.WriteBit(false); //Render and frame size different. - - _cachedRefFrames.Clear(); - - // On key frames, all frame slots are set to the current frame, - // so the value of the selected slot doesn't really matter. - GetNewFrameSlot(keys.CurrKey); - } - else - { - if (!showFrame) - { - writer.WriteBit(isFrameIntra); - } - - if (!errorResilientMode) - { - writer.WriteU(0, 2); //Reset frame context. - } - - int refreshFrameFlags = 1 << GetNewFrameSlot(keys.CurrKey); - - if (isFrameIntra) - { - writer.WriteU(FrameSyncCode, 24); - writer.WriteU(refreshFrameFlags, 8); - writer.WriteU(header.CurrentFrame.Width - 1, 16); - writer.WriteU(header.CurrentFrame.Height - 1, 16); - writer.WriteBit(false); //Render and frame size different. - } - else - { - writer.WriteU(refreshFrameFlags, 8); - - int[] refFrameIndex = new int[] - { - GetFrameSlot(keys.Ref0Key), - GetFrameSlot(keys.Ref1Key), - GetFrameSlot(keys.Ref2Key) - }; - - byte[] refFrameSignBias = header.RefFrameSignBias; - - for (int index = 1; index < 4; index++) - { - writer.WriteU(refFrameIndex[index - 1], 3); - writer.WriteU(refFrameSignBias[index], 1); - } - - writer.WriteBit(true); //Frame size with refs. - writer.WriteBit(false); //Render and frame size different. - writer.WriteBit(header.AllowHighPrecisionMv); - writer.WriteBit(header.RawInterpolationFilter == 4); - - if (header.RawInterpolationFilter != 4) - { - writer.WriteU(header.RawInterpolationFilter, 2); - } - } - } - - if (!errorResilientMode) - { - writer.WriteBit(false); //Refresh frame context. - writer.WriteBit(true); //Frame parallel decoding mode. - } - - writer.WriteU(0, 2); //Frame context index. - - writer.WriteU(header.LoopFilterLevel, 6); - writer.WriteU(header.LoopFilterSharpness, 3); - writer.WriteBit(header.LoopFilterDeltaEnabled); - - if (header.LoopFilterDeltaEnabled) - { - bool[] updateLoopFilterRefDeltas = new bool[4]; - bool[] updateLoopFilterModeDeltas = new bool[2]; - - bool loopFilterDeltaUpdate = false; - - for (int index = 0; index < header.LoopFilterRefDeltas.Length; index++) - { - sbyte old = _loopFilterRefDeltas[index]; - sbyte New = header.LoopFilterRefDeltas[index]; - - loopFilterDeltaUpdate |= (updateLoopFilterRefDeltas[index] = old != New); - } - - for (int index = 0; index < header.LoopFilterModeDeltas.Length; index++) - { - sbyte old = _loopFilterModeDeltas[index]; - sbyte New = header.LoopFilterModeDeltas[index]; - - loopFilterDeltaUpdate |= (updateLoopFilterModeDeltas[index] = old != New); - } - - writer.WriteBit(loopFilterDeltaUpdate); - - if (loopFilterDeltaUpdate) - { - for (int index = 0; index < header.LoopFilterRefDeltas.Length; index++) - { - writer.WriteBit(updateLoopFilterRefDeltas[index]); - - if (updateLoopFilterRefDeltas[index]) - { - writer.WriteS(header.LoopFilterRefDeltas[index], 6); - } - } - - for (int index = 0; index < header.LoopFilterModeDeltas.Length; index++) - { - writer.WriteBit(updateLoopFilterModeDeltas[index]); - - if (updateLoopFilterModeDeltas[index]) - { - writer.WriteS(header.LoopFilterModeDeltas[index], 6); - } - } - } - } - - writer.WriteU(header.BaseQIndex, 8); - - writer.WriteDeltaQ(header.DeltaQYDc); - writer.WriteDeltaQ(header.DeltaQUvDc); - writer.WriteDeltaQ(header.DeltaQUvAc); - - writer.WriteBit(false); //Segmentation enabled (TODO). - - int minTileColsLog2 = CalcMinLog2TileCols(header.CurrentFrame.Width); - int maxTileColsLog2 = CalcMaxLog2TileCols(header.CurrentFrame.Width); - - int tileColsLog2Diff = header.TileColsLog2 - minTileColsLog2; - - int tileColsLog2IncMask = (1 << tileColsLog2Diff) - 1; - - // If it's less than the maximum, we need to add an extra 0 on the bitstream - // to indicate that it should stop reading. - if (header.TileColsLog2 < maxTileColsLog2) - { - writer.WriteU(tileColsLog2IncMask << 1, tileColsLog2Diff + 1); - } - else - { - writer.WriteU(tileColsLog2IncMask, tileColsLog2Diff); - } - - bool tileRowsLog2IsNonZero = header.TileRowsLog2 != 0; - - writer.WriteBit(tileRowsLog2IsNonZero); - - if (tileRowsLog2IsNonZero) - { - writer.WriteBit(header.TileRowsLog2 > 1); - } - - writer.WriteU(compressedHeaderData.Length, 16); - - writer.Flush(); - - encodedHeader.Write(compressedHeaderData, 0, compressedHeaderData.Length); - - if (!FFmpegWrapper.IsInitialized) - { - FFmpegWrapper.Vp9Initialize(); - } - - FFmpegWrapper.DecodeFrame(DecoderHelper.Combine(encodedHeader.ToArray(), frameData)); - } - - _loopFilterRefDeltas = header.LoopFilterRefDeltas; - _loopFilterModeDeltas = header.LoopFilterModeDeltas; - } - - private int GetNewFrameSlot(long key) - { - LinkedListNode<int> node = _frameSlotByLastUse.Last; - - _frameSlotByLastUse.RemoveLast(); - _frameSlotByLastUse.AddFirst(node); - - _cachedRefFrames[key] = node; - - return node.Value; - } - - private int GetFrameSlot(long key) - { - if (_cachedRefFrames.TryGetValue(key, out LinkedListNode<int> node)) - { - _frameSlotByLastUse.Remove(node); - _frameSlotByLastUse.AddFirst(node); - - return node.Value; - } - - // Reference frame was lost. - // What we should do in this case? - return 0; - } - - private void WriteProbabilityUpdate(VpxRangeEncoder writer, byte[] New, byte[] old) - { - for (int offset = 0; offset < New.Length; offset++) - { - WriteProbabilityUpdate(writer, New[offset], old[offset]); - } - } - - private void WriteCoefProbabilityUpdate(VpxRangeEncoder writer, int txMode, byte[] New, byte[] old) - { - // Note: There's 1 byte added on each packet for alignment, - // this byte is ignored when doing updates. - const int blockBytes = 2 * 2 * 6 * 6 * 4; - - bool NeedsUpdate(int baseIndex) - { - int index = baseIndex; - - for (int i = 0; i < 2; i++) - for (int j = 0; j < 2; j++) - for (int k = 0; k < 6; k++) - for (int l = 0; l < 6; l++) - { - if (New[index + 0] != old[index + 0] || - New[index + 1] != old[index + 1] || - New[index + 2] != old[index + 2]) - { - return true; - } - - index += 4; - } - - return false; - } - - for (int blockIndex = 0; blockIndex < 4; blockIndex++) - { - int baseIndex = blockIndex * blockBytes; - - bool update = NeedsUpdate(baseIndex); - - writer.Write(update); - - if (update) - { - int index = baseIndex; - - for (int i = 0; i < 2; i++) - for (int j = 0; j < 2; j++) - for (int k = 0; k < 6; k++) - for (int l = 0; l < 6; l++) - { - if (k != 0 || l < 3) - { - WriteProbabilityUpdate(writer, New[index + 0], old[index + 0]); - WriteProbabilityUpdate(writer, New[index + 1], old[index + 1]); - WriteProbabilityUpdate(writer, New[index + 2], old[index + 2]); - } - - index += 4; - } - } - - if (blockIndex == txMode) - { - break; - } - } - } - - private void WriteProbabilityUpdateAligned4(VpxRangeEncoder writer, byte[] New, byte[] old) - { - for (int offset = 0; offset < New.Length; offset += 4) - { - WriteProbabilityUpdate(writer, New[offset + 0], old[offset + 0]); - WriteProbabilityUpdate(writer, New[offset + 1], old[offset + 1]); - WriteProbabilityUpdate(writer, New[offset + 2], old[offset + 2]); - } - } - - private void WriteProbabilityUpdate(VpxRangeEncoder writer, byte New, byte old) - { - bool update = New != old; - - writer.Write(update, DiffUpdateProbability); - - if (update) - { - WriteProbabilityDelta(writer, New, old); - } - } - - private void WriteProbabilityDelta(VpxRangeEncoder writer, int New, int old) - { - int delta = RemapProbability(New, old); - - EncodeTermSubExp(writer, delta); - } - - private int RemapProbability(int New, int old) - { - New--; - old--; - - int index; - - if (old * 2 <= 0xff) - { - index = RecenterNonNeg(New, old) - 1; - } - else - { - index = RecenterNonNeg(0xff - 1 - New, 0xff - 1 - old) - 1; - } - - return MapLut[index]; - } - - private int RecenterNonNeg(int New, int old) - { - if (New > old * 2) - { - return New; - } - else if (New >= old) - { - return (New - old) * 2; - } - else /* if (New < Old) */ - { - return (old - New) * 2 - 1; - } - } - - private void EncodeTermSubExp(VpxRangeEncoder writer, int value) - { - if (WriteLessThan(writer, value, 16)) - { - writer.Write(value, 4); - } - else if (WriteLessThan(writer, value, 32)) - { - writer.Write(value - 16, 4); - } - else if (WriteLessThan(writer, value, 64)) - { - writer.Write(value - 32, 5); - } - else - { - value -= 64; - - const int size = 8; - - int mask = (1 << size) - 191; - - int delta = value - mask; - - if (delta < 0) - { - writer.Write(value, size - 1); - } - else - { - writer.Write(delta / 2 + mask, size - 1); - writer.Write(delta & 1, 1); - } - } - } - - private bool WriteLessThan(VpxRangeEncoder writer, int value, int test) - { - bool isLessThan = value < test; - - writer.Write(!isLessThan); - - return isLessThan; - } - - private void WriteMvProbabilityUpdate(VpxRangeEncoder writer, byte New, byte old) - { - bool update = New != old; - - writer.Write(update, DiffUpdateProbability); - - if (update) - { - writer.Write(New >> 1, 7); - } - } - - private static int CalcMinLog2TileCols(int frameWidth) - { - int sb64Cols = (frameWidth + 63) / 64; - int minLog2 = 0; - - while ((64 << minLog2) < sb64Cols) - { - minLog2++; - } - - return minLog2; - } - - private static int CalcMaxLog2TileCols(int frameWidth) - { - int sb64Cols = (frameWidth + 63) / 64; - int maxLog2 = 1; - - while ((sb64Cols >> maxLog2) >= 4) - { - maxLog2++; - } - - return maxLog2 - 1; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/Vp9FrameHeader.cs b/Ryujinx.Graphics/VDec/Vp9FrameHeader.cs deleted file mode 100644 index bdba6de5..00000000 --- a/Ryujinx.Graphics/VDec/Vp9FrameHeader.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.Graphics.VDec -{ - [StructLayout(LayoutKind.Sequential, Pack = 2)] - struct Vp9FrameDimensions - { - public short Width; - public short Height; - public short SubsamplingX; //? - public short SubsamplingY; //? - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct Vp9FrameHeader - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public Vp9FrameDimensions[] RefFrames; - - public Vp9FrameDimensions CurrentFrame; - - public int Flags; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] - public byte[] RefFrameSignBias; - - public byte LoopFilterLevel; - public byte LoopFilterSharpness; - - public byte BaseQIndex; - public sbyte DeltaQYDc; - public sbyte DeltaQUvDc; - public sbyte DeltaQUvAc; - - [MarshalAs(UnmanagedType.I1)] - public bool Lossless; - - public byte TxMode; - - [MarshalAs(UnmanagedType.I1)] - public bool AllowHighPrecisionMv; - - public byte RawInterpolationFilter; - public byte CompPredMode; - public byte FixCompRef; - public byte VarCompRef0; - public byte VarCompRef1; - - public byte TileColsLog2; - public byte TileRowsLog2; - - [MarshalAs(UnmanagedType.I1)] - public bool SegmentationEnabled; - - [MarshalAs(UnmanagedType.I1)] - public bool SegmentationUpdate; - - [MarshalAs(UnmanagedType.I1)] - public bool SegmentationTemporalUpdate; - - [MarshalAs(UnmanagedType.I1)] - public bool SegmentationAbsOrDeltaUpdate; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8 * 4, ArraySubType = UnmanagedType.I1)] - public bool[] FeatureEnabled; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8 * 4)] - public short[] FeatureData; - - [MarshalAs(UnmanagedType.I1)] - public bool LoopFilterDeltaEnabled; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] - public sbyte[] LoopFilterRefDeltas; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] - public sbyte[] LoopFilterModeDeltas; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/Vp9FrameKeys.cs b/Ryujinx.Graphics/VDec/Vp9FrameKeys.cs deleted file mode 100644 index dfc31ea3..00000000 --- a/Ryujinx.Graphics/VDec/Vp9FrameKeys.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.VDec -{ - struct Vp9FrameKeys - { - public long CurrKey; - public long Ref0Key; - public long Ref1Key; - public long Ref2Key; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/Vp9ProbabilityTables.cs b/Ryujinx.Graphics/VDec/Vp9ProbabilityTables.cs deleted file mode 100644 index 5a6dd0cf..00000000 --- a/Ryujinx.Graphics/VDec/Vp9ProbabilityTables.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace Ryujinx.Graphics.VDec -{ - struct Vp9ProbabilityTables - { - public byte[] SegmentationTreeProbs; - public byte[] SegmentationPredProbs; - public byte[] Tx8x8Probs; - public byte[] Tx16x16Probs; - public byte[] Tx32x32Probs; - public byte[] CoefProbs; - public byte[] SkipProbs; - public byte[] InterModeProbs; - public byte[] InterpFilterProbs; - public byte[] IsInterProbs; - public byte[] CompModeProbs; - public byte[] SingleRefProbs; - public byte[] CompRefProbs; - public byte[] YModeProbs0; - public byte[] YModeProbs1; - public byte[] PartitionProbs; - public byte[] MvJointProbs; - public byte[] MvSignProbs; - public byte[] MvClassProbs; - public byte[] MvClass0BitProbs; - public byte[] MvBitsProbs; - public byte[] MvClass0FrProbs; - public byte[] MvFrProbs; - public byte[] MvClass0HpProbs; - public byte[] MvHpProbs; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/VpxBitStreamWriter.cs b/Ryujinx.Graphics/VDec/VpxBitStreamWriter.cs deleted file mode 100644 index 97ada333..00000000 --- a/Ryujinx.Graphics/VDec/VpxBitStreamWriter.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.IO; - -namespace Ryujinx.Graphics.VDec -{ - class VpxBitStreamWriter : BitStreamWriter - { - public VpxBitStreamWriter(Stream baseStream) : base(baseStream) { } - - public void WriteU(int value, int valueSize) - { - WriteBits(value, valueSize); - } - - public void WriteS(int value, int valueSize) - { - bool sign = value < 0; - - if (sign) - { - value = -value; - } - - WriteBits((value << 1) | (sign ? 1 : 0), valueSize + 1); - } - - public void WriteDeltaQ(int value) - { - bool deltaCoded = value != 0; - - WriteBit(deltaCoded); - - if (deltaCoded) - { - WriteBits(value, 4); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/VDec/VpxRangeEncoder.cs b/Ryujinx.Graphics/VDec/VpxRangeEncoder.cs deleted file mode 100644 index c854c9d9..00000000 --- a/Ryujinx.Graphics/VDec/VpxRangeEncoder.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System.IO; - -namespace Ryujinx.Graphics.VDec -{ - class VpxRangeEncoder - { - private const int HalfProbability = 128; - - private static readonly int[] NormLut = new int[] - { - 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, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - private Stream _baseStream; - - private uint _lowValue; - private uint _range; - private int _count; - - public VpxRangeEncoder(Stream baseStream) - { - _baseStream = baseStream; - - _range = 0xff; - _count = -24; - - Write(false); - } - - public void WriteByte(byte value) - { - Write(value, 8); - } - - public void Write(int value, int valueSize) - { - for (int bit = valueSize - 1; bit >= 0; bit--) - { - Write(((value >> bit) & 1) != 0); - } - } - - public void Write(bool bit) - { - Write(bit, HalfProbability); - } - - public void Write(bool bit, int probability) - { - uint range = _range; - - uint split = 1 + (((range - 1) * (uint)probability) >> 8); - - range = split; - - if (bit) - { - _lowValue += split; - range = _range - split; - } - - int shift = NormLut[range]; - - range <<= shift; - _count += shift; - - if (_count >= 0) - { - int offset = shift - _count; - - if (((_lowValue << (offset - 1)) >> 31) != 0) - { - long currentPos = _baseStream.Position; - - _baseStream.Seek(-1, SeekOrigin.Current); - - while (_baseStream.Position >= 0 && PeekByte() == 0xff) - { - _baseStream.WriteByte(0); - - _baseStream.Seek(-2, SeekOrigin.Current); - } - - _baseStream.WriteByte((byte)(PeekByte() + 1)); - - _baseStream.Seek(currentPos, SeekOrigin.Begin); - } - - _baseStream.WriteByte((byte)(_lowValue >> (24 - offset))); - - _lowValue <<= offset; - shift = _count; - _lowValue &= 0xffffff; - _count -= 8; - } - - _lowValue <<= shift; - - _range = range; - } - - private byte PeekByte() - { - byte value = (byte)_baseStream.ReadByte(); - - _baseStream.Seek(-1, SeekOrigin.Current); - - return value; - } - - public void End() - { - for (int index = 0; index < 32; index++) - { - Write(false); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Vic/StructUnpacker.cs b/Ryujinx.Graphics/Vic/StructUnpacker.cs deleted file mode 100644 index 6b6b9795..00000000 --- a/Ryujinx.Graphics/Vic/StructUnpacker.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Ryujinx.Graphics.Memory; -using System; - -namespace Ryujinx.Graphics.Vic -{ - class StructUnpacker - { - private NvGpuVmm _vmm; - - private long _position; - - private ulong _buffer; - private int _buffPos; - - public StructUnpacker(NvGpuVmm vmm, long position) - { - _vmm = vmm; - _position = position; - - _buffPos = 64; - } - - public int Read(int bits) - { - if ((uint)bits > 32) - { - throw new ArgumentOutOfRangeException(nameof(bits)); - } - - int value = 0; - - while (bits > 0) - { - RefillBufferIfNeeded(); - - int readBits = bits; - - int maxReadBits = 64 - _buffPos; - - if (readBits > maxReadBits) - { - readBits = maxReadBits; - } - - value <<= readBits; - - value |= (int)(_buffer >> _buffPos) & (int)(0xffffffff >> (32 - readBits)); - - _buffPos += readBits; - - bits -= readBits; - } - - return value; - } - - private void RefillBufferIfNeeded() - { - if (_buffPos >= 64) - { - _buffer = _vmm.ReadUInt64(_position); - - _position += 8; - - _buffPos = 0; - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Vic/SurfaceOutputConfig.cs b/Ryujinx.Graphics/Vic/SurfaceOutputConfig.cs deleted file mode 100644 index bdd55fc7..00000000 --- a/Ryujinx.Graphics/Vic/SurfaceOutputConfig.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Ryujinx.Graphics.Vic -{ - struct SurfaceOutputConfig - { - public SurfacePixelFormat PixelFormat; - - public int SurfaceWidth; - public int SurfaceHeight; - public int GobBlockHeight; - - public long SurfaceLumaAddress; - public long SurfaceChromaUAddress; - public long SurfaceChromaVAddress; - - public SurfaceOutputConfig( - SurfacePixelFormat pixelFormat, - int surfaceWidth, - int surfaceHeight, - int gobBlockHeight, - long outputSurfaceLumaAddress, - long outputSurfaceChromaUAddress, - long outputSurfaceChromaVAddress) - { - PixelFormat = pixelFormat; - SurfaceWidth = surfaceWidth; - SurfaceHeight = surfaceHeight; - GobBlockHeight = gobBlockHeight; - SurfaceLumaAddress = outputSurfaceLumaAddress; - SurfaceChromaUAddress = outputSurfaceChromaUAddress; - SurfaceChromaVAddress = outputSurfaceChromaVAddress; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Vic/SurfacePixelFormat.cs b/Ryujinx.Graphics/Vic/SurfacePixelFormat.cs deleted file mode 100644 index 8dabd094..00000000 --- a/Ryujinx.Graphics/Vic/SurfacePixelFormat.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.Vic -{ - enum SurfacePixelFormat - { - Rgba8 = 0x1f, - Yuv420P = 0x44 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Vic/VideoImageComposer.cs b/Ryujinx.Graphics/Vic/VideoImageComposer.cs deleted file mode 100644 index e05bcfdb..00000000 --- a/Ryujinx.Graphics/Vic/VideoImageComposer.cs +++ /dev/null @@ -1,107 +0,0 @@ -using Ryujinx.Graphics.Memory; - -namespace Ryujinx.Graphics.Vic -{ - class VideoImageComposer - { - private NvGpu _gpu; - - private long _configStructAddress; - private long _outputSurfaceLumaAddress; - private long _outputSurfaceChromaUAddress; - private long _outputSurfaceChromaVAddress; - - public VideoImageComposer(NvGpu gpu) - { - _gpu = gpu; - } - - public void Process(NvGpuVmm vmm, int methodOffset, int[] arguments) - { - VideoImageComposerMeth method = (VideoImageComposerMeth)methodOffset; - - switch (method) - { - case VideoImageComposerMeth.Execute: - Execute(vmm, arguments); - break; - - case VideoImageComposerMeth.SetConfigStructOffset: - SetConfigStructOffset(vmm, arguments); - break; - - case VideoImageComposerMeth.SetOutputSurfaceLumaOffset: - SetOutputSurfaceLumaOffset(vmm, arguments); - break; - - case VideoImageComposerMeth.SetOutputSurfaceChromaUOffset: - SetOutputSurfaceChromaUOffset(vmm, arguments); - break; - - case VideoImageComposerMeth.SetOutputSurfaceChromaVOffset: - SetOutputSurfaceChromaVOffset(vmm, arguments); - break; - } - } - - private void Execute(NvGpuVmm vmm, int[] arguments) - { - StructUnpacker unpacker = new StructUnpacker(vmm, _configStructAddress + 0x20); - - SurfacePixelFormat pixelFormat = (SurfacePixelFormat)unpacker.Read(7); - - int chromaLocHoriz = unpacker.Read(2); - int chromaLocVert = unpacker.Read(2); - - int blockLinearKind = unpacker.Read(4); - int blockLinearHeightLog2 = unpacker.Read(4); - - int reserved0 = unpacker.Read(3); - int reserved1 = unpacker.Read(10); - - int surfaceWidthMinus1 = unpacker.Read(14); - int surfaceHeightMinus1 = unpacker.Read(14); - - int gobBlockHeight = 1 << blockLinearHeightLog2; - - int surfaceWidth = surfaceWidthMinus1 + 1; - int surfaceHeight = surfaceHeightMinus1 + 1; - - SurfaceOutputConfig outputConfig = new SurfaceOutputConfig( - pixelFormat, - surfaceWidth, - surfaceHeight, - gobBlockHeight, - _outputSurfaceLumaAddress, - _outputSurfaceChromaUAddress, - _outputSurfaceChromaVAddress); - - _gpu.VideoDecoder.CopyPlanes(vmm, outputConfig); - } - - private void SetConfigStructOffset(NvGpuVmm vmm, int[] arguments) - { - _configStructAddress = GetAddress(arguments); - } - - private void SetOutputSurfaceLumaOffset(NvGpuVmm vmm, int[] arguments) - { - _outputSurfaceLumaAddress = GetAddress(arguments); - } - - private void SetOutputSurfaceChromaUOffset(NvGpuVmm vmm, int[] arguments) - { - _outputSurfaceChromaUAddress = GetAddress(arguments); - } - - private void SetOutputSurfaceChromaVOffset(NvGpuVmm vmm, int[] arguments) - { - _outputSurfaceChromaVAddress = GetAddress(arguments); - } - - private static long GetAddress(int[] arguments) - { - return (long)(uint)arguments[0] << 8; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Vic/VideoImageComposerMeth.cs b/Ryujinx.Graphics/Vic/VideoImageComposerMeth.cs deleted file mode 100644 index b30cabea..00000000 --- a/Ryujinx.Graphics/Vic/VideoImageComposerMeth.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Vic -{ - enum VideoImageComposerMeth - { - Execute = 0xc0, - SetControlParams = 0x1c1, - SetConfigStructOffset = 0x1c2, - SetOutputSurfaceLumaOffset = 0x1c8, - SetOutputSurfaceChromaUOffset = 0x1c9, - SetOutputSurfaceChromaVOffset = 0x1ca - } -}
\ No newline at end of file |
