diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2020-04-25 10:02:18 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-25 23:02:18 +1000 |
| commit | 3cb1fa0e853efc04cc183d3ee75ec1bbe2c845a4 (patch) | |
| tree | cf19d371b99cffdbff03e2f20271927cb7b08bf8 /Ryujinx.Graphics.OpenGL | |
| parent | a065dc1626d2fa4cb5c7300a1aa8713ffb4f5896 (diff) | |
Implement texture buffers (#1152)
* Implement texture buffers
* Throw NotSupportedException where appropriate
Diffstat (limited to 'Ryujinx.Graphics.OpenGL')
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Pipeline.cs | 12 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Renderer.cs | 7 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/TextureBase.cs | 39 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/TextureBuffer.cs | 71 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/TextureView.cs | 86 |
5 files changed, 150 insertions, 65 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs index eec2b643..e313595d 100644 --- a/Ryujinx.Graphics.OpenGL/Pipeline.cs +++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -26,7 +26,7 @@ namespace Ryujinx.Graphics.OpenGL private bool _depthTest; private bool _hasDepthBuffer; - private TextureView _unit0Texture; + private TextureBase _unit0Texture; private ClipOrigin _clipOrigin; private ClipDepthMode _clipDepthMode; @@ -616,13 +616,13 @@ namespace Ryujinx.Graphics.OpenGL if (unit != -1 && texture != null) { - TextureView view = (TextureView)texture; + TextureBase texBase = (TextureBase)texture; - FormatInfo formatInfo = FormatTable.GetFormatInfo(view.Format); + FormatInfo formatInfo = FormatTable.GetFormatInfo(texBase.Format); SizedInternalFormat format = (SizedInternalFormat)formatInfo.PixelInternalFormat; - GL.BindImageTexture(unit, view.Handle, 0, true, 0, TextureAccess.ReadWrite, format); + GL.BindImageTexture(unit, texBase.Handle, 0, true, 0, TextureAccess.ReadWrite, format); } } @@ -801,11 +801,11 @@ namespace Ryujinx.Graphics.OpenGL { if (unit == 0) { - _unit0Texture = ((TextureView)texture); + _unit0Texture = (TextureBase)texture; } else { - ((TextureView)texture).Bind(unit); + ((TextureBase)texture).Bind(unit); } } } diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs index 504a947b..3f718345 100644 --- a/Ryujinx.Graphics.OpenGL/Renderer.cs +++ b/Ryujinx.Graphics.OpenGL/Renderer.cs @@ -20,19 +20,14 @@ namespace Ryujinx.Graphics.OpenGL internal TextureCopy TextureCopy { get; } public string GpuVendor { get; private set; } - public string GpuRenderer { get; private set; } - public string GpuVersion { get; private set; } public Renderer() { _pipeline = new Pipeline(); - _counters = new Counters(); - _window = new Window(this); - TextureCopy = new TextureCopy(this); } @@ -58,7 +53,7 @@ namespace Ryujinx.Graphics.OpenGL public ITexture CreateTexture(TextureCreateInfo info) { - return new TextureStorage(this, info).CreateDefaultView(); + return info.Target == Target.TextureBuffer ? new TextureBuffer(info) : new TextureStorage(this, info).CreateDefaultView(); } public Capabilities GetCapabilities() diff --git a/Ryujinx.Graphics.OpenGL/TextureBase.cs b/Ryujinx.Graphics.OpenGL/TextureBase.cs new file mode 100644 index 00000000..f4ab0bda --- /dev/null +++ b/Ryujinx.Graphics.OpenGL/TextureBase.cs @@ -0,0 +1,39 @@ +using OpenTK.Graphics.OpenGL; +using Ryujinx.Graphics.GAL; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ryujinx.Graphics.OpenGL +{ + class TextureBase + { + public int Handle { get; protected set; } + + protected TextureCreateInfo Info { get; } + + public int Width => Info.Width; + public int Height => Info.Height; + + public Target Target => Info.Target; + public Format Format => Info.Format; + + public TextureBase(TextureCreateInfo info) + { + Info = info; + + 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); + } + } +} diff --git a/Ryujinx.Graphics.OpenGL/TextureBuffer.cs b/Ryujinx.Graphics.OpenGL/TextureBuffer.cs new file mode 100644 index 00000000..fb18c6ee --- /dev/null +++ b/Ryujinx.Graphics.OpenGL/TextureBuffer.cs @@ -0,0 +1,71 @@ +using OpenTK.Graphics.OpenGL; +using Ryujinx.Graphics.GAL; +using System; + +namespace Ryujinx.Graphics.OpenGL +{ + class TextureBuffer : TextureBase, ITexture + { + private int _bufferOffset; + private int _bufferSize; + + private Buffer _buffer; + + public TextureBuffer(TextureCreateInfo info) : base(info) {} + + public void CopyTo(ITexture destination, int firstLayer, int firstLevel) + { + 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 byte[] GetData() + { + return _buffer?.GetData(_bufferOffset, _bufferSize); + } + + public void SetData(ReadOnlySpan<byte> data) + { + _buffer?.SetData(_bufferOffset, data.Slice(0, Math.Min(data.Length, _bufferSize))); + } + + public void SetStorage(BufferRange buffer) + { + if (buffer.Buffer == _buffer && + buffer.Offset == _bufferOffset && + buffer.Size == _bufferSize) + { + return; + } + + _buffer = (Buffer)buffer.Buffer; + _bufferOffset = buffer.Offset; + _bufferSize = buffer.Size; + + Bind(0); + + SizedInternalFormat format = (SizedInternalFormat)FormatTable.GetFormatInfo(Info.Format).PixelInternalFormat; + + GL.TexBufferRange(TextureBufferTarget.TextureBuffer, format, _buffer.Handle, (IntPtr)buffer.Offset, buffer.Size); + } + + public void Dispose() + { + if (Handle != 0) + { + GL.DeleteTexture(Handle); + + Handle = 0; + } + } + } +} diff --git a/Ryujinx.Graphics.OpenGL/TextureView.cs b/Ryujinx.Graphics.OpenGL/TextureView.cs index cb872880..0ab59d42 100644 --- a/Ryujinx.Graphics.OpenGL/TextureView.cs +++ b/Ryujinx.Graphics.OpenGL/TextureView.cs @@ -4,10 +4,8 @@ using System; namespace Ryujinx.Graphics.OpenGL { - class TextureView : ITexture + class TextureView : TextureBase, ITexture { - public int Handle { get; private set; } - private readonly Renderer _renderer; private readonly TextureStorage _parent; @@ -16,33 +14,22 @@ namespace Ryujinx.Graphics.OpenGL private TextureView _incompatibleFormatView; - private readonly TextureCreateInfo _info; - public int FirstLayer { get; private set; } public int FirstLevel { get; private set; } - public int Width => _info.Width; - public int Height => _info.Height; - - public Target Target => _info.Target; - public Format Format => _info.Format; - public TextureView( Renderer renderer, TextureStorage parent, TextureCreateInfo info, int firstLayer, - int firstLevel) + int firstLevel) : base(info) { _renderer = renderer; _parent = parent; - _info = info; FirstLayer = firstLayer; FirstLevel = firstLevel; - Handle = GL.GenTexture(); - CreateView(); } @@ -50,7 +37,7 @@ namespace Ryujinx.Graphics.OpenGL { TextureTarget target = Target.Convert(); - FormatInfo format = FormatTable.GetFormatInfo(_info.Format); + FormatInfo format = FormatTable.GetFormatInfo(Info.Format); PixelInternalFormat pixelInternalFormat; @@ -69,9 +56,9 @@ namespace Ryujinx.Graphics.OpenGL _parent.Handle, pixelInternalFormat, FirstLevel, - _info.Levels, + Info.Levels, FirstLayer, - _info.GetLayers()); + Info.GetLayers()); GL.ActiveTexture(TextureUnit.Texture0); @@ -79,15 +66,15 @@ namespace Ryujinx.Graphics.OpenGL int[] swizzleRgba = new int[] { - (int)_info.SwizzleR.Convert(), - (int)_info.SwizzleG.Convert(), - (int)_info.SwizzleB.Convert(), - (int)_info.SwizzleA.Convert() + (int)Info.SwizzleR.Convert(), + (int)Info.SwizzleG.Convert(), + (int)Info.SwizzleB.Convert(), + (int)Info.SwizzleA.Convert() }; GL.TexParameter(target, TextureParameterName.TextureSwizzleRgba, swizzleRgba); - int maxLevel = _info.Levels - 1; + int maxLevel = Info.Levels - 1; if (maxLevel < 0) { @@ -95,12 +82,12 @@ namespace Ryujinx.Graphics.OpenGL } GL.TexParameter(target, TextureParameterName.TextureMaxLevel, maxLevel); - GL.TexParameter(target, TextureParameterName.DepthStencilTextureMode, (int)_info.DepthStencilMode.Convert()); + GL.TexParameter(target, TextureParameterName.DepthStencilTextureMode, (int)Info.DepthStencilMode.Convert()); } public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) { - if (_info.IsCompressed == info.IsCompressed) + if (Info.IsCompressed == info.IsCompressed) { firstLayer += FirstLayer; firstLevel += FirstLevel; @@ -135,10 +122,10 @@ namespace Ryujinx.Graphics.OpenGL { if (_incompatibleFormatView == null) { - _incompatibleFormatView = (TextureView)_renderer.CreateTexture(_info); + _incompatibleFormatView = (TextureView)_renderer.CreateTexture(Info); } - TextureCopyUnscaled.Copy(_parent.Info, _incompatibleFormatView._info, _parent.Handle, _incompatibleFormatView.Handle, FirstLayer, 0, FirstLevel, 0); + TextureCopyUnscaled.Copy(_parent.Info, _incompatibleFormatView.Info, _parent.Handle, _incompatibleFormatView.Handle, FirstLayer, 0, FirstLevel, 0); return _incompatibleFormatView.Handle; } @@ -150,7 +137,7 @@ namespace Ryujinx.Graphics.OpenGL { if (_incompatibleFormatView != null) { - TextureCopyUnscaled.Copy(_incompatibleFormatView._info, _parent.Info, _incompatibleFormatView.Handle, _parent.Handle, 0, FirstLayer, 0, FirstLevel); + TextureCopyUnscaled.Copy(_incompatibleFormatView.Info, _parent.Info, _incompatibleFormatView.Handle, _parent.Handle, 0, FirstLayer, 0, FirstLevel); } } @@ -158,13 +145,13 @@ namespace Ryujinx.Graphics.OpenGL { TextureView destinationView = (TextureView)destination; - TextureCopyUnscaled.Copy(_info, destinationView._info, Handle, destinationView.Handle, 0, firstLayer, 0, firstLevel); + TextureCopyUnscaled.Copy(Info, destinationView.Info, Handle, destinationView.Handle, 0, firstLayer, 0, firstLevel); if (destinationView._emulatedViewParent != null) { TextureCopyUnscaled.Copy( - _info, - destinationView._emulatedViewParent._info, + Info, + destinationView._emulatedViewParent.Info, Handle, destinationView._emulatedViewParent.Handle, 0, @@ -183,9 +170,9 @@ namespace Ryujinx.Graphics.OpenGL { int size = 0; - for (int level = 0; level < _info.Levels; level++) + for (int level = 0; level < Info.Levels; level++) { - size += _info.GetMipSize(level); + size += Info.GetMipSize(level); } byte[] data = new byte[size]; @@ -207,7 +194,7 @@ namespace Ryujinx.Graphics.OpenGL Bind(target, 0); - FormatInfo format = FormatTable.GetFormatInfo(_info.Format); + FormatInfo format = FormatTable.GetFormatInfo(Info.Format); int faces = 1; @@ -218,11 +205,11 @@ namespace Ryujinx.Graphics.OpenGL faces = 6; } - for (int level = 0; level < _info.Levels; level++) + for (int level = 0; level < Info.Levels; level++) { for (int face = 0; face < faces; face++) { - int faceOffset = face * _info.GetMipSize2D(level); + int faceOffset = face * Info.GetMipSize2D(level); if (format.IsCompressed) { @@ -239,7 +226,7 @@ namespace Ryujinx.Graphics.OpenGL } } - ptr += _info.GetMipSize(level); + ptr += Info.GetMipSize(level); } } @@ -260,17 +247,17 @@ namespace Ryujinx.Graphics.OpenGL Bind(target, 0); - FormatInfo format = FormatTable.GetFormatInfo(_info.Format); + FormatInfo format = FormatTable.GetFormatInfo(Info.Format); - int width = _info.Width; - int height = _info.Height; - int depth = _info.Depth; + int width = Info.Width; + int height = Info.Height; + int depth = Info.Depth; int offset = 0; - for (int level = 0; level < _info.Levels; level++) + for (int level = 0; level < Info.Levels; level++) { - int mipSize = _info.GetMipSize(level); + int mipSize = Info.GetMipSize(level); int endOffset = offset + mipSize; @@ -279,7 +266,7 @@ namespace Ryujinx.Graphics.OpenGL return; } - switch (_info.Target) + switch (Info.Target) { case Target.Texture1D: if (format.IsCompressed) @@ -419,16 +406,9 @@ namespace Ryujinx.Graphics.OpenGL } } - public void Bind(int unit) + public void SetStorage(BufferRange buffer) { - Bind(Target.Convert(), unit); - } - - private void Bind(TextureTarget target, int unit) - { - GL.ActiveTexture(TextureUnit.Texture0 + unit); - - GL.BindTexture(target, Handle); + throw new NotSupportedException(); } public void Dispose() |
