726de8c46a
* Add multiple color outputs for fragment shaders * Add registers and gal enums * Use textures for framebuffers and split color and zeta framebuffers * Abstract texture and framebuffer targets as an image * Share images between framebuffers and textures * Unstub formats * Add some formats * Disable multiple attachments * Cache framebuffer attachments * Handle format types * Add some rendertarget formats * Code cleanup * Fixup half float types * Address feedback * Disable multiple attachments in shaders * Add A4B4G4R4 image format * Add reversed section for image enums
124 lines
4 KiB
C#
124 lines
4 KiB
C#
using OpenTK.Graphics.OpenGL;
|
|
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;
|
|
|
|
public GalImage Image { get; private set; }
|
|
|
|
public int Width => Image.Width;
|
|
public int Height => Image.Height;
|
|
|
|
public GalImageFormat Format => Image.Format;
|
|
|
|
public PixelInternalFormat InternalFormat { get; private set; }
|
|
public PixelFormat PixelFormat { get; private set; }
|
|
public PixelType PixelType { get; private set; }
|
|
|
|
public int Handle { get; private set; }
|
|
|
|
private bool Initialized;
|
|
|
|
public ImageHandler()
|
|
{
|
|
Handle = GL.GenTexture();
|
|
}
|
|
|
|
public ImageHandler(int Handle, GalImage Image)
|
|
{
|
|
this.Handle = Handle;
|
|
|
|
this.Image = Image;
|
|
}
|
|
|
|
public void EnsureSetup(GalImage Image)
|
|
{
|
|
if (Width != Image.Width ||
|
|
Height != Image.Height ||
|
|
Format != Image.Format ||
|
|
!Initialized)
|
|
{
|
|
(PixelInternalFormat InternalFormat, PixelFormat PixelFormat, PixelType PixelType) =
|
|
OGLEnumConverter.GetImageFormat(Image.Format);
|
|
|
|
GL.BindTexture(TextureTarget.Texture2D, Handle);
|
|
|
|
if (Initialized)
|
|
{
|
|
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);
|
|
}
|
|
|
|
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;
|
|
|
|
GL.TexImage2D(
|
|
TextureTarget.Texture2D,
|
|
Level,
|
|
InternalFormat,
|
|
Image.Width,
|
|
Image.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;
|
|
}
|
|
}
|
|
|
|
public bool HasColor { get => ImageFormatConverter.HasColor(Format); }
|
|
public bool HasDepth { get => ImageFormatConverter.HasDepth(Format); }
|
|
public bool HasStencil { get => ImageFormatConverter.HasStencil(Format); }
|
|
}
|
|
}
|