diff options
| author | emmauss <emmausssss@gmail.com> | 2018-02-20 22:09:23 +0200 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-02-20 17:09:23 -0300 |
| commit | 62b827f474f0aa2152dd339fcc7cf31084e16a0b (patch) | |
| tree | 0e5c55b341aee4db0ccb841a084f253ec5e05657 /Ryujinx.Graphics/Gal | |
| parent | cb665bb715834526d73c9469d16114b287faaecd (diff) | |
Split main project into core,graphics and chocolarm4 subproject (#29)
Diffstat (limited to 'Ryujinx.Graphics/Gal')
| -rw-r--r-- | Ryujinx.Graphics/Gal/GalPrimitiveType.cs | 21 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/GalVertexAttrib.cs | 33 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/GalVertexAttribSize.cs | 20 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/GalVertexAttribType.cs | 13 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/IGalRenderer.cs | 17 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs | 282 |
6 files changed, 386 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/Gal/GalPrimitiveType.cs b/Ryujinx.Graphics/Gal/GalPrimitiveType.cs new file mode 100644 index 00000000..ce084149 --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalPrimitiveType.cs @@ -0,0 +1,21 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalPrimitiveType + { + Points = 0x0, + Lines = 0x1, + LineLoop = 0x2, + LineStrip = 0x3, + Triangles = 0x4, + TriangleStrip = 0x5, + TriangleFan = 0x6, + Quads = 0x7, + QuadStrip = 0x8, + Polygon = 0x9, + LinesAdjacency = 0xa, + LineStripAdjacency = 0xb, + TrianglesAdjacency = 0xc, + TriangleStripAdjacency = 0xd, + Patches = 0xe + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalVertexAttrib.cs b/Ryujinx.Graphics/Gal/GalVertexAttrib.cs new file mode 100644 index 00000000..dc38c593 --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalVertexAttrib.cs @@ -0,0 +1,33 @@ +namespace Ryujinx.Graphics.Gal +{ + public struct GalVertexAttrib + { + public int Index { get; private set; } + public int Buffer { get; private set; } + public bool IsConst { get; private set; } + public int Offset { get; private set; } + + public GalVertexAttribSize Size { get; private set; } + public GalVertexAttribType Type { get; private set; } + + public bool IsBgra { get; private set; } + + public GalVertexAttrib( + int Index, + int Buffer, + bool IsConst, + int Offset, + GalVertexAttribSize Size, + GalVertexAttribType Type, + bool IsBgra) + { + this.Index = Index; + this.Buffer = Buffer; + this.IsConst = IsConst; + this.Offset = Offset; + this.Size = Size; + this.Type = Type; + this.IsBgra = IsBgra; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalVertexAttribSize.cs b/Ryujinx.Graphics/Gal/GalVertexAttribSize.cs new file mode 100644 index 00000000..d3ce60ac --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalVertexAttribSize.cs @@ -0,0 +1,20 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalVertexAttribSize + { + _32_32_32_32 = 0x1, + _32_32_32 = 0x2, + _16_16_16_16 = 0x3, + _32_32 = 0x4, + _16_16_16 = 0x5, + _8_8_8_8 = 0xa, + _16_16 = 0xf, + _32 = 0x12, + _8_8_8 = 0x13, + _8_8 = 0x18, + _16 = 0x1b, + _8 = 0x1d, + _10_10_10_2 = 0x30, + _11_11_10 = 0x31 + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalVertexAttribType.cs b/Ryujinx.Graphics/Gal/GalVertexAttribType.cs new file mode 100644 index 00000000..358836fd --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalVertexAttribType.cs @@ -0,0 +1,13 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalVertexAttribType + { + Snorm = 1, + Unorm = 2, + Sint = 3, + Uint = 4, + Uscaled = 5, + Sscaled = 6, + Float = 7 + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalRenderer.cs b/Ryujinx.Graphics/Gal/IGalRenderer.cs new file mode 100644 index 00000000..1870aca5 --- /dev/null +++ b/Ryujinx.Graphics/Gal/IGalRenderer.cs @@ -0,0 +1,17 @@ +using System; + +namespace Ryujinx.Graphics.Gal +{ + public interface IGalRenderer + { + long FrameBufferPtr { get; set; } + + void QueueAction(Action ActionMthd); + void RunActions(); + + void Render(); + void SendVertexBuffer(int Index, byte[] Buffer, int Stride, GalVertexAttrib[] Attribs); + void SendR8G8B8A8Texture(int Index, byte[] Buffer, int Width, int Height); + void BindTexture(int Index); + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs b/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs new file mode 100644 index 00000000..7429569b --- /dev/null +++ b/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs @@ -0,0 +1,282 @@ +using OpenTK.Graphics.OpenGL; +using System; +using System.Collections.Generic; + +namespace Ryujinx.Graphics.Gal.OpenGL +{ + public class OpenGLRenderer : IGalRenderer + { + private struct VertexBuffer + { + public int VaoHandle; + public int VboHandle; + + public int PrimCount; + } + + private struct Texture + { + public int Handle; + } + + private List<VertexBuffer> VertexBuffers; + + private Texture[] Textures; + + private Queue<Action> ActionsQueue; + + public long FrameBufferPtr { get; set; } + + public OpenGLRenderer() + { + VertexBuffers = new List<VertexBuffer>(); + + Textures = new Texture[8]; + + ActionsQueue = new Queue<Action>(); + } + + public void QueueAction(Action ActionMthd) + { + ActionsQueue.Enqueue(ActionMthd); + } + + public void RunActions() + { + while (ActionsQueue.Count > 0) + { + ActionsQueue.Dequeue()(); + } + } + + public void Render() + { + for (int Index = 0; Index < VertexBuffers.Count; Index++) + { + VertexBuffer Vb = VertexBuffers[Index]; + + if (Vb.VaoHandle != 0 && + Vb.PrimCount != 0) + { + GL.BindVertexArray(Vb.VaoHandle); + GL.DrawArrays(PrimitiveType.TriangleStrip, 0, Vb.PrimCount); + } + } + + } + + public void SendVertexBuffer(int Index, byte[] Buffer, int Stride, GalVertexAttrib[] Attribs) + { + if (Index < 0) + { + throw new ArgumentOutOfRangeException(nameof(Index)); + } + + if (Buffer.Length == 0 || Stride == 0) + { + return; + } + + EnsureVbInitialized(Index); + + VertexBuffer Vb = VertexBuffers[Index]; + + Vb.PrimCount = Buffer.Length / Stride; + + VertexBuffers[Index] = Vb; + + IntPtr Length = new IntPtr(Buffer.Length); + + GL.BindBuffer(BufferTarget.ArrayBuffer, Vb.VboHandle); + GL.BufferData(BufferTarget.ArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw); + GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + + GL.BindVertexArray(Vb.VaoHandle); + + for (int Attr = 0; Attr < 16; Attr++) + { + GL.DisableVertexAttribArray(Attr); + } + + foreach (GalVertexAttrib Attrib in Attribs) + { + if (Attrib.Index >= 3) break; + + GL.EnableVertexAttribArray(Attrib.Index); + + GL.BindBuffer(BufferTarget.ArrayBuffer, Vb.VboHandle); + + int Size = 0; + + switch (Attrib.Size) + { + case GalVertexAttribSize._8: + case GalVertexAttribSize._16: + case GalVertexAttribSize._32: + Size = 1; + break; + case GalVertexAttribSize._8_8: + case GalVertexAttribSize._16_16: + case GalVertexAttribSize._32_32: + Size = 2; + break; + case GalVertexAttribSize._8_8_8: + case GalVertexAttribSize._11_11_10: + case GalVertexAttribSize._16_16_16: + case GalVertexAttribSize._32_32_32: + Size = 3; + break; + case GalVertexAttribSize._8_8_8_8: + case GalVertexAttribSize._10_10_10_2: + case GalVertexAttribSize._16_16_16_16: + case GalVertexAttribSize._32_32_32_32: + Size = 4; + break; + } + + bool Signed = + Attrib.Type == GalVertexAttribType.Snorm || + Attrib.Type == GalVertexAttribType.Sint || + Attrib.Type == GalVertexAttribType.Sscaled; + + bool Normalize = + Attrib.Type == GalVertexAttribType.Snorm || + Attrib.Type == GalVertexAttribType.Unorm; + + VertexAttribPointerType Type = 0; + + switch (Attrib.Type) + { + case GalVertexAttribType.Snorm: + case GalVertexAttribType.Unorm: + case GalVertexAttribType.Sint: + case GalVertexAttribType.Uint: + case GalVertexAttribType.Uscaled: + case GalVertexAttribType.Sscaled: + { + switch (Attrib.Size) + { + case GalVertexAttribSize._8: + case GalVertexAttribSize._8_8: + case GalVertexAttribSize._8_8_8: + case GalVertexAttribSize._8_8_8_8: + { + Type = Signed + ? VertexAttribPointerType.Byte + : VertexAttribPointerType.UnsignedByte; + + break; + } + + case GalVertexAttribSize._16: + case GalVertexAttribSize._16_16: + case GalVertexAttribSize._16_16_16: + case GalVertexAttribSize._16_16_16_16: + { + Type = Signed + ? VertexAttribPointerType.Short + : VertexAttribPointerType.UnsignedShort; + + break; + } + + case GalVertexAttribSize._10_10_10_2: + case GalVertexAttribSize._11_11_10: + case GalVertexAttribSize._32: + case GalVertexAttribSize._32_32: + case GalVertexAttribSize._32_32_32: + case GalVertexAttribSize._32_32_32_32: + { + Type = Signed + ? VertexAttribPointerType.Int + : VertexAttribPointerType.UnsignedInt; + + break; + } + } + + break; + } + + case GalVertexAttribType.Float: + { + Type = VertexAttribPointerType.Float; + + break; + } + } + + GL.VertexAttribPointer( + Attrib.Index, + Size, + Type, + Normalize, + Stride, + Attrib.Offset); + } + + GL.BindVertexArray(0); + } + + public void SendR8G8B8A8Texture(int Index, byte[] Buffer, int Width, int Height) + { + EnsureTexInitialized(Index); + + GL.BindTexture(TextureTarget.Texture2D, Textures[Index].Handle); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + GL.TexImage2D(TextureTarget.Texture2D, + 0, + PixelInternalFormat.Rgba, + Width, + Height, + 0, + PixelFormat.Rgba, + PixelType.UnsignedByte, + Buffer); + } + + public void BindTexture(int Index) + { + GL.ActiveTexture(TextureUnit.Texture0 + Index); + + GL.BindTexture(TextureTarget.Texture2D, Textures[Index].Handle); + } + + private void EnsureVbInitialized(int VbIndex) + { + while (VbIndex >= VertexBuffers.Count) + { + VertexBuffers.Add(new VertexBuffer()); + } + + VertexBuffer Vb = VertexBuffers[VbIndex]; + + if (Vb.VaoHandle == 0) + { + Vb.VaoHandle = GL.GenVertexArray(); + } + + if (Vb.VboHandle == 0) + { + Vb.VboHandle = GL.GenBuffer(); + } + + VertexBuffers[VbIndex] = Vb; + } + + private void EnsureTexInitialized(int TexIndex) + { + Texture Tex = Textures[TexIndex]; + + if (Tex.Handle == 0) + { + Tex.Handle = GL.GenTexture(); + } + + Textures[TexIndex] = Tex; + } + } +}
\ No newline at end of file |
