aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/Image
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
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Image')
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/FormatConverter.cs149
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/ITextureInfo.cs14
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/IntermmediatePool.cs103
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/Sampler.cs64
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/TextureBase.cs44
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs108
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs524
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/TextureCopyIncompatible.cs252
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/TextureCopyMS.cs276
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs212
-rw-r--r--Ryujinx.Graphics.OpenGL/Image/TextureView.cs867
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();
- }
- }
-}