aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs')
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs193
1 files changed, 181 insertions, 12 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
index 20e92ff2..96da17f8 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
@@ -25,6 +25,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ GalVertexAttribSize._11_11_10, 3 }
};
+ private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> FloatAttribTypes =
+ new Dictionary<GalVertexAttribSize, VertexAttribPointerType>()
+ {
+ { GalVertexAttribSize._32_32_32_32, VertexAttribPointerType.Float },
+ { GalVertexAttribSize._32_32_32, VertexAttribPointerType.Float },
+ { GalVertexAttribSize._16_16_16_16, VertexAttribPointerType.HalfFloat },
+ { GalVertexAttribSize._32_32, VertexAttribPointerType.Float },
+ { GalVertexAttribSize._16_16_16, VertexAttribPointerType.HalfFloat },
+ { GalVertexAttribSize._16_16, VertexAttribPointerType.HalfFloat },
+ { GalVertexAttribSize._32, VertexAttribPointerType.Float },
+ { GalVertexAttribSize._16, VertexAttribPointerType.HalfFloat }
+ };
+
private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> SignedAttribTypes =
new Dictionary<GalVertexAttribSize, VertexAttribPointerType>()
{
@@ -356,8 +369,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
continue;
}
- GL.EnableVertexAttribArray(Attrib.Index);
-
GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
bool Unsigned =
@@ -373,35 +384,50 @@ namespace Ryujinx.Graphics.Gal.OpenGL
if (Attrib.Type == GalVertexAttribType.Float)
{
- Type = VertexAttribPointerType.Float;
+ Type = GetType(FloatAttribTypes, Attrib);
}
else
{
if (Unsigned)
{
- Type = UnsignedAttribTypes[Attrib.Size];
+ Type = GetType(UnsignedAttribTypes, Attrib);
}
else
{
- Type = SignedAttribTypes[Attrib.Size];
+ Type = GetType(SignedAttribTypes, Attrib);
}
}
- int Size = AttribElements[Attrib.Size];
+ if (!AttribElements.TryGetValue(Attrib.Size, out int Size))
+ {
+ throw new InvalidOperationException("Invalid attribute size \"" + Attrib.Size + "\"!");
+ }
+
int Offset = Attrib.Offset;
- if (Attrib.Type == GalVertexAttribType.Sint ||
- Attrib.Type == GalVertexAttribType.Uint)
+ if (Binding.Stride != 0)
{
- IntPtr Pointer = new IntPtr(Offset);
+ GL.EnableVertexAttribArray(Attrib.Index);
+
+ if (Attrib.Type == GalVertexAttribType.Sint ||
+ Attrib.Type == GalVertexAttribType.Uint)
+ {
+ IntPtr Pointer = new IntPtr(Offset);
- VertexAttribIntegerType IType = (VertexAttribIntegerType)Type;
+ VertexAttribIntegerType IType = (VertexAttribIntegerType)Type;
- GL.VertexAttribIPointer(Attrib.Index, Size, IType, Binding.Stride, Pointer);
+ GL.VertexAttribIPointer(Attrib.Index, Size, IType, Binding.Stride, Pointer);
+ }
+ else
+ {
+ GL.VertexAttribPointer(Attrib.Index, Size, Type, Normalize, Binding.Stride, Offset);
+ }
}
else
{
- GL.VertexAttribPointer(Attrib.Index, Size, Type, Normalize, Binding.Stride, Offset);
+ GL.DisableVertexAttribArray(Attrib.Index);
+
+ SetConstAttrib(Attrib);
}
if (Binding.Instanced && Binding.Divisor != 0)
@@ -416,6 +442,149 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
}
+ private static VertexAttribPointerType GetType(Dictionary<GalVertexAttribSize, VertexAttribPointerType> Dict, GalVertexAttrib Attrib)
+ {
+ if (!Dict.TryGetValue(Attrib.Size, out VertexAttribPointerType Type))
+ {
+ throw new NotImplementedException("Unsupported size \"" + Attrib.Size + "\" on type \"" + Attrib.Type + "\"!");
+ }
+
+ return Type;
+ }
+
+ private unsafe static void SetConstAttrib(GalVertexAttrib Attrib)
+ {
+ void Unsupported()
+ {
+ throw new NotImplementedException("Constant attribute " + Attrib.Size + " not implemented!");
+ }
+
+ if (Attrib.Size == GalVertexAttribSize._10_10_10_2 ||
+ Attrib.Size == GalVertexAttribSize._11_11_10)
+ {
+ Unsupported();
+ }
+
+ if (Attrib.Type == GalVertexAttribType.Unorm)
+ {
+ switch (Attrib.Size)
+ {
+ case GalVertexAttribSize._8:
+ case GalVertexAttribSize._8_8:
+ case GalVertexAttribSize._8_8_8:
+ case GalVertexAttribSize._8_8_8_8:
+ GL.VertexAttrib4N((uint)Attrib.Index, (byte*)Attrib.Pointer);
+ break;
+
+ case GalVertexAttribSize._16:
+ case GalVertexAttribSize._16_16:
+ case GalVertexAttribSize._16_16_16:
+ case GalVertexAttribSize._16_16_16_16:
+ GL.VertexAttrib4N((uint)Attrib.Index, (ushort*)Attrib.Pointer);
+ break;
+
+ case GalVertexAttribSize._32:
+ case GalVertexAttribSize._32_32:
+ case GalVertexAttribSize._32_32_32:
+ case GalVertexAttribSize._32_32_32_32:
+ GL.VertexAttrib4N((uint)Attrib.Index, (uint*)Attrib.Pointer);
+ break;
+ }
+ }
+ else if (Attrib.Type == GalVertexAttribType.Snorm)
+ {
+ switch (Attrib.Size)
+ {
+ case GalVertexAttribSize._8:
+ case GalVertexAttribSize._8_8:
+ case GalVertexAttribSize._8_8_8:
+ case GalVertexAttribSize._8_8_8_8:
+ GL.VertexAttrib4N((uint)Attrib.Index, (sbyte*)Attrib.Pointer);
+ break;
+
+ case GalVertexAttribSize._16:
+ case GalVertexAttribSize._16_16:
+ case GalVertexAttribSize._16_16_16:
+ case GalVertexAttribSize._16_16_16_16:
+ GL.VertexAttrib4N((uint)Attrib.Index, (short*)Attrib.Pointer);
+ break;
+
+ case GalVertexAttribSize._32:
+ case GalVertexAttribSize._32_32:
+ case GalVertexAttribSize._32_32_32:
+ case GalVertexAttribSize._32_32_32_32:
+ GL.VertexAttrib4N((uint)Attrib.Index, (int*)Attrib.Pointer);
+ break;
+ }
+ }
+ else if (Attrib.Type == GalVertexAttribType.Uint)
+ {
+ switch (Attrib.Size)
+ {
+ case GalVertexAttribSize._8:
+ case GalVertexAttribSize._8_8:
+ case GalVertexAttribSize._8_8_8:
+ case GalVertexAttribSize._8_8_8_8:
+ GL.VertexAttribI4((uint)Attrib.Index, (byte*)Attrib.Pointer);
+ break;
+
+ case GalVertexAttribSize._16:
+ case GalVertexAttribSize._16_16:
+ case GalVertexAttribSize._16_16_16:
+ case GalVertexAttribSize._16_16_16_16:
+ GL.VertexAttribI4((uint)Attrib.Index, (ushort*)Attrib.Pointer);
+ break;
+
+ case GalVertexAttribSize._32:
+ case GalVertexAttribSize._32_32:
+ case GalVertexAttribSize._32_32_32:
+ case GalVertexAttribSize._32_32_32_32:
+ GL.VertexAttribI4((uint)Attrib.Index, (uint*)Attrib.Pointer);
+ break;
+ }
+ }
+ else if (Attrib.Type == GalVertexAttribType.Sint)
+ {
+ switch (Attrib.Size)
+ {
+ case GalVertexAttribSize._8:
+ case GalVertexAttribSize._8_8:
+ case GalVertexAttribSize._8_8_8:
+ case GalVertexAttribSize._8_8_8_8:
+ GL.VertexAttribI4((uint)Attrib.Index, (sbyte*)Attrib.Pointer);
+ break;
+
+ case GalVertexAttribSize._16:
+ case GalVertexAttribSize._16_16:
+ case GalVertexAttribSize._16_16_16:
+ case GalVertexAttribSize._16_16_16_16:
+ GL.VertexAttribI4((uint)Attrib.Index, (short*)Attrib.Pointer);
+ break;
+
+ case GalVertexAttribSize._32:
+ case GalVertexAttribSize._32_32:
+ case GalVertexAttribSize._32_32_32:
+ case GalVertexAttribSize._32_32_32_32:
+ GL.VertexAttribI4((uint)Attrib.Index, (int*)Attrib.Pointer);
+ break;
+ }
+ }
+ else if (Attrib.Type == GalVertexAttribType.Float)
+ {
+ switch (Attrib.Size)
+ {
+ case GalVertexAttribSize._32:
+ case GalVertexAttribSize._32_32:
+ case GalVertexAttribSize._32_32_32:
+ case GalVertexAttribSize._32_32_32_32:
+ GL.VertexAttrib4(Attrib.Index, (float*)Attrib.Pointer);
+ break;
+
+ default: Unsupported(); break;
+ }
+ }
+ }
+
private void Enable(EnableCap Cap, bool Enabled)
{
if (Enabled)