diff options
| author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
|---|---|---|
| committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
| commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
| tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.Graphics.OpenGL/Image | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Image')
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/FormatConverter.cs | 149 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/ITextureInfo.cs | 14 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/IntermmediatePool.cs | 103 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/Sampler.cs | 64 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureBase.cs | 44 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs | 108 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs | 524 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureCopyIncompatible.cs | 252 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureCopyMS.cs | 276 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs | 212 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureView.cs | 867 |
11 files changed, 0 insertions, 2613 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Image/FormatConverter.cs b/Ryujinx.Graphics.OpenGL/Image/FormatConverter.cs deleted file mode 100644 index c4bbf745..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/FormatConverter.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using System.Numerics; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - static class FormatConverter - { - public unsafe static byte[] ConvertS8D24ToD24S8(ReadOnlySpan<byte> data) - { - byte[] output = new byte[data.Length]; - - int start = 0; - - if (Avx2.IsSupported) - { - var mask = Vector256.Create( - (byte)3, (byte)0, (byte)1, (byte)2, - (byte)7, (byte)4, (byte)5, (byte)6, - (byte)11, (byte)8, (byte)9, (byte)10, - (byte)15, (byte)12, (byte)13, (byte)14, - (byte)19, (byte)16, (byte)17, (byte)18, - (byte)23, (byte)20, (byte)21, (byte)22, - (byte)27, (byte)24, (byte)25, (byte)26, - (byte)31, (byte)28, (byte)29, (byte)30); - - int sizeAligned = data.Length & ~31; - - fixed (byte* pInput = data, pOutput = output) - { - for (uint i = 0; i < sizeAligned; i += 32) - { - var dataVec = Avx.LoadVector256(pInput + i); - - dataVec = Avx2.Shuffle(dataVec, mask); - - Avx.Store(pOutput + i, dataVec); - } - } - - start = sizeAligned; - } - else if (Ssse3.IsSupported) - { - var mask = Vector128.Create( - (byte)3, (byte)0, (byte)1, (byte)2, - (byte)7, (byte)4, (byte)5, (byte)6, - (byte)11, (byte)8, (byte)9, (byte)10, - (byte)15, (byte)12, (byte)13, (byte)14); - - int sizeAligned = data.Length & ~15; - - fixed (byte* pInput = data, pOutput = output) - { - for (uint i = 0; i < sizeAligned; i += 16) - { - var dataVec = Sse2.LoadVector128(pInput + i); - - dataVec = Ssse3.Shuffle(dataVec, mask); - - Sse2.Store(pOutput + i, dataVec); - } - } - - start = sizeAligned; - } - - var outSpan = MemoryMarshal.Cast<byte, uint>(output); - var dataSpan = MemoryMarshal.Cast<byte, uint>(data); - for (int i = start / sizeof(uint); i < dataSpan.Length; i++) - { - outSpan[i] = BitOperations.RotateLeft(dataSpan[i], 8); - } - - return output; - } - - public unsafe static byte[] ConvertD24S8ToS8D24(ReadOnlySpan<byte> data) - { - byte[] output = new byte[data.Length]; - - int start = 0; - - if (Avx2.IsSupported) - { - var mask = Vector256.Create( - (byte)1, (byte)2, (byte)3, (byte)0, - (byte)5, (byte)6, (byte)7, (byte)4, - (byte)9, (byte)10, (byte)11, (byte)8, - (byte)13, (byte)14, (byte)15, (byte)12, - (byte)17, (byte)18, (byte)19, (byte)16, - (byte)21, (byte)22, (byte)23, (byte)20, - (byte)25, (byte)26, (byte)27, (byte)24, - (byte)29, (byte)30, (byte)31, (byte)28); - - int sizeAligned = data.Length & ~31; - - fixed (byte* pInput = data, pOutput = output) - { - for (uint i = 0; i < sizeAligned; i += 32) - { - var dataVec = Avx.LoadVector256(pInput + i); - - dataVec = Avx2.Shuffle(dataVec, mask); - - Avx.Store(pOutput + i, dataVec); - } - } - - start = sizeAligned; - } - else if (Ssse3.IsSupported) - { - var mask = Vector128.Create( - (byte)1, (byte)2, (byte)3, (byte)0, - (byte)5, (byte)6, (byte)7, (byte)4, - (byte)9, (byte)10, (byte)11, (byte)8, - (byte)13, (byte)14, (byte)15, (byte)12); - - int sizeAligned = data.Length & ~15; - - fixed (byte* pInput = data, pOutput = output) - { - for (uint i = 0; i < sizeAligned; i += 16) - { - var dataVec = Sse2.LoadVector128(pInput + i); - - dataVec = Ssse3.Shuffle(dataVec, mask); - - Sse2.Store(pOutput + i, dataVec); - } - } - - start = sizeAligned; - } - - var outSpan = MemoryMarshal.Cast<byte, uint>(output); - var dataSpan = MemoryMarshal.Cast<byte, uint>(data); - for (int i = start / sizeof(uint); i < dataSpan.Length; i++) - { - outSpan[i] = BitOperations.RotateRight(dataSpan[i], 8); - } - - return output; - } - } -} diff --git a/Ryujinx.Graphics.OpenGL/Image/ITextureInfo.cs b/Ryujinx.Graphics.OpenGL/Image/ITextureInfo.cs deleted file mode 100644 index 4c8d7fef..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/ITextureInfo.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.GAL; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - interface ITextureInfo - { - ITextureInfo Storage { get; } - int Handle { get; } - int FirstLayer => 0; - int FirstLevel => 0; - - TextureCreateInfo Info { get; } - } -} diff --git a/Ryujinx.Graphics.OpenGL/Image/IntermmediatePool.cs b/Ryujinx.Graphics.OpenGL/Image/IntermmediatePool.cs deleted file mode 100644 index 4f167e89..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/IntermmediatePool.cs +++ /dev/null @@ -1,103 +0,0 @@ -using Ryujinx.Graphics.GAL; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - class IntermediatePool : IDisposable - { - private readonly OpenGLRenderer _renderer; - private readonly List<TextureView> _entries; - - public IntermediatePool(OpenGLRenderer renderer) - { - _renderer = renderer; - _entries = new List<TextureView>(); - } - - public TextureView GetOrCreateWithAtLeast( - Target target, - int blockWidth, - int blockHeight, - int bytesPerPixel, - Format format, - int width, - int height, - int depth, - int levels, - int samples) - { - TextureView entry; - - for (int i = 0; i < _entries.Count; i++) - { - entry = _entries[i]; - - if (entry.Target == target && entry.Format == format && entry.Info.Samples == samples) - { - if (entry.Width < width || - entry.Height < height || - entry.Info.Depth < depth || - entry.Info.Levels < levels) - { - width = Math.Max(width, entry.Width); - height = Math.Max(height, entry.Height); - depth = Math.Max(depth, entry.Info.Depth); - levels = Math.Max(levels, entry.Info.Levels); - - entry.Dispose(); - entry = CreateNew(target, blockWidth, blockHeight, bytesPerPixel, format, width, height, depth, levels, samples); - _entries[i] = entry; - } - - return entry; - } - } - - entry = CreateNew(target, blockWidth, blockHeight, bytesPerPixel, format, width, height, depth, levels, samples); - _entries.Add(entry); - - return entry; - } - - private TextureView CreateNew( - Target target, - int blockWidth, - int blockHeight, - int bytesPerPixel, - Format format, - int width, - int height, - int depth, - int levels, - int samples) - { - return (TextureView)_renderer.CreateTexture(new TextureCreateInfo( - width, - height, - depth, - levels, - samples, - blockWidth, - blockHeight, - bytesPerPixel, - format, - DepthStencilMode.Depth, - target, - SwizzleComponent.Red, - SwizzleComponent.Green, - SwizzleComponent.Blue, - SwizzleComponent.Alpha), 1f); - } - - public void Dispose() - { - foreach (TextureView entry in _entries) - { - entry.Dispose(); - } - - _entries.Clear(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.OpenGL/Image/Sampler.cs b/Ryujinx.Graphics.OpenGL/Image/Sampler.cs deleted file mode 100644 index f705aa3e..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/Sampler.cs +++ /dev/null @@ -1,64 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.GAL; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - class Sampler : ISampler - { - public int Handle { get; private set; } - - public Sampler(SamplerCreateInfo info) - { - Handle = GL.GenSampler(); - - GL.SamplerParameter(Handle, SamplerParameterName.TextureMinFilter, (int)info.MinFilter.Convert()); - GL.SamplerParameter(Handle, SamplerParameterName.TextureMagFilter, (int)info.MagFilter.Convert()); - - if (HwCapabilities.SupportsSeamlessCubemapPerTexture) - { - GL.SamplerParameter(Handle, (SamplerParameterName)ArbSeamlessCubemapPerTexture.TextureCubeMapSeamless, info.SeamlessCubemap ? 1 : 0); - } - - GL.SamplerParameter(Handle, SamplerParameterName.TextureWrapS, (int)info.AddressU.Convert()); - GL.SamplerParameter(Handle, SamplerParameterName.TextureWrapT, (int)info.AddressV.Convert()); - GL.SamplerParameter(Handle, SamplerParameterName.TextureWrapR, (int)info.AddressP.Convert()); - - GL.SamplerParameter(Handle, SamplerParameterName.TextureCompareMode, (int)info.CompareMode.Convert()); - GL.SamplerParameter(Handle, SamplerParameterName.TextureCompareFunc, (int)info.CompareOp.Convert()); - - unsafe - { - float* borderColor = stackalloc float[4] - { - info.BorderColor.Red, - info.BorderColor.Green, - info.BorderColor.Blue, - info.BorderColor.Alpha - }; - - GL.SamplerParameter(Handle, SamplerParameterName.TextureBorderColor, borderColor); - } - - GL.SamplerParameter(Handle, SamplerParameterName.TextureMinLod, info.MinLod); - GL.SamplerParameter(Handle, SamplerParameterName.TextureMaxLod, info.MaxLod); - GL.SamplerParameter(Handle, SamplerParameterName.TextureLodBias, info.MipLodBias); - - GL.SamplerParameter(Handle, SamplerParameterName.TextureMaxAnisotropyExt, info.MaxAnisotropy); - } - - public void Bind(int unit) - { - GL.BindSampler(unit, Handle); - } - - public void Dispose() - { - if (Handle != 0) - { - GL.DeleteSampler(Handle); - - Handle = 0; - } - } - } -} diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs b/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs deleted file mode 100644 index 2ab9dffb..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs +++ /dev/null @@ -1,44 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.GAL; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - class TextureBase - { - public int Handle { get; protected set; } - - public TextureCreateInfo Info { get; } - - public int Width => Info.Width; - public int Height => Info.Height; - public float ScaleFactor { get; } - - public Target Target => Info.Target; - public Format Format => Info.Format; - - public TextureBase(TextureCreateInfo info, float scaleFactor = 1f) - { - Info = info; - ScaleFactor = scaleFactor; - - Handle = GL.GenTexture(); - } - - public void Bind(int unit) - { - Bind(Target.Convert(), unit); - } - - protected void Bind(TextureTarget target, int unit) - { - GL.ActiveTexture(TextureUnit.Texture0 + unit); - GL.BindTexture(target, Handle); - } - - public static void ClearBinding(int unit) - { - GL.ActiveTexture(TextureUnit.Texture0 + unit); - GL.BindTextureUnit(unit, 0); - } - } -} diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs b/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs deleted file mode 100644 index 1e9e4d6b..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs +++ /dev/null @@ -1,108 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Common.Memory; -using Ryujinx.Graphics.GAL; -using System; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - class TextureBuffer : TextureBase, ITexture - { - private OpenGLRenderer _renderer; - private int _bufferOffset; - private int _bufferSize; - private int _bufferCount; - - private BufferHandle _buffer; - - public TextureBuffer(OpenGLRenderer renderer, TextureCreateInfo info) : base(info) - { - _renderer = renderer; - } - - public void CopyTo(ITexture destination, int firstLayer, int firstLevel) - { - throw new NotSupportedException(); - } - - public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel) - { - throw new NotSupportedException(); - } - - public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter) - { - throw new NotSupportedException(); - } - - public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) - { - throw new NotSupportedException(); - } - - public PinnedSpan<byte> GetData() - { - return Buffer.GetData(_renderer, _buffer, _bufferOffset, _bufferSize); - } - - public PinnedSpan<byte> GetData(int layer, int level) - { - return GetData(); - } - - public void SetData(SpanOrArray<byte> data) - { - var dataSpan = data.AsSpan(); - - Buffer.SetData(_buffer, _bufferOffset, dataSpan.Slice(0, Math.Min(dataSpan.Length, _bufferSize))); - } - - public void SetData(SpanOrArray<byte> data, int layer, int level) - { - throw new NotSupportedException(); - } - - public void SetData(SpanOrArray<byte> data, int layer, int level, Rectangle<int> region) - { - throw new NotSupportedException(); - } - - public void SetStorage(BufferRange buffer) - { - if (_buffer != BufferHandle.Null && - _buffer == buffer.Handle && - buffer.Offset == _bufferOffset && - buffer.Size == _bufferSize && - _renderer.BufferCount == _bufferCount) - { - // Only rebind the buffer when more have been created. - return; - } - - _buffer = buffer.Handle; - _bufferOffset = buffer.Offset; - _bufferSize = buffer.Size; - _bufferCount = _renderer.BufferCount; - - Bind(0); - - SizedInternalFormat format = (SizedInternalFormat)FormatTable.GetFormatInfo(Info.Format).PixelInternalFormat; - - GL.TexBufferRange(TextureBufferTarget.TextureBuffer, format, _buffer.ToInt32(), (IntPtr)buffer.Offset, buffer.Size); - } - - public void Dispose() - { - if (Handle != 0) - { - GL.DeleteTexture(Handle); - - Handle = 0; - } - } - - public void Release() - { - Dispose(); - } - } -} diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs b/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs deleted file mode 100644 index a4b08787..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs +++ /dev/null @@ -1,524 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Common; -using Ryujinx.Graphics.GAL; -using System; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - class TextureCopy : IDisposable - { - private readonly OpenGLRenderer _renderer; - - private int _srcFramebuffer; - private int _dstFramebuffer; - - private int _copyPboHandle; - private int _copyPboSize; - - public IntermediatePool IntermediatePool { get; } - - public TextureCopy(OpenGLRenderer renderer) - { - _renderer = renderer; - IntermediatePool = new IntermediatePool(renderer); - } - - public void Copy( - TextureView src, - TextureView dst, - Extents2D srcRegion, - Extents2D dstRegion, - bool linearFilter, - int srcLayer = 0, - int dstLayer = 0, - int srcLevel = 0, - int dstLevel = 0) - { - int levels = Math.Min(src.Info.Levels - srcLevel, dst.Info.Levels - dstLevel); - int layers = Math.Min(src.Info.GetLayers() - srcLayer, dst.Info.GetLayers() - dstLayer); - - Copy(src, dst, srcRegion, dstRegion, linearFilter, srcLayer, dstLayer, srcLevel, dstLevel, layers, levels); - } - - public void Copy( - TextureView src, - TextureView dst, - Extents2D srcRegion, - Extents2D dstRegion, - bool linearFilter, - int srcLayer, - int dstLayer, - int srcLevel, - int dstLevel, - int layers, - int levels) - { - TextureView srcConverted = src.Format.IsBgr() != dst.Format.IsBgr() ? BgraSwap(src) : src; - - (int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers(); - - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, GetSrcFramebufferLazy()); - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, GetDstFramebufferLazy()); - - if (srcLevel != 0) - { - srcRegion = srcRegion.Reduce(srcLevel); - } - - if (dstLevel != 0) - { - dstRegion = dstRegion.Reduce(dstLevel); - } - - for (int level = 0; level < levels; level++) - { - for (int layer = 0; layer < layers; layer++) - { - if ((srcLayer | dstLayer) != 0 || layers > 1) - { - Attach(FramebufferTarget.ReadFramebuffer, src.Format, srcConverted.Handle, srcLevel + level, srcLayer + layer); - Attach(FramebufferTarget.DrawFramebuffer, dst.Format, dst.Handle, dstLevel + level, dstLayer + layer); - } - else - { - Attach(FramebufferTarget.ReadFramebuffer, src.Format, srcConverted.Handle, srcLevel + level); - Attach(FramebufferTarget.DrawFramebuffer, dst.Format, dst.Handle, dstLevel + level); - } - - ClearBufferMask mask = GetMask(src.Format); - - if ((mask & (ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit)) != 0 || src.Format.IsInteger()) - { - linearFilter = false; - } - - BlitFramebufferFilter filter = linearFilter - ? BlitFramebufferFilter.Linear - : BlitFramebufferFilter.Nearest; - - GL.ReadBuffer(ReadBufferMode.ColorAttachment0); - GL.DrawBuffer(DrawBufferMode.ColorAttachment0); - - GL.Disable(EnableCap.RasterizerDiscard); - GL.Disable(IndexedEnableCap.ScissorTest, 0); - - GL.BlitFramebuffer( - srcRegion.X1, - srcRegion.Y1, - srcRegion.X2, - srcRegion.Y2, - dstRegion.X1, - dstRegion.Y1, - dstRegion.X2, - dstRegion.Y2, - mask, - filter); - } - - if (level < levels - 1) - { - srcRegion = srcRegion.Reduce(1); - dstRegion = dstRegion.Reduce(1); - } - } - - Attach(FramebufferTarget.ReadFramebuffer, src.Format, 0); - Attach(FramebufferTarget.DrawFramebuffer, dst.Format, 0); - - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); - - ((Pipeline)_renderer.Pipeline).RestoreScissor0Enable(); - ((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard(); - - if (srcConverted != src) - { - srcConverted.Dispose(); - } - } - - public void CopyUnscaled( - ITextureInfo src, - ITextureInfo dst, - int srcLayer, - int dstLayer, - int srcLevel, - int dstLevel) - { - TextureCreateInfo srcInfo = src.Info; - TextureCreateInfo dstInfo = dst.Info; - - int srcDepth = srcInfo.GetDepthOrLayers(); - int srcLevels = srcInfo.Levels; - - int dstDepth = dstInfo.GetDepthOrLayers(); - int dstLevels = dstInfo.Levels; - - if (dstInfo.Target == Target.Texture3D) - { - dstDepth = Math.Max(1, dstDepth >> dstLevel); - } - - int depth = Math.Min(srcDepth, dstDepth); - int levels = Math.Min(srcLevels, dstLevels); - - CopyUnscaled(src, dst, srcLayer, dstLayer, srcLevel, dstLevel, depth, levels); - } - - public void CopyUnscaled( - ITextureInfo src, - ITextureInfo dst, - int srcLayer, - int dstLayer, - int srcLevel, - int dstLevel, - int depth, - int levels) - { - TextureCreateInfo srcInfo = src.Info; - TextureCreateInfo dstInfo = dst.Info; - - int srcHandle = src.Handle; - int dstHandle = dst.Handle; - - int srcWidth = srcInfo.Width; - int srcHeight = srcInfo.Height; - - int dstWidth = dstInfo.Width; - int dstHeight = dstInfo.Height; - - srcWidth = Math.Max(1, srcWidth >> srcLevel); - srcHeight = Math.Max(1, srcHeight >> srcLevel); - - dstWidth = Math.Max(1, dstWidth >> dstLevel); - dstHeight = Math.Max(1, dstHeight >> dstLevel); - - int blockWidth = 1; - int blockHeight = 1; - bool sizeInBlocks = false; - - // When copying from a compressed to a non-compressed format, - // the non-compressed texture will have the size of the texture - // in blocks (not in texels), so we must adjust that size to - // match the size in texels of the compressed texture. - if (!srcInfo.IsCompressed && dstInfo.IsCompressed) - { - srcWidth *= dstInfo.BlockWidth; - srcHeight *= dstInfo.BlockHeight; - blockWidth = dstInfo.BlockWidth; - blockHeight = dstInfo.BlockHeight; - - sizeInBlocks = true; - } - else if (srcInfo.IsCompressed && !dstInfo.IsCompressed) - { - dstWidth *= srcInfo.BlockWidth; - dstHeight *= srcInfo.BlockHeight; - blockWidth = srcInfo.BlockWidth; - blockHeight = srcInfo.BlockHeight; - } - - int width = Math.Min(srcWidth, dstWidth); - int height = Math.Min(srcHeight, dstHeight); - - for (int level = 0; level < levels; level++) - { - // Stop copy if we are already out of the levels range. - if (level >= srcInfo.Levels || dstLevel + level >= dstInfo.Levels) - { - break; - } - - if ((width % blockWidth != 0 || height % blockHeight != 0) && src is TextureView srcView && dst is TextureView dstView) - { - PboCopy(srcView, dstView, srcLayer, dstLayer, srcLevel + level, dstLevel + level, width, height); - } - else - { - int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width; - int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height; - - if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows) - { - GL.CopyImageSubData( - src.Storage.Handle, - src.Storage.Info.Target.ConvertToImageTarget(), - src.FirstLevel + srcLevel + level, - 0, - 0, - src.FirstLayer + srcLayer, - dst.Storage.Handle, - dst.Storage.Info.Target.ConvertToImageTarget(), - dst.FirstLevel + dstLevel + level, - 0, - 0, - dst.FirstLayer + dstLayer, - copyWidth, - copyHeight, - depth); - } - else - { - GL.CopyImageSubData( - srcHandle, - srcInfo.Target.ConvertToImageTarget(), - srcLevel + level, - 0, - 0, - srcLayer, - dstHandle, - dstInfo.Target.ConvertToImageTarget(), - dstLevel + level, - 0, - 0, - dstLayer, - copyWidth, - copyHeight, - depth); - } - } - - width = Math.Max(1, width >> 1); - height = Math.Max(1, height >> 1); - - if (srcInfo.Target == Target.Texture3D) - { - depth = Math.Max(1, depth >> 1); - } - } - } - - private static FramebufferAttachment AttachmentForFormat(Format format) - { - if (format == Format.D24UnormS8Uint || format == Format.D32FloatS8Uint) - { - return FramebufferAttachment.DepthStencilAttachment; - } - else if (IsDepthOnly(format)) - { - return FramebufferAttachment.DepthAttachment; - } - else if (format == Format.S8Uint) - { - return FramebufferAttachment.StencilAttachment; - } - else - { - return FramebufferAttachment.ColorAttachment0; - } - } - - private static void Attach(FramebufferTarget target, Format format, int handle, int level = 0) - { - FramebufferAttachment attachment = AttachmentForFormat(format); - - GL.FramebufferTexture(target, attachment, handle, level); - } - - private static void Attach(FramebufferTarget target, Format format, int handle, int level, int layer) - { - FramebufferAttachment attachment = AttachmentForFormat(format); - - GL.FramebufferTextureLayer(target, attachment, handle, level, layer); - } - - private static ClearBufferMask GetMask(Format format) - { - if (format == Format.D24UnormS8Uint || format == Format.D32FloatS8Uint || format == Format.S8UintD24Unorm) - { - return ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit; - } - else if (IsDepthOnly(format)) - { - return ClearBufferMask.DepthBufferBit; - } - else if (format == Format.S8Uint) - { - return ClearBufferMask.StencilBufferBit; - } - else - { - return ClearBufferMask.ColorBufferBit; - } - } - - private static bool IsDepthOnly(Format format) - { - return format == Format.D16Unorm || format == Format.D32Float; - } - - public TextureView BgraSwap(TextureView from) - { - TextureView to = (TextureView)_renderer.CreateTexture(from.Info, from.ScaleFactor); - - EnsurePbo(from); - - GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyPboHandle); - - from.WriteToPbo(0, forceBgra: true); - - GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, _copyPboHandle); - - to.ReadFromPbo(0, _copyPboSize); - - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); - - return to; - } - - private TextureView PboCopy(TextureView from, TextureView to, int srcLayer, int dstLayer, int srcLevel, int dstLevel, int width, int height) - { - int dstWidth = width; - int dstHeight = height; - - // The size of the source texture. - int unpackWidth = from.Width; - int unpackHeight = from.Height; - - if (from.Info.IsCompressed != to.Info.IsCompressed) - { - if (from.Info.IsCompressed) - { - // Dest size is in pixels, but should be in blocks - dstWidth = BitUtils.DivRoundUp(width, from.Info.BlockWidth); - dstHeight = BitUtils.DivRoundUp(height, from.Info.BlockHeight); - - // When copying from a compressed texture, the source size must be taken in blocks for unpacking to the uncompressed block texture. - unpackWidth = BitUtils.DivRoundUp(from.Info.Width, from.Info.BlockWidth); - unpackHeight = BitUtils.DivRoundUp(from.Info.Height, from.Info.BlockHeight); - } - else - { - // When copying to a compressed texture, the source size must be scaled by the block width for unpacking on the compressed target. - unpackWidth = from.Info.Width * to.Info.BlockWidth; - unpackHeight = from.Info.Height * to.Info.BlockHeight; - } - } - - EnsurePbo(from); - - GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyPboHandle); - - // The source texture is written out in full, then the destination is taken as a slice from the data using unpack params. - // The offset points to the base at which the requested layer is at. - - int offset = from.WriteToPbo2D(0, srcLayer, srcLevel); - - // If the destination size is not an exact match for the source unpack parameters, we need to set them to slice the data correctly. - - bool slice = (unpackWidth != dstWidth || unpackHeight != dstHeight); - - if (slice) - { - // Set unpack parameters to take a slice of width/height: - GL.PixelStore(PixelStoreParameter.UnpackRowLength, unpackWidth); - GL.PixelStore(PixelStoreParameter.UnpackImageHeight, unpackHeight); - - if (to.Info.IsCompressed) - { - GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockWidth, to.Info.BlockWidth); - GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockHeight, to.Info.BlockHeight); - GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockDepth, 1); - GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockSize, to.Info.BytesPerPixel); - } - } - - GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, _copyPboHandle); - - to.ReadFromPbo2D(offset, dstLayer, dstLevel, dstWidth, dstHeight); - - if (slice) - { - // Reset unpack parameters - GL.PixelStore(PixelStoreParameter.UnpackRowLength, 0); - GL.PixelStore(PixelStoreParameter.UnpackImageHeight, 0); - - if (to.Info.IsCompressed) - { - GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockWidth, 0); - GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockHeight, 0); - GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockDepth, 0); - GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockSize, 0); - } - } - - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); - - return to; - } - - private void EnsurePbo(TextureView view) - { - int requiredSize = 0; - - for (int level = 0; level < view.Info.Levels; level++) - { - requiredSize += view.Info.GetMipSize(level); - } - - if (_copyPboSize < requiredSize && _copyPboHandle != 0) - { - GL.DeleteBuffer(_copyPboHandle); - - _copyPboHandle = 0; - } - - if (_copyPboHandle == 0) - { - _copyPboHandle = GL.GenBuffer(); - _copyPboSize = requiredSize; - - GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyPboHandle); - GL.BufferData(BufferTarget.PixelPackBuffer, requiredSize, IntPtr.Zero, BufferUsageHint.DynamicCopy); - } - } - - private int GetSrcFramebufferLazy() - { - if (_srcFramebuffer == 0) - { - _srcFramebuffer = GL.GenFramebuffer(); - } - - return _srcFramebuffer; - } - - private int GetDstFramebufferLazy() - { - if (_dstFramebuffer == 0) - { - _dstFramebuffer = GL.GenFramebuffer(); - } - - return _dstFramebuffer; - } - - public void Dispose() - { - if (_srcFramebuffer != 0) - { - GL.DeleteFramebuffer(_srcFramebuffer); - - _srcFramebuffer = 0; - } - - if (_dstFramebuffer != 0) - { - GL.DeleteFramebuffer(_dstFramebuffer); - - _dstFramebuffer = 0; - } - - if (_copyPboHandle != 0) - { - GL.DeleteBuffer(_copyPboHandle); - - _copyPboHandle = 0; - } - - IntermediatePool.Dispose(); - } - } -} diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureCopyIncompatible.cs b/Ryujinx.Graphics.OpenGL/Image/TextureCopyIncompatible.cs deleted file mode 100644 index c8fbfbc6..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/TextureCopyIncompatible.cs +++ /dev/null @@ -1,252 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.GAL; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Numerics; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - class TextureCopyIncompatible - { - private const string ComputeShaderShortening = @"#version 450 core - -layout (binding = 0, $SRC_FORMAT$) uniform uimage2D src; -layout (binding = 1, $DST_FORMAT$) uniform uimage2D dst; - -layout (local_size_x = 32, local_size_y = 32, local_size_z = 1) in; - -void main() -{ - uvec2 coords = gl_GlobalInvocationID.xy; - ivec2 imageSz = imageSize(src); - - if (int(coords.x) >= imageSz.x || int(coords.y) >= imageSz.y) - { - return; - } - - uint coordsShifted = coords.x << $RATIO_LOG2$; - - uvec2 dstCoords0 = uvec2(coordsShifted, coords.y); - uvec2 dstCoords1 = uvec2(coordsShifted + 1, coords.y); - uvec2 dstCoords2 = uvec2(coordsShifted + 2, coords.y); - uvec2 dstCoords3 = uvec2(coordsShifted + 3, coords.y); - - uvec4 rgba = imageLoad(src, ivec2(coords)); - - imageStore(dst, ivec2(dstCoords0), rgba.rrrr); - imageStore(dst, ivec2(dstCoords1), rgba.gggg); - imageStore(dst, ivec2(dstCoords2), rgba.bbbb); - imageStore(dst, ivec2(dstCoords3), rgba.aaaa); -}"; - - private const string ComputeShaderWidening = @"#version 450 core - -layout (binding = 0, $SRC_FORMAT$) uniform uimage2D src; -layout (binding = 1, $DST_FORMAT$) uniform uimage2D dst; - -layout (local_size_x = 32, local_size_y = 32, local_size_z = 1) in; - -void main() -{ - uvec2 coords = gl_GlobalInvocationID.xy; - ivec2 imageSz = imageSize(dst); - - if (int(coords.x) >= imageSz.x || int(coords.y) >= imageSz.y) - { - return; - } - - uvec2 srcCoords = uvec2(coords.x << $RATIO_LOG2$, coords.y); - - uint r = imageLoad(src, ivec2(srcCoords) + ivec2(0, 0)).r; - uint g = imageLoad(src, ivec2(srcCoords) + ivec2(1, 0)).r; - uint b = imageLoad(src, ivec2(srcCoords) + ivec2(2, 0)).r; - uint a = imageLoad(src, ivec2(srcCoords) + ivec2(3, 0)).r; - - imageStore(dst, ivec2(coords), uvec4(r, g, b, a)); -}"; - - private readonly OpenGLRenderer _renderer; - private readonly Dictionary<int, int> _shorteningProgramHandles; - private readonly Dictionary<int, int> _wideningProgramHandles; - - public TextureCopyIncompatible(OpenGLRenderer renderer) - { - _renderer = renderer; - _shorteningProgramHandles = new Dictionary<int, int>(); - _wideningProgramHandles = new Dictionary<int, int>(); - } - - public void CopyIncompatibleFormats(ITextureInfo src, ITextureInfo dst, int srcLayer, int dstLayer, int srcLevel, int dstLevel, int depth, int levels) - { - TextureCreateInfo srcInfo = src.Info; - TextureCreateInfo dstInfo = dst.Info; - - int srcBpp = src.Info.BytesPerPixel; - int dstBpp = dst.Info.BytesPerPixel; - - // Calculate ideal component size, given our constraints: - // - Component size must not exceed bytes per pixel of source and destination image formats. - // - Maximum component size is 4 (R32). - int componentSize = Math.Min(Math.Min(srcBpp, dstBpp), 4); - - int srcComponentsCount = srcBpp / componentSize; - int dstComponentsCount = dstBpp / componentSize; - - var srcFormat = GetFormat(componentSize, srcComponentsCount); - var dstFormat = GetFormat(componentSize, dstComponentsCount); - - GL.UseProgram(srcBpp < dstBpp - ? GetWideningShader(componentSize, srcComponentsCount, dstComponentsCount) - : GetShorteningShader(componentSize, srcComponentsCount, dstComponentsCount)); - - for (int l = 0; l < levels; l++) - { - int srcWidth = Math.Max(1, src.Info.Width >> l); - int srcHeight = Math.Max(1, src.Info.Height >> l); - - int dstWidth = Math.Max(1, dst.Info.Width >> l); - int dstHeight = Math.Max(1, dst.Info.Height >> l); - - int width = Math.Min(srcWidth, dstWidth); - int height = Math.Min(srcHeight, dstHeight); - - for (int z = 0; z < depth; z++) - { - GL.BindImageTexture(0, src.Handle, srcLevel + l, false, srcLayer + z, TextureAccess.ReadOnly, srcFormat); - GL.BindImageTexture(1, dst.Handle, dstLevel + l, false, dstLayer + z, TextureAccess.WriteOnly, dstFormat); - - GL.DispatchCompute((width + 31) / 32, (height + 31) / 32, 1); - } - } - - Pipeline pipeline = (Pipeline)_renderer.Pipeline; - - pipeline.RestoreProgram(); - pipeline.RestoreImages1And2(); - } - - private static SizedInternalFormat GetFormat(int componentSize, int componentsCount) - { - if (componentSize == 1) - { - return componentsCount switch - { - 1 => SizedInternalFormat.R8ui, - 2 => SizedInternalFormat.Rg8ui, - 4 => SizedInternalFormat.Rgba8ui, - _ => throw new ArgumentException($"Invalid components count {componentsCount}.") - }; - } - else if (componentSize == 2) - { - return componentsCount switch - { - 1 => SizedInternalFormat.R16ui, - 2 => SizedInternalFormat.Rg16ui, - 4 => SizedInternalFormat.Rgba16ui, - _ => throw new ArgumentException($"Invalid components count {componentsCount}.") - }; - } - else if (componentSize == 4) - { - return componentsCount switch - { - 1 => SizedInternalFormat.R32ui, - 2 => SizedInternalFormat.Rg32ui, - 4 => SizedInternalFormat.Rgba32ui, - _ => throw new ArgumentException($"Invalid components count {componentsCount}.") - }; - } - else - { - throw new ArgumentException($"Invalid component size {componentSize}."); - } - } - - private int GetShorteningShader(int componentSize, int srcComponentsCount, int dstComponentsCount) - { - return GetShader(ComputeShaderShortening, _shorteningProgramHandles, componentSize, srcComponentsCount, dstComponentsCount); - } - - private int GetWideningShader(int componentSize, int srcComponentsCount, int dstComponentsCount) - { - return GetShader(ComputeShaderWidening, _wideningProgramHandles, componentSize, srcComponentsCount, dstComponentsCount); - } - - private int GetShader( - string code, - Dictionary<int, int> programHandles, - int componentSize, - int srcComponentsCount, - int dstComponentsCount) - { - int componentSizeLog2 = BitOperations.Log2((uint)componentSize); - - int srcIndex = componentSizeLog2 + BitOperations.Log2((uint)srcComponentsCount) * 3; - int dstIndex = componentSizeLog2 + BitOperations.Log2((uint)dstComponentsCount) * 3; - - int key = srcIndex | (dstIndex << 8); - - if (!programHandles.TryGetValue(key, out int programHandle)) - { - int csHandle = GL.CreateShader(ShaderType.ComputeShader); - - string[] formatTable = new[] { "r8ui", "r16ui", "r32ui", "rg8ui", "rg16ui", "rg32ui", "rgba8ui", "rgba16ui", "rgba32ui" }; - - string srcFormat = formatTable[srcIndex]; - string dstFormat = formatTable[dstIndex]; - - int srcBpp = srcComponentsCount * componentSize; - int dstBpp = dstComponentsCount * componentSize; - - int ratio = srcBpp < dstBpp ? dstBpp / srcBpp : srcBpp / dstBpp; - int ratioLog2 = BitOperations.Log2((uint)ratio); - - GL.ShaderSource(csHandle, code - .Replace("$SRC_FORMAT$", srcFormat) - .Replace("$DST_FORMAT$", dstFormat) - .Replace("$RATIO_LOG2$", ratioLog2.ToString(CultureInfo.InvariantCulture))); - - GL.CompileShader(csHandle); - - programHandle = GL.CreateProgram(); - - GL.AttachShader(programHandle, csHandle); - GL.LinkProgram(programHandle); - GL.DetachShader(programHandle, csHandle); - GL.DeleteShader(csHandle); - - GL.GetProgram(programHandle, GetProgramParameterName.LinkStatus, out int status); - - if (status == 0) - { - throw new Exception(GL.GetProgramInfoLog(programHandle)); - } - - programHandles.Add(key, programHandle); - } - - return programHandle; - } - - public void Dispose() - { - foreach (int handle in _shorteningProgramHandles.Values) - { - GL.DeleteProgram(handle); - } - - _shorteningProgramHandles.Clear(); - - foreach (int handle in _wideningProgramHandles.Values) - { - GL.DeleteProgram(handle); - } - - _wideningProgramHandles.Clear(); - } - } -} diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureCopyMS.cs b/Ryujinx.Graphics.OpenGL/Image/TextureCopyMS.cs deleted file mode 100644 index 9963dc66..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/TextureCopyMS.cs +++ /dev/null @@ -1,276 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.GAL; -using System; -using System.Numerics; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - class TextureCopyMS - { - private const string ComputeShaderMSToNonMS = @"#version 450 core - -layout (binding = 0, $FORMAT$) uniform uimage2DMS imgIn; -layout (binding = 1, $FORMAT$) uniform uimage2D imgOut; - -layout (local_size_x = 32, local_size_y = 32, local_size_z = 1) in; - -void main() -{ - uvec2 coords = gl_GlobalInvocationID.xy; - ivec2 imageSz = imageSize(imgOut); - if (int(coords.x) >= imageSz.x || int(coords.y) >= imageSz.y) - { - return; - } - int inSamples = imageSamples(imgIn); - int samplesInXLog2 = 0; - int samplesInYLog2 = 0; - switch (inSamples) - { - case 2: - samplesInXLog2 = 1; - break; - case 4: - samplesInXLog2 = 1; - samplesInYLog2 = 1; - break; - case 8: - samplesInXLog2 = 2; - samplesInYLog2 = 1; - break; - case 16: - samplesInXLog2 = 2; - samplesInYLog2 = 2; - break; - } - int samplesInX = 1 << samplesInXLog2; - int samplesInY = 1 << samplesInYLog2; - int sampleIdx = (int(coords.x) & (samplesInX - 1)) | ((int(coords.y) & (samplesInY - 1)) << samplesInXLog2); - uvec4 value = imageLoad(imgIn, ivec2(int(coords.x) >> samplesInXLog2, int(coords.y) >> samplesInYLog2), sampleIdx); - imageStore(imgOut, ivec2(coords), value); -}"; - - private const string ComputeShaderNonMSToMS = @"#version 450 core - -layout (binding = 0, $FORMAT$) uniform uimage2D imgIn; -layout (binding = 1, $FORMAT$) uniform uimage2DMS imgOut; - -layout (local_size_x = 32, local_size_y = 32, local_size_z = 1) in; - -void main() -{ - uvec2 coords = gl_GlobalInvocationID.xy; - ivec2 imageSz = imageSize(imgIn); - if (int(coords.x) >= imageSz.x || int(coords.y) >= imageSz.y) - { - return; - } - int outSamples = imageSamples(imgOut); - int samplesInXLog2 = 0; - int samplesInYLog2 = 0; - switch (outSamples) - { - case 2: - samplesInXLog2 = 1; - break; - case 4: - samplesInXLog2 = 1; - samplesInYLog2 = 1; - break; - case 8: - samplesInXLog2 = 2; - samplesInYLog2 = 1; - break; - case 16: - samplesInXLog2 = 2; - samplesInYLog2 = 2; - break; - } - int samplesInX = 1 << samplesInXLog2; - int samplesInY = 1 << samplesInYLog2; - int sampleIdx = (int(coords.x) & (samplesInX - 1)) | ((int(coords.y) & (samplesInY - 1)) << samplesInXLog2); - uvec4 value = imageLoad(imgIn, ivec2(coords)); - imageStore(imgOut, ivec2(int(coords.x) >> samplesInXLog2, int(coords.y) >> samplesInYLog2), sampleIdx, value); -}"; - - private readonly OpenGLRenderer _renderer; - private int[] _msToNonMSProgramHandles; - private int[] _nonMSToMSProgramHandles; - - public TextureCopyMS(OpenGLRenderer renderer) - { - _renderer = renderer; - _msToNonMSProgramHandles = new int[5]; - _nonMSToMSProgramHandles = new int[5]; - } - - public void CopyMSToNonMS(ITextureInfo src, ITextureInfo dst, int srcLayer, int dstLayer, int depth) - { - TextureCreateInfo srcInfo = src.Info; - TextureCreateInfo dstInfo = dst.Info; - - int srcHandle = CreateViewIfNeeded(src); - int dstHandle = CreateViewIfNeeded(dst); - - int dstWidth = dstInfo.Width; - int dstHeight = dstInfo.Height; - - GL.UseProgram(GetMSToNonMSShader(srcInfo.BytesPerPixel)); - - for (int z = 0; z < depth; z++) - { - GL.BindImageTexture(0, srcHandle, 0, false, srcLayer + z, TextureAccess.ReadOnly, GetFormat(srcInfo.BytesPerPixel)); - GL.BindImageTexture(1, dstHandle, 0, false, dstLayer + z, TextureAccess.WriteOnly, GetFormat(dstInfo.BytesPerPixel)); - - GL.DispatchCompute((dstWidth + 31) / 32, (dstHeight + 31) / 32, 1); - } - - Pipeline pipeline = (Pipeline)_renderer.Pipeline; - - pipeline.RestoreProgram(); - pipeline.RestoreImages1And2(); - - DestroyViewIfNeeded(src, srcHandle); - DestroyViewIfNeeded(dst, dstHandle); - } - - public void CopyNonMSToMS(ITextureInfo src, ITextureInfo dst, int srcLayer, int dstLayer, int depth) - { - TextureCreateInfo srcInfo = src.Info; - TextureCreateInfo dstInfo = dst.Info; - - int srcHandle = CreateViewIfNeeded(src); - int dstHandle = CreateViewIfNeeded(dst); - - int srcWidth = srcInfo.Width; - int srcHeight = srcInfo.Height; - - GL.UseProgram(GetNonMSToMSShader(srcInfo.BytesPerPixel)); - - for (int z = 0; z < depth; z++) - { - GL.BindImageTexture(0, srcHandle, 0, false, srcLayer + z, TextureAccess.ReadOnly, GetFormat(srcInfo.BytesPerPixel)); - GL.BindImageTexture(1, dstHandle, 0, false, dstLayer + z, TextureAccess.WriteOnly, GetFormat(dstInfo.BytesPerPixel)); - - GL.DispatchCompute((srcWidth + 31) / 32, (srcHeight + 31) / 32, 1); - } - - Pipeline pipeline = (Pipeline)_renderer.Pipeline; - - pipeline.RestoreProgram(); - pipeline.RestoreImages1And2(); - - DestroyViewIfNeeded(src, srcHandle); - DestroyViewIfNeeded(dst, dstHandle); - } - - private static SizedInternalFormat GetFormat(int bytesPerPixel) - { - return bytesPerPixel switch - { - 1 => SizedInternalFormat.R8ui, - 2 => SizedInternalFormat.R16ui, - 4 => SizedInternalFormat.R32ui, - 8 => SizedInternalFormat.Rg32ui, - 16 => SizedInternalFormat.Rgba32ui, - _ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}.") - }; - } - - private static int CreateViewIfNeeded(ITextureInfo texture) - { - // Binding sRGB textures as images doesn't work on NVIDIA, - // we need to create and bind a RGBA view for it to work. - if (texture.Info.Format == Format.R8G8B8A8Srgb) - { - int handle = GL.GenTexture(); - - GL.TextureView( - handle, - texture.Info.Target.Convert(), - texture.Storage.Handle, - PixelInternalFormat.Rgba8, - texture.FirstLevel, - 1, - texture.FirstLayer, - texture.Info.GetLayers()); - - return handle; - } - - return texture.Handle; - } - - private static void DestroyViewIfNeeded(ITextureInfo info, int handle) - { - if (info.Handle != handle) - { - GL.DeleteTexture(handle); - } - } - - private int GetMSToNonMSShader(int bytesPerPixel) - { - return GetShader(ComputeShaderMSToNonMS, _msToNonMSProgramHandles, bytesPerPixel); - } - - private int GetNonMSToMSShader(int bytesPerPixel) - { - return GetShader(ComputeShaderNonMSToMS, _nonMSToMSProgramHandles, bytesPerPixel); - } - - private int GetShader(string code, int[] programHandles, int bytesPerPixel) - { - int index = BitOperations.Log2((uint)bytesPerPixel); - - if (programHandles[index] == 0) - { - int csHandle = GL.CreateShader(ShaderType.ComputeShader); - - string format = new[] { "r8ui", "r16ui", "r32ui", "rg32ui", "rgba32ui" }[index]; - - GL.ShaderSource(csHandle, code.Replace("$FORMAT$", format)); - GL.CompileShader(csHandle); - - int programHandle = GL.CreateProgram(); - - GL.AttachShader(programHandle, csHandle); - GL.LinkProgram(programHandle); - GL.DetachShader(programHandle, csHandle); - GL.DeleteShader(csHandle); - - GL.GetProgram(programHandle, GetProgramParameterName.LinkStatus, out int status); - - if (status == 0) - { - throw new Exception(GL.GetProgramInfoLog(programHandle)); - } - - programHandles[index] = programHandle; - } - - return programHandles[index]; - } - - public void Dispose() - { - for (int i = 0; i < _msToNonMSProgramHandles.Length; i++) - { - if (_msToNonMSProgramHandles[i] != 0) - { - GL.DeleteProgram(_msToNonMSProgramHandles[i]); - _msToNonMSProgramHandles[i] = 0; - } - } - - for (int i = 0; i < _nonMSToMSProgramHandles.Length; i++) - { - if (_nonMSToMSProgramHandles[i] != 0) - { - GL.DeleteProgram(_nonMSToMSProgramHandles[i]); - _nonMSToMSProgramHandles[i] = 0; - } - } - } - } -} diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs b/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs deleted file mode 100644 index c058ac88..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs +++ /dev/null @@ -1,212 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Common.Logging; -using Ryujinx.Graphics.GAL; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - class TextureStorage : ITextureInfo - { - public ITextureInfo Storage => this; - public int Handle { get; private set; } - public float ScaleFactor { get; private set; } - - public TextureCreateInfo Info { get; } - - private readonly OpenGLRenderer _renderer; - - private int _viewsCount; - - internal ITexture DefaultView { get; private set; } - - public TextureStorage(OpenGLRenderer renderer, TextureCreateInfo info, float scaleFactor) - { - _renderer = renderer; - Info = info; - - Handle = GL.GenTexture(); - ScaleFactor = scaleFactor; - - CreateImmutableStorage(); - } - - private void CreateImmutableStorage() - { - TextureTarget target = Info.Target.Convert(); - - GL.ActiveTexture(TextureUnit.Texture0); - - GL.BindTexture(target, Handle); - - FormatInfo format = FormatTable.GetFormatInfo(Info.Format); - - SizedInternalFormat internalFormat; - - if (format.IsCompressed) - { - internalFormat = (SizedInternalFormat)format.PixelFormat; - } - else - { - internalFormat = (SizedInternalFormat)format.PixelInternalFormat; - } - - int levels = Info.GetLevelsClamped(); - - switch (Info.Target) - { - case Target.Texture1D: - GL.TexStorage1D( - TextureTarget1d.Texture1D, - levels, - internalFormat, - Info.Width); - break; - - case Target.Texture1DArray: - GL.TexStorage2D( - TextureTarget2d.Texture1DArray, - levels, - internalFormat, - Info.Width, - Info.Height); - break; - - case Target.Texture2D: - GL.TexStorage2D( - TextureTarget2d.Texture2D, - levels, - internalFormat, - Info.Width, - Info.Height); - break; - - case Target.Texture2DArray: - GL.TexStorage3D( - TextureTarget3d.Texture2DArray, - levels, - internalFormat, - Info.Width, - Info.Height, - Info.Depth); - break; - - case Target.Texture2DMultisample: - GL.TexStorage2DMultisample( - TextureTargetMultisample2d.Texture2DMultisample, - Info.Samples, - internalFormat, - Info.Width, - Info.Height, - true); - break; - - case Target.Texture2DMultisampleArray: - GL.TexStorage3DMultisample( - TextureTargetMultisample3d.Texture2DMultisampleArray, - Info.Samples, - internalFormat, - Info.Width, - Info.Height, - Info.Depth, - true); - break; - - case Target.Texture3D: - GL.TexStorage3D( - TextureTarget3d.Texture3D, - levels, - internalFormat, - Info.Width, - Info.Height, - Info.Depth); - break; - - case Target.Cubemap: - GL.TexStorage2D( - TextureTarget2d.TextureCubeMap, - levels, - internalFormat, - Info.Width, - Info.Height); - break; - - case Target.CubemapArray: - GL.TexStorage3D( - (TextureTarget3d)All.TextureCubeMapArray, - levels, - internalFormat, - Info.Width, - Info.Height, - Info.Depth); - break; - - default: - Logger.Debug?.Print(LogClass.Gpu, $"Invalid or unsupported texture target: {target}."); - break; - } - } - - public ITexture CreateDefaultView() - { - DefaultView = CreateView(Info, 0, 0); - - return DefaultView; - } - - public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) - { - IncrementViewsCount(); - - return new TextureView(_renderer, this, info, firstLayer, firstLevel); - } - - private void IncrementViewsCount() - { - _viewsCount++; - } - - public void DecrementViewsCount() - { - // If we don't have any views, then the storage is now useless, delete it. - if (--_viewsCount == 0) - { - if (DefaultView == null) - { - Dispose(); - } - else - { - // If the default view still exists, we can put it into the resource pool. - Release(); - } - } - } - - /// <summary> - /// Release the TextureStorage to the resource pool without disposing its handle. - /// </summary> - public void Release() - { - _viewsCount = 1; // When we are used again, we will have the default view. - - _renderer.ResourcePool.AddTexture((TextureView)DefaultView); - } - - public void DeleteDefault() - { - DefaultView = null; - } - - public void Dispose() - { - DefaultView = null; - - if (Handle != 0) - { - GL.DeleteTexture(Handle); - - Handle = 0; - } - } - } -} diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs deleted file mode 100644 index 804b3b03..00000000 --- a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs +++ /dev/null @@ -1,867 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Common; -using Ryujinx.Common.Memory; -using Ryujinx.Graphics.GAL; -using System; - -namespace Ryujinx.Graphics.OpenGL.Image -{ - class TextureView : TextureBase, ITexture, ITextureInfo - { - private readonly OpenGLRenderer _renderer; - - private readonly TextureStorage _parent; - - public ITextureInfo Storage => _parent; - - public int FirstLayer { get; private set; } - public int FirstLevel { get; private set; } - - public TextureView( - OpenGLRenderer renderer, - TextureStorage parent, - TextureCreateInfo info, - int firstLayer, - int firstLevel) : base(info, parent.ScaleFactor) - { - _renderer = renderer; - _parent = parent; - - FirstLayer = firstLayer; - FirstLevel = firstLevel; - - CreateView(); - } - - private void CreateView() - { - TextureTarget target = Target.Convert(); - - FormatInfo format = FormatTable.GetFormatInfo(Info.Format); - - PixelInternalFormat pixelInternalFormat; - - if (format.IsCompressed) - { - pixelInternalFormat = (PixelInternalFormat)format.PixelFormat; - } - else - { - pixelInternalFormat = format.PixelInternalFormat; - } - - int levels = Info.GetLevelsClamped(); - - GL.TextureView( - Handle, - target, - _parent.Handle, - pixelInternalFormat, - FirstLevel, - levels, - FirstLayer, - Info.GetLayers()); - - GL.ActiveTexture(TextureUnit.Texture0); - - GL.BindTexture(target, Handle); - - int[] swizzleRgba = new int[] - { - (int)Info.SwizzleR.Convert(), - (int)Info.SwizzleG.Convert(), - (int)Info.SwizzleB.Convert(), - (int)Info.SwizzleA.Convert() - }; - - if (Info.Format == Format.A1B5G5R5Unorm) - { - int temp = swizzleRgba[0]; - int temp2 = swizzleRgba[1]; - swizzleRgba[0] = swizzleRgba[3]; - swizzleRgba[1] = swizzleRgba[2]; - swizzleRgba[2] = temp2; - swizzleRgba[3] = temp; - } - else if (Info.Format.IsBgr()) - { - // Swap B <-> R for BGRA formats, as OpenGL has no support for them - // and we need to manually swap the components on read/write on the GPU. - int temp = swizzleRgba[0]; - swizzleRgba[0] = swizzleRgba[2]; - swizzleRgba[2] = temp; - } - - GL.TexParameter(target, TextureParameterName.TextureSwizzleRgba, swizzleRgba); - - int maxLevel = levels - 1; - - if (maxLevel < 0) - { - maxLevel = 0; - } - - GL.TexParameter(target, TextureParameterName.TextureMaxLevel, maxLevel); - GL.TexParameter(target, TextureParameterName.DepthStencilTextureMode, (int)Info.DepthStencilMode.Convert()); - } - - public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) - { - firstLayer += FirstLayer; - firstLevel += FirstLevel; - - return _parent.CreateView(info, firstLayer, firstLevel); - } - - public void CopyTo(ITexture destination, int firstLayer, int firstLevel) - { - TextureView destinationView = (TextureView)destination; - - bool srcIsMultisample = Target.IsMultisample(); - bool dstIsMultisample = destinationView.Target.IsMultisample(); - - if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil()) - { - int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer); - CopyWithBlitForDepthMS(destinationView, 0, firstLayer, layers); - } - else if (!dstIsMultisample && srcIsMultisample) - { - int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer); - _renderer.TextureCopyMS.CopyMSToNonMS(this, destinationView, 0, firstLayer, layers); - } - else if (dstIsMultisample && !srcIsMultisample) - { - int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer); - _renderer.TextureCopyMS.CopyNonMSToMS(this, destinationView, 0, firstLayer, layers); - } - else if (destinationView.Info.BytesPerPixel != Info.BytesPerPixel) - { - int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer); - int levels = Math.Min(Info.Levels, destinationView.Info.Levels - firstLevel); - _renderer.TextureCopyIncompatible.CopyIncompatibleFormats(this, destinationView, 0, firstLayer, 0, firstLevel, layers, levels); - } - else - { - _renderer.TextureCopy.CopyUnscaled(this, destinationView, 0, firstLayer, 0, firstLevel); - } - } - - public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel) - { - TextureView destinationView = (TextureView)destination; - - bool srcIsMultisample = Target.IsMultisample(); - bool dstIsMultisample = destinationView.Target.IsMultisample(); - - if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil()) - { - CopyWithBlitForDepthMS(destinationView, srcLayer, dstLayer, 1); - } - else if (!dstIsMultisample && srcIsMultisample) - { - _renderer.TextureCopyMS.CopyMSToNonMS(this, destinationView, srcLayer, dstLayer, 1); - } - else if (dstIsMultisample && !srcIsMultisample) - { - _renderer.TextureCopyMS.CopyNonMSToMS(this, destinationView, srcLayer, dstLayer, 1); - } - else if (destinationView.Info.BytesPerPixel != Info.BytesPerPixel) - { - _renderer.TextureCopyIncompatible.CopyIncompatibleFormats(this, destinationView, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); - } - else - { - _renderer.TextureCopy.CopyUnscaled(this, destinationView, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); - } - } - - private void CopyWithBlitForDepthMS(TextureView destinationView, int srcLayer, int dstLayer, int layers) - { - // This is currently used for multisample <-> non-multisample copies. - // We can't do that with compute because it's not possible to write depth textures on compute. - // It can be done with draws, but we don't have support for saving and restoring the OpenGL state - // for a draw with different state right now. - // This approach uses blit, which causes a resolution loss since some samples will be lost - // in the process. - - Extents2D srcRegion = new Extents2D(0, 0, Width, Height); - Extents2D dstRegion = new Extents2D(0, 0, destinationView.Width, destinationView.Height); - - if (destinationView.Target.IsMultisample()) - { - TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast( - Info.Target, - Info.BlockWidth, - Info.BlockHeight, - Info.BytesPerPixel, - Format, - destinationView.Width, - destinationView.Height, - Info.Depth, - 1, - 1); - - _renderer.TextureCopy.Copy(this, intermmediate, srcRegion, dstRegion, false); - _renderer.TextureCopy.Copy(intermmediate, destinationView, dstRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1); - } - else - { - Target target = Target switch - { - Target.Texture2DMultisample => Target.Texture2D, - Target.Texture2DMultisampleArray => Target.Texture2DArray, - _ => Target - }; - - TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast( - target, - Info.BlockWidth, - Info.BlockHeight, - Info.BytesPerPixel, - Format, - Width, - Height, - Info.Depth, - 1, - 1); - - _renderer.TextureCopy.Copy(this, intermmediate, srcRegion, srcRegion, false); - _renderer.TextureCopy.Copy(intermmediate, destinationView, srcRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1); - } - } - - public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter) - { - _renderer.TextureCopy.Copy(this, (TextureView)destination, srcRegion, dstRegion, linearFilter); - } - - public unsafe PinnedSpan<byte> GetData() - { - int size = 0; - int levels = Info.GetLevelsClamped(); - - for (int level = 0; level < levels; level++) - { - size += Info.GetMipSize(level); - } - - ReadOnlySpan<byte> data; - - if (HwCapabilities.UsePersistentBufferForFlush) - { - data = _renderer.PersistentBuffers.Default.GetTextureData(this, size); - } - else - { - IntPtr target = _renderer.PersistentBuffers.Default.GetHostArray(size); - - WriteTo(target); - - data = new ReadOnlySpan<byte>(target.ToPointer(), size); - } - - if (Format == Format.S8UintD24Unorm) - { - data = FormatConverter.ConvertD24S8ToS8D24(data); - } - - return PinnedSpan<byte>.UnsafeFromSpan(data); - } - - public unsafe PinnedSpan<byte> GetData(int layer, int level) - { - int size = Info.GetMipSize(level); - - if (HwCapabilities.UsePersistentBufferForFlush) - { - return PinnedSpan<byte>.UnsafeFromSpan(_renderer.PersistentBuffers.Default.GetTextureData(this, size, layer, level)); - } - else - { - IntPtr target = _renderer.PersistentBuffers.Default.GetHostArray(size); - - int offset = WriteTo2D(target, layer, level); - - return new PinnedSpan<byte>((byte*)target.ToPointer() + offset, size); - } - } - - public void WriteToPbo(int offset, bool forceBgra) - { - WriteTo(IntPtr.Zero + offset, forceBgra); - } - - public int WriteToPbo2D(int offset, int layer, int level) - { - return WriteTo2D(IntPtr.Zero + offset, layer, level); - } - - private int WriteTo2D(IntPtr data, int layer, int level) - { - TextureTarget target = Target.Convert(); - - Bind(target, 0); - - FormatInfo format = FormatTable.GetFormatInfo(Info.Format); - - PixelFormat pixelFormat = format.PixelFormat; - PixelType pixelType = format.PixelType; - - if (target == TextureTarget.TextureCubeMap || target == TextureTarget.TextureCubeMapArray) - { - target = TextureTarget.TextureCubeMapPositiveX + (layer % 6); - } - - int mipSize = Info.GetMipSize2D(level); - - if (format.IsCompressed) - { - GL.GetCompressedTextureSubImage(Handle, level, 0, 0, layer, Math.Max(1, Info.Width >> level), Math.Max(1, Info.Height >> level), 1, mipSize, data); - } - else if (format.PixelFormat != PixelFormat.DepthStencil) - { - GL.GetTextureSubImage(Handle, level, 0, 0, layer, Math.Max(1, Info.Width >> level), Math.Max(1, Info.Height >> level), 1, pixelFormat, pixelType, mipSize, data); - } - else - { - GL.GetTexImage(target, level, pixelFormat, pixelType, data); - - // The GL function returns all layers. Must return the offset of the layer we're interested in. - return target switch - { - TextureTarget.TextureCubeMapArray => (layer / 6) * mipSize, - TextureTarget.Texture1DArray => layer * mipSize, - TextureTarget.Texture2DArray => layer * mipSize, - _ => 0 - }; - } - - return 0; - } - - private void WriteTo(IntPtr data, bool forceBgra = false) - { - TextureTarget target = Target.Convert(); - - Bind(target, 0); - - FormatInfo format = FormatTable.GetFormatInfo(Info.Format); - - PixelFormat pixelFormat = format.PixelFormat; - PixelType pixelType = format.PixelType; - - if (forceBgra) - { - if (pixelType == PixelType.UnsignedShort565) - { - pixelType = PixelType.UnsignedShort565Reversed; - } - else if (pixelType == PixelType.UnsignedShort565Reversed) - { - pixelType = PixelType.UnsignedShort565; - } - else - { - pixelFormat = PixelFormat.Bgra; - } - } - - int faces = 1; - - if (target == TextureTarget.TextureCubeMap) - { - target = TextureTarget.TextureCubeMapPositiveX; - - faces = 6; - } - - int levels = Info.GetLevelsClamped(); - - for (int level = 0; level < levels; level++) - { - for (int face = 0; face < faces; face++) - { - int faceOffset = face * Info.GetMipSize2D(level); - - if (format.IsCompressed) - { - GL.GetCompressedTexImage(target + face, level, data + faceOffset); - } - else - { - GL.GetTexImage(target + face, level, pixelFormat, pixelType, data + faceOffset); - } - } - - data += Info.GetMipSize(level); - } - } - - public void SetData(SpanOrArray<byte> data) - { - var dataSpan = data.AsSpan(); - - if (Format == Format.S8UintD24Unorm) - { - dataSpan = FormatConverter.ConvertS8D24ToD24S8(dataSpan); - } - - unsafe - { - fixed (byte* ptr = dataSpan) - { - ReadFrom((IntPtr)ptr, dataSpan.Length); - } - } - } - - public void SetData(SpanOrArray<byte> data, int layer, int level) - { - var dataSpan = data.AsSpan(); - - if (Format == Format.S8UintD24Unorm) - { - dataSpan = FormatConverter.ConvertS8D24ToD24S8(dataSpan); - } - - unsafe - { - fixed (byte* ptr = dataSpan) - { - int width = Math.Max(Info.Width >> level, 1); - int height = Math.Max(Info.Height >> level, 1); - - ReadFrom2D((IntPtr)ptr, layer, level, 0, 0, width, height); - } - } - } - - public void SetData(SpanOrArray<byte> data, int layer, int level, Rectangle<int> region) - { - var dataSpan = data.AsSpan(); - - if (Format == Format.S8UintD24Unorm) - { - dataSpan = FormatConverter.ConvertS8D24ToD24S8(dataSpan); - } - - int wInBlocks = BitUtils.DivRoundUp(region.Width, Info.BlockWidth); - int hInBlocks = BitUtils.DivRoundUp(region.Height, Info.BlockHeight); - - unsafe - { - fixed (byte* ptr = dataSpan) - { - ReadFrom2D( - (IntPtr)ptr, - layer, - level, - region.X, - region.Y, - region.Width, - region.Height, - BitUtils.AlignUp(wInBlocks * Info.BytesPerPixel, 4) * hInBlocks); - } - } - } - - public void ReadFromPbo(int offset, int size) - { - ReadFrom(IntPtr.Zero + offset, size); - } - - public void ReadFromPbo2D(int offset, int layer, int level, int width, int height) - { - ReadFrom2D(IntPtr.Zero + offset, layer, level, 0, 0, width, height); - } - - private void ReadFrom2D(IntPtr data, int layer, int level, int x, int y, int width, int height) - { - int mipSize = Info.GetMipSize2D(level); - - ReadFrom2D(data, layer, level, x, y, width, height, mipSize); - } - - private void ReadFrom2D(IntPtr data, int layer, int level, int x, int y, int width, int height, int mipSize) - { - TextureTarget target = Target.Convert(); - - Bind(target, 0); - - FormatInfo format = FormatTable.GetFormatInfo(Info.Format); - - switch (Target) - { - case Target.Texture1D: - if (format.IsCompressed) - { - GL.CompressedTexSubImage1D( - target, - level, - x, - width, - format.PixelFormat, - mipSize, - data); - } - else - { - GL.TexSubImage1D( - target, - level, - x, - width, - format.PixelFormat, - format.PixelType, - data); - } - break; - - case Target.Texture1DArray: - if (format.IsCompressed) - { - GL.CompressedTexSubImage2D( - target, - level, - x, - layer, - width, - 1, - format.PixelFormat, - mipSize, - data); - } - else - { - GL.TexSubImage2D( - target, - level, - x, - layer, - width, - 1, - format.PixelFormat, - format.PixelType, - data); - } - break; - - case Target.Texture2D: - if (format.IsCompressed) - { - GL.CompressedTexSubImage2D( - target, - level, - x, - y, - width, - height, - format.PixelFormat, - mipSize, - data); - } - else - { - GL.TexSubImage2D( - target, - level, - x, - y, - width, - height, - format.PixelFormat, - format.PixelType, - data); - } - break; - - case Target.Texture2DArray: - case Target.Texture3D: - case Target.CubemapArray: - if (format.IsCompressed) - { - GL.CompressedTexSubImage3D( - target, - level, - x, - y, - layer, - width, - height, - 1, - format.PixelFormat, - mipSize, - data); - } - else - { - GL.TexSubImage3D( - target, - level, - x, - y, - layer, - width, - height, - 1, - format.PixelFormat, - format.PixelType, - data); - } - break; - - case Target.Cubemap: - if (format.IsCompressed) - { - GL.CompressedTexSubImage2D( - TextureTarget.TextureCubeMapPositiveX + layer, - level, - x, - y, - width, - height, - format.PixelFormat, - mipSize, - data); - } - else - { - GL.TexSubImage2D( - TextureTarget.TextureCubeMapPositiveX + layer, - level, - x, - y, - width, - height, - format.PixelFormat, - format.PixelType, - data); - } - break; - } - } - - private void ReadFrom(IntPtr data, int size) - { - TextureTarget target = Target.Convert(); - int baseLevel = 0; - - // glTexSubImage on cubemap views is broken on Intel, we have to use the storage instead. - if (Target == Target.Cubemap && HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows) - { - GL.ActiveTexture(TextureUnit.Texture0); - GL.BindTexture(target, Storage.Handle); - baseLevel = FirstLevel; - } - else - { - Bind(target, 0); - } - - FormatInfo format = FormatTable.GetFormatInfo(Info.Format); - - int width = Info.Width; - int height = Info.Height; - int depth = Info.Depth; - int levels = Info.GetLevelsClamped(); - - int offset = 0; - - for (int level = 0; level < levels; level++) - { - int mipSize = Info.GetMipSize(level); - - int endOffset = offset + mipSize; - - if ((uint)endOffset > (uint)size) - { - return; - } - - switch (Target) - { - case Target.Texture1D: - if (format.IsCompressed) - { - GL.CompressedTexSubImage1D( - target, - level, - 0, - width, - format.PixelFormat, - mipSize, - data); - } - else - { - GL.TexSubImage1D( - target, - level, - 0, - width, - format.PixelFormat, - format.PixelType, - data); - } - break; - - case Target.Texture1DArray: - case Target.Texture2D: - if (format.IsCompressed) - { - GL.CompressedTexSubImage2D( - target, - level, - 0, - 0, - width, - height, - format.PixelFormat, - mipSize, - data); - } - else - { - GL.TexSubImage2D( - target, - level, - 0, - 0, - width, - height, - format.PixelFormat, - format.PixelType, - data); - } - break; - - case Target.Texture2DArray: - case Target.Texture3D: - case Target.CubemapArray: - if (format.IsCompressed) - { - GL.CompressedTexSubImage3D( - target, - level, - 0, - 0, - 0, - width, - height, - depth, - format.PixelFormat, - mipSize, - data); - } - else - { - GL.TexSubImage3D( - target, - level, - 0, - 0, - 0, - width, - height, - depth, - format.PixelFormat, - format.PixelType, - data); - } - break; - - case Target.Cubemap: - int faceOffset = 0; - - for (int face = 0; face < 6; face++, faceOffset += mipSize / 6) - { - if (format.IsCompressed) - { - GL.CompressedTexSubImage2D( - TextureTarget.TextureCubeMapPositiveX + face, - baseLevel + level, - 0, - 0, - width, - height, - format.PixelFormat, - mipSize / 6, - data + faceOffset); - } - else - { - GL.TexSubImage2D( - TextureTarget.TextureCubeMapPositiveX + face, - baseLevel + level, - 0, - 0, - width, - height, - format.PixelFormat, - format.PixelType, - data + faceOffset); - } - } - break; - } - - data += mipSize; - offset += mipSize; - - width = Math.Max(1, width >> 1); - height = Math.Max(1, height >> 1); - - if (Target == Target.Texture3D) - { - depth = Math.Max(1, depth >> 1); - } - } - } - - public void SetStorage(BufferRange buffer) - { - throw new NotSupportedException(); - } - - private void DisposeHandles() - { - if (Handle != 0) - { - GL.DeleteTexture(Handle); - - Handle = 0; - } - } - - /// <summary> - /// Release the view without necessarily disposing the parent if we are the default view. - /// This allows it to be added to the resource pool and reused later. - /// </summary> - public void Release() - { - bool hadHandle = Handle != 0; - - if (_parent.DefaultView != this) - { - DisposeHandles(); - } - - if (hadHandle) - { - _parent.DecrementViewsCount(); - } - } - - public void Dispose() - { - if (_parent.DefaultView == this) - { - // Remove the default view (us), so that the texture cannot be released to the cache. - _parent.DeleteDefault(); - } - - Release(); - } - } -} |
