diff options
author | riperiperi <rhy3756547@hotmail.com> | 2020-11-20 16:30:59 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-20 13:30:59 -0300 |
commit | cf7044e37bc628f25525941d25b830594b833428 (patch) | |
tree | 3da120676707d1ee7f4c2fcc2273ce036d6fd821 /Ryujinx.Graphics.OpenGL/Image/TextureView.cs | |
parent | 9852cb9c9ea3793eaef405ebb671052bb4b6643a (diff) |
Perform Compressed<->Uncompressed copies using Pixel Buffer Objects (#1732)
* PBO single layer copy, part 1
Still needs ability to take and set width/height slices. (using pack paramaters)
* PBO Copies pt 2
* Some fixes and cleanup.
* Misc Cleanup
* Move handle into the TextureInfo interface.
This interface is shared between texture storages and views.
* Move unscaled copy to the TextureCopy class.
* Address feedback.
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Image/TextureView.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureView.cs | 232 |
1 files changed, 224 insertions, 8 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs index 449c18d4..89f74cee 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs @@ -112,6 +112,14 @@ namespace Ryujinx.Graphics.OpenGL.Image // so it doesn't work for all cases. TextureView emulatedView = (TextureView)_renderer.CreateTexture(info, ScaleFactor); + _renderer.TextureCopy.CopyUnscaled( + this, + emulatedView, + 0, + firstLayer, + 0, + firstLevel); + emulatedView._emulatedViewParent = this; emulatedView.FirstLayer = firstLayer; @@ -134,7 +142,7 @@ namespace Ryujinx.Graphics.OpenGL.Image _incompatibleFormatView = (TextureView)_renderer.CreateTexture(Info, ScaleFactor); } - TextureCopyUnscaled.Copy(_parent.Info, _incompatibleFormatView.Info, _parent.Handle, _incompatibleFormatView.Handle, FirstLayer, 0, FirstLevel, 0); + _renderer.TextureCopy.CopyUnscaled(_parent, _incompatibleFormatView, FirstLayer, 0, FirstLevel, 0); return _incompatibleFormatView.Handle; } @@ -146,7 +154,7 @@ namespace Ryujinx.Graphics.OpenGL.Image { if (_incompatibleFormatView != null) { - TextureCopyUnscaled.Copy(_incompatibleFormatView.Info, _parent.Info, _incompatibleFormatView.Handle, _parent.Handle, 0, FirstLayer, 0, FirstLevel); + _renderer.TextureCopy.CopyUnscaled(_incompatibleFormatView, _parent, 0, FirstLayer, 0, FirstLevel); } } @@ -154,15 +162,13 @@ namespace Ryujinx.Graphics.OpenGL.Image { TextureView destinationView = (TextureView)destination; - TextureCopyUnscaled.Copy(Info, destinationView.Info, Handle, destinationView.Handle, 0, firstLayer, 0, firstLevel); + _renderer.TextureCopy.CopyUnscaled(this, destinationView, 0, firstLayer, 0, firstLevel); if (destinationView._emulatedViewParent != null) { - TextureCopyUnscaled.Copy( - Info, - destinationView._emulatedViewParent.Info, - Handle, - destinationView._emulatedViewParent.Handle, + _renderer.TextureCopy.CopyUnscaled( + this, + destinationView._emulatedViewParent, 0, destinationView.FirstLayer, 0, @@ -202,6 +208,50 @@ namespace Ryujinx.Graphics.OpenGL.Image 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); + + // 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); + } + else + { + GL.GetTexImage(target, level, pixelFormat, pixelType, data); + } + + return resultOffset; + } + private void WriteTo(IntPtr data, bool forceBgra = false) { TextureTarget target = Target.Convert(); @@ -263,6 +313,172 @@ namespace Ryujinx.Graphics.OpenGL.Image ReadFrom(IntPtr.Zero + offset, size); } + public void ReadFromPbo2D(int offset, int layer, int level, int width, int height) + { + ReadFrom2D(IntPtr.Zero + offset, layer, level, width, height); + } + + private void ReadFrom2D(IntPtr data, int layer, int level, int width, int height) + { + TextureTarget target = Target.Convert(); + + int mipSize = Info.GetMipSize2D(level); + + Bind(target, 0); + + FormatInfo format = FormatTable.GetFormatInfo(Info.Format); + + 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: + if (format.IsCompressed) + { + GL.CompressedTexSubImage2D( + target, + level, + 0, + layer, + width, + 1, + format.PixelFormat, + mipSize, + data); + } + else + { + GL.TexSubImage2D( + target, + level, + 0, + layer, + width, + 1, + format.PixelFormat, + format.PixelType, + data); + } + break; + + 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, + layer, + width, + height, + 1, + format.PixelFormat, + mipSize, + data); + } + else + { + GL.TexSubImage3D( + target, + level, + 0, + 0, + layer, + width, + height, + 1, + format.PixelFormat, + format.PixelType, + data); + } + break; + + case Target.Cubemap: + if (format.IsCompressed) + { + GL.CompressedTexSubImage2D( + TextureTarget.TextureCubeMapPositiveX + layer, + level, + 0, + 0, + width, + height, + format.PixelFormat, + mipSize, + data); + } + else + { + GL.TexSubImage2D( + TextureTarget.TextureCubeMapPositiveX + layer, + level, + 0, + 0, + width, + height, + format.PixelFormat, + format.PixelType, + data); + } + break; + } + } + private void ReadFrom(IntPtr data, int size) { TextureTarget target = Target.Convert(); |