diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2021-07-07 20:56:06 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-07 20:56:06 -0300 |
| commit | 8b44eb1c981d7106be37107755c7c71c3c3c0ce4 (patch) | |
| tree | 70c3a8d7286d827941c41dee2ec3cb3273c1e6d7 /Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs | |
| parent | 31cbd09a75a9d5f4814c3907a060e0961eb2bb15 (diff) | |
Separate GPU engines and make state follow official docs (part 1/2) (#2422)
* Use DeviceState for compute and i2m
* Migrate 2D class, more comments
* Migrate DMA copy engine
* Remove now unused code
* Replace GpuState by GpuAccessorState on GpuAcessor, since compute no longer has a GpuState
* More comments
* Add logging (disabled)
* Add back i2m on 3D engine
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs | 237 |
1 files changed, 0 insertions, 237 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs b/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs deleted file mode 100644 index 9064051a..00000000 --- a/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs +++ /dev/null @@ -1,237 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Graphics.Gpu.State; -using Ryujinx.Graphics.Texture; -using System; -using System.Runtime.Intrinsics; - -namespace Ryujinx.Graphics.Gpu.Engine -{ - partial class Methods - { - enum CopyFlags - { - SrcLinear = 1 << 7, - DstLinear = 1 << 8, - MultiLineEnable = 1 << 9, - RemapEnable = 1 << 10 - } - - /// <summary> - /// Determine if a buffer-to-texture region covers the entirety of a texture. - /// </summary> - /// <param name="cbp">Copy command parameters</param> - /// <param name="tex">Texture to compare</param> - /// <param name="linear">True if the texture is linear, false if block linear</param> - /// <param name="bpp">Texture bytes per pixel</param> - /// <param name="stride">Texture stride</param> - /// <returns></returns> - private bool IsTextureCopyComplete(CopyBufferParams cbp, CopyBufferTexture tex, bool linear, int bpp, int stride) - { - if (linear) - { - int alignWidth = Constants.StrideAlignment / bpp; - return tex.RegionX == 0 && - tex.RegionY == 0 && - stride / bpp == BitUtils.AlignUp(cbp.XCount, alignWidth); - } - else - { - int alignWidth = Constants.GobAlignment / bpp; - return tex.RegionX == 0 && - tex.RegionY == 0 && - tex.Width == BitUtils.AlignUp(cbp.XCount, alignWidth) && - tex.Height == cbp.YCount; - } - } - - /// <summary> - /// Performs a buffer to buffer, or buffer to texture copy. - /// </summary> - /// <param name="state">Current GPU state</param> - /// <param name="argument">Method call argument</param> - private void CopyBuffer(GpuState state, int argument) - { - var cbp = state.Get<CopyBufferParams>(MethodOffset.CopyBufferParams); - - var swizzle = state.Get<CopyBufferSwizzle>(MethodOffset.CopyBufferSwizzle); - - CopyFlags copyFlags = (CopyFlags)argument; - - bool srcLinear = copyFlags.HasFlag(CopyFlags.SrcLinear); - bool dstLinear = copyFlags.HasFlag(CopyFlags.DstLinear); - bool copy2D = copyFlags.HasFlag(CopyFlags.MultiLineEnable); - bool remap = copyFlags.HasFlag(CopyFlags.RemapEnable); - - int size = cbp.XCount; - - if (size == 0) - { - return; - } - - FlushUboDirty(state.Channel.MemoryManager); - - if (copy2D) - { - // Buffer to texture copy. - int srcBpp = remap ? swizzle.UnpackSrcComponentsCount() * swizzle.UnpackComponentSize() : 1; - int dstBpp = remap ? swizzle.UnpackDstComponentsCount() * swizzle.UnpackComponentSize() : 1; - - var dst = state.Get<CopyBufferTexture>(MethodOffset.CopyBufferDstTexture); - var src = state.Get<CopyBufferTexture>(MethodOffset.CopyBufferSrcTexture); - - var srcCalculator = new OffsetCalculator( - src.Width, - src.Height, - cbp.SrcStride, - srcLinear, - src.MemoryLayout.UnpackGobBlocksInY(), - src.MemoryLayout.UnpackGobBlocksInZ(), - srcBpp); - - var dstCalculator = new OffsetCalculator( - dst.Width, - dst.Height, - cbp.DstStride, - dstLinear, - dst.MemoryLayout.UnpackGobBlocksInY(), - dst.MemoryLayout.UnpackGobBlocksInZ(), - dstBpp); - - ulong srcBaseAddress = state.Channel.MemoryManager.Translate(cbp.SrcAddress.Pack()); - ulong dstBaseAddress = state.Channel.MemoryManager.Translate(cbp.DstAddress.Pack()); - - (int srcBaseOffset, int srcSize) = srcCalculator.GetRectangleRange(src.RegionX, src.RegionY, cbp.XCount, cbp.YCount); - (int dstBaseOffset, int dstSize) = dstCalculator.GetRectangleRange(dst.RegionX, dst.RegionY, cbp.XCount, cbp.YCount); - - ReadOnlySpan<byte> srcSpan = state.Channel.MemoryManager.Physical.GetSpan(srcBaseAddress + (ulong)srcBaseOffset, srcSize, true); - Span<byte> dstSpan = state.Channel.MemoryManager.Physical.GetSpan(dstBaseAddress + (ulong)dstBaseOffset, dstSize).ToArray(); - - bool completeSource = IsTextureCopyComplete(cbp, src, srcLinear, srcBpp, cbp.SrcStride); - bool completeDest = IsTextureCopyComplete(cbp, dst, dstLinear, dstBpp, cbp.DstStride); - - if (completeSource && completeDest) - { - Image.Texture target = state.Channel.MemoryManager.Physical.TextureCache.FindTexture( - state.Channel.MemoryManager, - dst, - cbp, - swizzle, - dstLinear); - - if (target != null) - { - ReadOnlySpan<byte> data; - if (srcLinear) - { - data = LayoutConverter.ConvertLinearStridedToLinear( - target.Info.Width, - target.Info.Height, - 1, - 1, - cbp.SrcStride, - target.Info.FormatInfo.BytesPerPixel, - srcSpan); - } - else - { - data = LayoutConverter.ConvertBlockLinearToLinear( - src.Width, - src.Height, - 1, - target.Info.Levels, - 1, - 1, - 1, - srcBpp, - src.MemoryLayout.UnpackGobBlocksInY(), - src.MemoryLayout.UnpackGobBlocksInZ(), - 1, - new SizeInfo((int)target.Size), - srcSpan); - } - - target.SetData(data); - target.SignalModified(); - - return; - } - else if (srcCalculator.LayoutMatches(dstCalculator)) - { - srcSpan.CopyTo(dstSpan); // No layout conversion has to be performed, just copy the data entirely. - - state.Channel.MemoryManager.Physical.Write(dstBaseAddress + (ulong)dstBaseOffset, dstSpan); - - return; - } - } - - unsafe bool Convert<T>(Span<byte> dstSpan, ReadOnlySpan<byte> srcSpan) where T : unmanaged - { - fixed (byte* dstPtr = dstSpan, srcPtr = srcSpan) - { - byte* dstBase = dstPtr - dstBaseOffset; // Layout offset is relative to the base, so we need to subtract the span's offset. - byte* srcBase = srcPtr - srcBaseOffset; - - for (int y = 0; y < cbp.YCount; y++) - { - srcCalculator.SetY(src.RegionY + y); - dstCalculator.SetY(dst.RegionY + y); - - for (int x = 0; x < cbp.XCount; x++) - { - int srcOffset = srcCalculator.GetOffset(src.RegionX + x); - int dstOffset = dstCalculator.GetOffset(dst.RegionX + x); - - *(T*)(dstBase + dstOffset) = *(T*)(srcBase + srcOffset); - } - } - } - return true; - } - - bool _ = srcBpp switch - { - 1 => Convert<byte>(dstSpan, srcSpan), - 2 => Convert<ushort>(dstSpan, srcSpan), - 4 => Convert<uint>(dstSpan, srcSpan), - 8 => Convert<ulong>(dstSpan, srcSpan), - 12 => Convert<Bpp12Pixel>(dstSpan, srcSpan), - 16 => Convert<Vector128<byte>>(dstSpan, srcSpan), - _ => throw new NotSupportedException($"Unable to copy ${srcBpp} bpp pixel format.") - }; - - state.Channel.MemoryManager.Physical.Write(dstBaseAddress + (ulong)dstBaseOffset, dstSpan); - } - else - { - if (remap && - swizzle.UnpackDstX() == BufferSwizzleComponent.ConstA && - swizzle.UnpackDstY() == BufferSwizzleComponent.ConstA && - swizzle.UnpackDstZ() == BufferSwizzleComponent.ConstA && - swizzle.UnpackDstW() == BufferSwizzleComponent.ConstA && - swizzle.UnpackSrcComponentsCount() == 1 && - swizzle.UnpackDstComponentsCount() == 1 && - swizzle.UnpackComponentSize() == 4) - { - // Fast path for clears when remap is enabled. - state.Channel.MemoryManager.Physical.BufferCache.ClearBuffer( - state.Channel.MemoryManager, - cbp.DstAddress, - (uint)size * 4, - state.Get<uint>(MethodOffset.CopyBufferConstA)); - } - else - { - // TODO: Implement remap functionality. - // Buffer to buffer copy. - state.Channel.MemoryManager.Physical.BufferCache.CopyBuffer( - state.Channel.MemoryManager, - cbp.SrcAddress, - cbp.DstAddress, - (uint)size); - } - } - } - } -}
\ No newline at end of file |
