diff options
Diffstat (limited to 'Ryujinx.Graphics.OpenGL')
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs | 5 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureView.cs | 44 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/PersistentBuffers.cs | 15 |
3 files changed, 53 insertions, 11 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs b/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs index 899deedf..dc9bf6af 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs @@ -43,6 +43,11 @@ namespace Ryujinx.Graphics.OpenGL.Image return Buffer.GetData(_renderer, _buffer, _bufferOffset, _bufferSize); } + public ReadOnlySpan<byte> GetData(int layer, int level) + { + return GetData(); + } + public void SetData(ReadOnlySpan<byte> data) { Buffer.SetData(_buffer, _bufferOffset, data.Slice(0, Math.Min(data.Length, _bufferSize))); diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs index 40ab18ef..f03653c4 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs @@ -154,6 +154,24 @@ namespace Ryujinx.Graphics.OpenGL.Image } } + public unsafe ReadOnlySpan<byte> GetData(int layer, int level) + { + int size = Info.GetMipSize(level); + + if (HwCapabilities.UsePersistentBufferForFlush) + { + return _renderer.PersistentBuffers.Default.GetTextureData(this, size, layer, level); + } + else + { + IntPtr target = _renderer.PersistentBuffers.Default.GetHostArray(size); + + int offset = WriteTo2D(target, layer, level); + + return new ReadOnlySpan<byte>(target.ToPointer(), size).Slice(offset); + } + } + public void WriteToPbo(int offset, bool forceBgra) { WriteTo(IntPtr.Zero + offset, forceBgra); @@ -182,25 +200,29 @@ namespace Ryujinx.Graphics.OpenGL.Image int mipSize = Info.GetMipSize2D(level); - // The GL function returns all layers. Must return the offset of the layer we're interested in. - int resultOffset = target switch - { - TextureTarget.TextureCubeMapArray => (layer / 6) * mipSize, - TextureTarget.Texture1DArray => layer * mipSize, - TextureTarget.Texture2DArray => layer * mipSize, - _ => 0 - }; - if (format.IsCompressed) { - GL.GetCompressedTexImage(target, level, data); + 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 resultOffset; + return 0; } private void WriteTo(IntPtr data, bool forceBgra = false) diff --git a/Ryujinx.Graphics.OpenGL/PersistentBuffers.cs b/Ryujinx.Graphics.OpenGL/PersistentBuffers.cs index fe224433..872efcc3 100644 --- a/Ryujinx.Graphics.OpenGL/PersistentBuffers.cs +++ b/Ryujinx.Graphics.OpenGL/PersistentBuffers.cs @@ -94,6 +94,21 @@ namespace Ryujinx.Graphics.OpenGL return new ReadOnlySpan<byte>(_bufferMap.ToPointer(), size); } + public unsafe ReadOnlySpan<byte> GetTextureData(TextureView view, int size, int layer, int level) + { + EnsureBuffer(size); + + GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyBufferHandle); + + int offset = view.WriteToPbo2D(0, layer, level); + + GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); + + Sync(); + + return new ReadOnlySpan<byte>(_bufferMap.ToPointer(), size).Slice(offset); + } + public unsafe ReadOnlySpan<byte> GetBufferData(BufferHandle buffer, int offset, int size) { EnsureBuffer(size); |
