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/TextureView.cs | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Image/TextureView.cs')
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureView.cs | 867 |
1 files changed, 0 insertions, 867 deletions
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(); - } - } -} |
