aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/Image/TextureView.cs
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.Graphics.OpenGL/Image/TextureView.cs
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Image/TextureView.cs')
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/TextureView.cs867
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();
- }
- }
-}