Move GPU emulation from Ryujinx.HLE to Ryujinx.Graphics and misc changes (#402)

* Move GPU LLE emulation from HLE to Graphics

* Graphics: Move Gal/Texture to Texture

* Remove Engines/ directory and namespace

* Use tables for image formats

* Abstract OpCode decoding

* Simplify image table

* Do not leak Read* symbols in TextureReader

* Fixups

* Rename IGalFrameBuffer -> IGalRenderTarget

* Remove MaxBpp hardcoded value

* Change yet again texture data and add G8R8 flipping

* Rename GalFrameBufferFormat to GalSurfaceFormat

* Unident EnsureSetup in ImageHandler

* Add IsCompressed

* Address some feedback
This commit is contained in:
ReinUsesLisp 2018-09-08 14:51:50 -03:00 committed by gdkchan
parent a0c78f7920
commit ce1d5be212
58 changed files with 3378 additions and 3448 deletions

View file

@ -1,13 +1,11 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.Texture;
using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class ImageHandler
{
//TODO: Use a variable value here
public const int MaxBpp = 16;
private static int CopyBuffer = 0;
private static int CopyBufferSize = 0;
@ -38,87 +36,124 @@ namespace Ryujinx.Graphics.Gal.OpenGL
this.Image = Image;
}
public void EnsureSetup(GalImage Image)
public void EnsureSetup(GalImage NewImage)
{
if (Width != Image.Width ||
Height != Image.Height ||
Format != Image.Format ||
!Initialized)
if (Width == NewImage.Width &&
Height == NewImage.Height &&
Format == NewImage.Format &&
Initialized)
{
(PixelInternalFormat InternalFormat, PixelFormat PixelFormat, PixelType PixelType) =
OGLEnumConverter.GetImageFormat(Image.Format);
return;
}
GL.BindTexture(TextureTarget.Texture2D, Handle);
PixelInternalFormat InternalFmt;
PixelFormat PixelFormat;
PixelType PixelType;
if (Initialized)
if (ImageUtils.IsCompressed(NewImage.Format))
{
InternalFmt = (PixelInternalFormat)OGLEnumConverter.GetCompressedImageFormat(NewImage.Format);
PixelFormat = default(PixelFormat);
PixelType = default(PixelType);
}
else
{
(InternalFmt, PixelFormat, PixelType) = OGLEnumConverter.GetImageFormat(NewImage.Format);
}
GL.BindTexture(TextureTarget.Texture2D, Handle);
if (Initialized)
{
if (CopyBuffer == 0)
{
if (CopyBuffer == 0)
{
CopyBuffer = GL.GenBuffer();
}
int MaxWidth = Math.Max(Image.Width, Width);
int MaxHeight = Math.Max(Image.Height, Height);
int CurrentSize = MaxWidth * MaxHeight * MaxBpp;
GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer);
if (CopyBufferSize < CurrentSize)
{
CopyBufferSize = CurrentSize;
GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.StreamCopy);
}
GL.GetTexImage(TextureTarget.Texture2D, 0, this.PixelFormat, this.PixelType, IntPtr.Zero);
GL.DeleteTexture(Handle);
Handle = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, Handle);
CopyBuffer = GL.GenBuffer();
}
const int MinFilter = (int)TextureMinFilter.Linear;
const int MagFilter = (int)TextureMagFilter.Linear;
int CurrentSize = Math.Max(ImageUtils.GetSize(NewImage),
ImageUtils.GetSize(Image));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer);
const int Level = 0;
const int Border = 0;
if (CopyBufferSize < CurrentSize)
{
CopyBufferSize = CurrentSize;
GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.StreamCopy);
}
if (ImageUtils.IsCompressed(Image.Format))
{
GL.GetCompressedTexImage(TextureTarget.Texture2D, 0, IntPtr.Zero);
}
else
{
GL.GetTexImage(TextureTarget.Texture2D, 0, this.PixelFormat, this.PixelType, IntPtr.Zero);
}
GL.DeleteTexture(Handle);
Handle = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, Handle);
}
const int MinFilter = (int)TextureMinFilter.Linear;
const int MagFilter = (int)TextureMagFilter.Linear;
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
const int Level = 0;
const int Border = 0;
if (ImageUtils.IsCompressed(NewImage.Format))
{
Console.WriteLine("Hit");
GL.CompressedTexImage2D(
TextureTarget.Texture2D,
Level,
(InternalFormat)InternalFmt,
NewImage.Width,
NewImage.Height,
Border,
ImageUtils.GetSize(NewImage),
IntPtr.Zero);
}
else
{
GL.TexImage2D(
TextureTarget.Texture2D,
Level,
InternalFormat,
Image.Width,
Image.Height,
InternalFmt,
NewImage.Width,
NewImage.Height,
Border,
PixelFormat,
PixelType,
IntPtr.Zero);
if (Initialized)
{
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
}
this.Image = Image;
this.InternalFormat = InternalFormat;
this.PixelFormat = PixelFormat;
this.PixelType = PixelType;
Initialized = true;
}
if (Initialized)
{
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
}
Image = NewImage;
this.InternalFormat = InternalFmt;
this.PixelFormat = PixelFormat;
this.PixelType = PixelType;
Initialized = true;
}
public bool HasColor { get => ImageFormatConverter.HasColor(Format); }
public bool HasDepth { get => ImageFormatConverter.HasDepth(Format); }
public bool HasStencil { get => ImageFormatConverter.HasStencil(Format); }
public bool HasColor => ImageUtils.HasColor(Image.Format);
public bool HasDepth => ImageUtils.HasDepth(Image.Format);
public bool HasStencil => ImageUtils.HasStencil(Image.Format);
}
}