0
0
Fork 0

Add basic error logging to the GPU

This commit is contained in:
gdkchan 2019-12-28 20:45:33 -03:00 committed by Thog
parent d1ab9fb42c
commit af8498d679
27 changed files with 473 additions and 493 deletions

View file

@ -1,4 +1,5 @@
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Texture; using Ryujinx.Graphics.GAL.Texture;
using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Gpu.Memory;
@ -7,7 +8,6 @@ using Ryujinx.Graphics.Texture.Astc;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using Ryujinx.Common.Logging;
namespace Ryujinx.Graphics.Gpu.Image namespace Ryujinx.Graphics.Gpu.Image
{ {
@ -256,7 +256,9 @@ namespace Ryujinx.Graphics.Gpu.Image
_info.Levels, _info.Levels,
out Span<byte> decoded)) out Span<byte> decoded))
{ {
// TODO: Error. string texInfo = $"{_info.Target} {_info.FormatInfo.Format} {_info.Width}x{_info.Height}x{_info.DepthOrLayers} levels {_info.Levels}";
Logger.PrintError(LogClass.Gpu, $"Invalid ASTC texture at 0x{_info.Address:X} ({texInfo}).");
} }
data = decoded; data = decoded;

View file

@ -1,26 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL.Sampler;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class AddressModeConverter
{
public static TextureWrapMode Convert(this AddressMode mode)
{
switch (mode)
{
case AddressMode.Clamp : return TextureWrapMode.Clamp;
case AddressMode.Repeat : return TextureWrapMode.Repeat;
case AddressMode.MirrorClamp : return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampExt;
case AddressMode.MirrorClampToEdge : return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToEdgeExt;
case AddressMode.MirrorClampToBorder : return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToBorderExt;
case AddressMode.ClampToBorder : return TextureWrapMode.ClampToBorder;
case AddressMode.MirroredRepeat : return TextureWrapMode.MirroredRepeat;
case AddressMode.ClampToEdge : return TextureWrapMode.ClampToEdge;
}
throw new ArgumentException($"Invalid address mode \"{mode}\".");
}
}
}

View file

@ -1,73 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL.Blend;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class BlendFactorConverter
{
public static All Convert(this BlendFactor factor)
{
switch (factor)
{
case BlendFactor.Zero:
case BlendFactor.ZeroGl:
return All.Zero;
case BlendFactor.One:
case BlendFactor.OneGl:
return All.One;
case BlendFactor.SrcColor:
case BlendFactor.SrcColorGl:
return All.SrcColor;
case BlendFactor.OneMinusSrcColor:
case BlendFactor.OneMinusSrcColorGl:
return All.OneMinusSrcColor;
case BlendFactor.SrcAlpha:
case BlendFactor.SrcAlphaGl:
return All.SrcAlpha;
case BlendFactor.OneMinusSrcAlpha:
case BlendFactor.OneMinusSrcAlphaGl:
return All.OneMinusSrcAlpha;
case BlendFactor.DstAlpha:
case BlendFactor.DstAlphaGl:
return All.DstAlpha;
case BlendFactor.OneMinusDstAlpha:
case BlendFactor.OneMinusDstAlphaGl:
return All.OneMinusDstAlpha;
case BlendFactor.DstColor:
case BlendFactor.DstColorGl:
return All.DstColor;
case BlendFactor.OneMinusDstColor:
case BlendFactor.OneMinusDstColorGl:
return All.OneMinusDstColor;
case BlendFactor.SrcAlphaSaturate:
case BlendFactor.SrcAlphaSaturateGl:
return All.SrcAlphaSaturate;
case BlendFactor.Src1Color:
case BlendFactor.Src1ColorGl:
return All.Src1Color;
case BlendFactor.OneMinusSrc1Color:
case BlendFactor.OneMinusSrc1ColorGl:
return All.OneMinusSrc1Color;
case BlendFactor.Src1Alpha:
case BlendFactor.Src1AlphaGl:
return All.Src1Alpha;
case BlendFactor.OneMinusSrc1Alpha:
case BlendFactor.OneMinusSrc1AlphaGl:
return All.OneMinusSrc1Alpha;
case BlendFactor.ConstantColor:
return All.ConstantColor;
case BlendFactor.OneMinusConstantColor:
return All.OneMinusConstantColor;
case BlendFactor.ConstantAlpha:
return All.ConstantAlpha;
case BlendFactor.OneMinusConstantAlpha:
return All.OneMinusConstantAlpha;
}
return All.Zero;
throw new ArgumentException($"Invalid blend factor \"{factor}\".");
}
}
}

View file

@ -1,35 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL.Blend;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class BlendOpConverter
{
public static BlendEquationMode Convert(this BlendOp op)
{
switch (op)
{
case BlendOp.Add:
case BlendOp.AddGl:
return BlendEquationMode.FuncAdd;
case BlendOp.Subtract:
case BlendOp.SubtractGl:
return BlendEquationMode.FuncSubtract;
case BlendOp.ReverseSubtract:
case BlendOp.ReverseSubtractGl:
return BlendEquationMode.FuncReverseSubtract;
case BlendOp.Minimum:
case BlendOp.MinimumGl:
return BlendEquationMode.Min;
case BlendOp.Maximum:
case BlendOp.MaximumGl:
return BlendEquationMode.Max;
}
return BlendEquationMode.FuncAdd;
throw new ArgumentException($"Invalid blend operation \"{op}\".");
}
}
}

View file

@ -1,20 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL.Sampler;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class CompareModeConverter
{
public static TextureCompareMode Convert(this CompareMode mode)
{
switch (mode)
{
case CompareMode.None: return TextureCompareMode.None;
case CompareMode.CompareRToTexture: return TextureCompareMode.CompareRToTexture;
}
throw new ArgumentException($"Invalid compare mode \"{mode}\".");
}
}
}

View file

@ -1,41 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL;
namespace Ryujinx.Graphics.OpenGL
{
static class CompareOpConverter
{
public static All Convert(this CompareOp op)
{
switch (op)
{
case CompareOp.Never:
case CompareOp.NeverGl:
return All.Never;
case CompareOp.Less:
case CompareOp.LessGl:
return All.Less;
case CompareOp.Equal:
case CompareOp.EqualGl:
return All.Equal;
case CompareOp.LessOrEqual:
case CompareOp.LessOrEqualGl:
return All.Lequal;
case CompareOp.Greater:
case CompareOp.GreaterGl:
return All.Greater;
case CompareOp.NotEqual:
case CompareOp.NotEqualGl:
return All.Notequal;
case CompareOp.GreaterOrEqual:
case CompareOp.GreaterOrEqualGl:
return All.Gequal;
case CompareOp.Always:
case CompareOp.AlwaysGl:
return All.Always;
}
return All.Never;
}
}
}

View file

@ -1,20 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class DepthModeConverter
{
public static ClipDepthMode Convert(this DepthMode mode)
{
switch (mode)
{
case DepthMode.MinusOneToOne: return ClipDepthMode.NegativeOneToOne;
case DepthMode.ZeroToOne: return ClipDepthMode.ZeroToOne;
}
throw new ArgumentException($"Invalid depth mode \"{mode}\".");
}
}
}

View file

@ -1,20 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL.Texture;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class DepthStencilModeConverter
{
public static All Convert(this DepthStencilMode mode)
{
switch (mode)
{
case DepthStencilMode.Depth: return All.Depth;
case DepthStencilMode.Stencil: return All.Stencil;
}
throw new ArgumentException($"Invalid depth stencil mode \"{mode}\".");
}
}
}

View file

@ -1,23 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class FaceConverter
{
public static CullFaceMode Convert(this Face face)
{
switch (face)
{
case Face.Back: return CullFaceMode.Back;
case Face.Front: return CullFaceMode.Front;
case Face.FrontAndBack: return CullFaceMode.FrontAndBack;
}
return CullFaceMode.FrontAndBack;
throw new ArgumentException($"Invalid face \"{face}\".");
}
}
}

View file

@ -1,22 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class FrontFaceConverter
{
public static FrontFaceDirection Convert(this FrontFace frontFace)
{
switch (frontFace)
{
case FrontFace.Clockwise: return FrontFaceDirection.Cw;
case FrontFace.CounterClockwise: return FrontFaceDirection.Ccw;
}
return FrontFaceDirection.Cw;
throw new ArgumentException($"Invalid front face \"{frontFace}\".");
}
}
}

View file

@ -1,21 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class IndexTypeConverter
{
public static DrawElementsType Convert(this IndexType type)
{
switch (type)
{
case IndexType.UByte: return DrawElementsType.UnsignedByte;
case IndexType.UShort: return DrawElementsType.UnsignedShort;
case IndexType.UInt: return DrawElementsType.UnsignedInt;
}
throw new ArgumentException($"Invalid index type \"{type}\".");
}
}
}

View file

@ -1,20 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL.Sampler;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class MagFilterConverter
{
public static TextureMagFilter Convert(this MagFilter filter)
{
switch (filter)
{
case MagFilter.Nearest: return TextureMagFilter.Nearest;
case MagFilter.Linear: return TextureMagFilter.Linear;
}
return TextureMagFilter.Nearest;
}
}
}

View file

@ -1,24 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL.Sampler;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class MinFilterConverter
{
public static TextureMinFilter Convert(this MinFilter filter)
{
switch (filter)
{
case MinFilter.Nearest: return TextureMinFilter.Nearest;
case MinFilter.Linear: return TextureMinFilter.Linear;
case MinFilter.NearestMipmapNearest: return TextureMinFilter.NearestMipmapNearest;
case MinFilter.LinearMipmapNearest: return TextureMinFilter.LinearMipmapNearest;
case MinFilter.NearestMipmapLinear: return TextureMinFilter.NearestMipmapLinear;
case MinFilter.LinearMipmapLinear: return TextureMinFilter.LinearMipmapLinear;
}
return TextureMinFilter.Nearest;
}
}
}

View file

@ -1,33 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class PrimitiveTopologyConverter
{
public static PrimitiveType Convert(this PrimitiveTopology topology)
{
switch (topology)
{
case PrimitiveTopology.Points: return PrimitiveType.Points;
case PrimitiveTopology.Lines: return PrimitiveType.Lines;
case PrimitiveTopology.LineLoop: return PrimitiveType.LineLoop;
case PrimitiveTopology.LineStrip: return PrimitiveType.LineStrip;
case PrimitiveTopology.Triangles: return PrimitiveType.Triangles;
case PrimitiveTopology.TriangleStrip: return PrimitiveType.TriangleStrip;
case PrimitiveTopology.TriangleFan: return PrimitiveType.TriangleFan;
case PrimitiveTopology.Quads: return PrimitiveType.Quads;
case PrimitiveTopology.QuadStrip: return PrimitiveType.QuadStrip;
case PrimitiveTopology.Polygon: return PrimitiveType.Polygon;
case PrimitiveTopology.LinesAdjacency: return PrimitiveType.LinesAdjacency;
case PrimitiveTopology.LineStripAdjacency: return PrimitiveType.LineStripAdjacency;
case PrimitiveTopology.TrianglesAdjacency: return PrimitiveType.TrianglesAdjacency;
case PrimitiveTopology.TriangleStripAdjacency: return PrimitiveType.TriangleStripAdjacency;
case PrimitiveTopology.Patches: return PrimitiveType.Patches;
}
throw new ArgumentException($"Invalid primitive topology \"{topology}\".");
}
}
}

View file

@ -1,27 +0,0 @@
using OpenTK.Graphics.OpenGL;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class StencilOpConverter
{
public static StencilOp Convert(this GAL.DepthStencil.StencilOp op)
{
switch (op)
{
case GAL.DepthStencil.StencilOp.Keep: return StencilOp.Keep;
case GAL.DepthStencil.StencilOp.Zero: return StencilOp.Zero;
case GAL.DepthStencil.StencilOp.Replace: return StencilOp.Replace;
case GAL.DepthStencil.StencilOp.IncrementAndClamp: return StencilOp.Incr;
case GAL.DepthStencil.StencilOp.DecrementAndClamp: return StencilOp.Decr;
case GAL.DepthStencil.StencilOp.Invert: return StencilOp.Invert;
case GAL.DepthStencil.StencilOp.IncrementAndWrap: return StencilOp.IncrWrap;
case GAL.DepthStencil.StencilOp.DecrementAndWrap: return StencilOp.DecrWrap;
}
return StencilOp.Keep;
throw new ArgumentException($"Invalid stencil operation \"{op}\".");
}
}
}

View file

@ -1,24 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL.Texture;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class SwizzleComponentConverter
{
public static All Convert(this SwizzleComponent swizzleComponent)
{
switch (swizzleComponent)
{
case SwizzleComponent.Zero: return All.Zero;
case SwizzleComponent.One: return All.One;
case SwizzleComponent.Red: return All.Red;
case SwizzleComponent.Green: return All.Green;
case SwizzleComponent.Blue: return All.Blue;
case SwizzleComponent.Alpha: return All.Alpha;
}
throw new ArgumentException($"Invalid swizzle component \"{swizzleComponent}\".");
}
}
}

View file

@ -1,33 +0,0 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL.Texture;
using System;
namespace Ryujinx.Graphics.OpenGL
{
static class TargetConverter
{
public static ImageTarget ConvertToImageTarget(this Target target)
{
return (ImageTarget)target.Convert();
}
public static TextureTarget Convert(this Target target)
{
switch (target)
{
case Target.Texture1D: return TextureTarget.Texture1D;
case Target.Texture2D: return TextureTarget.Texture2D;
case Target.Texture3D: return TextureTarget.Texture3D;
case Target.Texture1DArray: return TextureTarget.Texture1DArray;
case Target.Texture2DArray: return TextureTarget.Texture2DArray;
case Target.Texture2DMultisample: return TextureTarget.Texture2DMultisample;
case Target.Rectangle: return TextureTarget.TextureRectangle;
case Target.Cubemap: return TextureTarget.TextureCubeMap;
case Target.CubemapArray: return TextureTarget.TextureCubeMapArray;
case Target.TextureBuffer: return TextureTarget.TextureBuffer;
}
throw new ArgumentException($"Invalid target \"{target}\".");
}
}
}

View file

@ -1,4 +1,5 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Logging;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -12,16 +13,14 @@ namespace Ryujinx.Graphics.OpenGL
{ {
GL.Enable(EnableCap.DebugOutputSynchronous); GL.Enable(EnableCap.DebugOutputSynchronous);
int[] array = null; GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DontCare, DebugSeverityControl.DontCare, 0, (int[])null, true);
GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DontCare, DebugSeverityControl.DontCare, 0, array, true); _debugCallback = GLDebugHandler;
_debugCallback = PrintDbg;
GL.DebugMessageCallback(_debugCallback, IntPtr.Zero); GL.DebugMessageCallback(_debugCallback, IntPtr.Zero);
} }
private static void PrintDbg( private static void GLDebugHandler(
DebugSource source, DebugSource source,
DebugType type, DebugType type,
int id, int id,
@ -30,14 +29,20 @@ namespace Ryujinx.Graphics.OpenGL
IntPtr message, IntPtr message,
IntPtr userParam) IntPtr userParam)
{ {
string msg = Marshal.PtrToStringAnsi(message); string fullMessage = $"{type} {severity} {source} {Marshal.PtrToStringAnsi(message)}";
if (type == DebugType.DebugTypeError && !msg.Contains("link")) switch (type)
{ {
throw new Exception(msg); case DebugType.DebugTypeError:
Logger.PrintError(LogClass.Gpu, fullMessage);
break;
case DebugType.DebugTypePerformance:
Logger.PrintWarning(LogClass.Gpu, fullMessage);
break;
default:
Logger.PrintDebug(LogClass.Gpu, fullMessage);
break;
} }
System.Console.WriteLine("GL message: " + source + " " + type + " " + severity + " " + msg);
} }
} }
} }

View file

@ -0,0 +1,423 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Blend;
using Ryujinx.Graphics.GAL.Sampler;
using Ryujinx.Graphics.GAL.Texture;
namespace Ryujinx.Graphics.OpenGL
{
static class EnumConversion
{
public static TextureWrapMode Convert(this AddressMode mode)
{
switch (mode)
{
case AddressMode.Clamp:
return TextureWrapMode.Clamp;
case AddressMode.Repeat:
return TextureWrapMode.Repeat;
case AddressMode.MirrorClamp:
return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampExt;
case AddressMode.MirrorClampToEdge:
return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToEdgeExt;
case AddressMode.MirrorClampToBorder:
return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToBorderExt;
case AddressMode.ClampToBorder:
return TextureWrapMode.ClampToBorder;
case AddressMode.MirroredRepeat:
return TextureWrapMode.MirroredRepeat;
case AddressMode.ClampToEdge:
return TextureWrapMode.ClampToEdge;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(AddressMode)} enum value: {mode}.");
return TextureWrapMode.Clamp;
}
public static All Convert(this BlendFactor factor)
{
switch (factor)
{
case BlendFactor.Zero:
case BlendFactor.ZeroGl:
return All.Zero;
case BlendFactor.One:
case BlendFactor.OneGl:
return All.One;
case BlendFactor.SrcColor:
case BlendFactor.SrcColorGl:
return All.SrcColor;
case BlendFactor.OneMinusSrcColor:
case BlendFactor.OneMinusSrcColorGl:
return All.OneMinusSrcColor;
case BlendFactor.SrcAlpha:
case BlendFactor.SrcAlphaGl:
return All.SrcAlpha;
case BlendFactor.OneMinusSrcAlpha:
case BlendFactor.OneMinusSrcAlphaGl:
return All.OneMinusSrcAlpha;
case BlendFactor.DstAlpha:
case BlendFactor.DstAlphaGl:
return All.DstAlpha;
case BlendFactor.OneMinusDstAlpha:
case BlendFactor.OneMinusDstAlphaGl:
return All.OneMinusDstAlpha;
case BlendFactor.DstColor:
case BlendFactor.DstColorGl:
return All.DstColor;
case BlendFactor.OneMinusDstColor:
case BlendFactor.OneMinusDstColorGl:
return All.OneMinusDstColor;
case BlendFactor.SrcAlphaSaturate:
case BlendFactor.SrcAlphaSaturateGl:
return All.SrcAlphaSaturate;
case BlendFactor.Src1Color:
case BlendFactor.Src1ColorGl:
return All.Src1Color;
case BlendFactor.OneMinusSrc1Color:
case BlendFactor.OneMinusSrc1ColorGl:
return All.OneMinusSrc1Color;
case BlendFactor.Src1Alpha:
case BlendFactor.Src1AlphaGl:
return All.Src1Alpha;
case BlendFactor.OneMinusSrc1Alpha:
case BlendFactor.OneMinusSrc1AlphaGl:
return All.OneMinusSrc1Alpha;
case BlendFactor.ConstantColor:
return All.ConstantColor;
case BlendFactor.OneMinusConstantColor:
return All.OneMinusConstantColor;
case BlendFactor.ConstantAlpha:
return All.ConstantAlpha;
case BlendFactor.OneMinusConstantAlpha:
return All.OneMinusConstantAlpha;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(BlendFactor)} enum value: {factor}.");
return All.Zero;
}
public static BlendEquationMode Convert(this BlendOp op)
{
switch (op)
{
case BlendOp.Add:
case BlendOp.AddGl:
return BlendEquationMode.FuncAdd;
case BlendOp.Subtract:
case BlendOp.SubtractGl:
return BlendEquationMode.FuncSubtract;
case BlendOp.ReverseSubtract:
case BlendOp.ReverseSubtractGl:
return BlendEquationMode.FuncReverseSubtract;
case BlendOp.Minimum:
case BlendOp.MinimumGl:
return BlendEquationMode.Min;
case BlendOp.Maximum:
case BlendOp.MaximumGl:
return BlendEquationMode.Max;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(BlendOp)} enum value: {op}.");
return BlendEquationMode.FuncAdd;
}
public static TextureCompareMode Convert(this CompareMode mode)
{
switch (mode)
{
case CompareMode.None:
return TextureCompareMode.None;
case CompareMode.CompareRToTexture:
return TextureCompareMode.CompareRToTexture;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(CompareMode)} enum value: {mode}.");
return TextureCompareMode.None;
}
public static All Convert(this CompareOp op)
{
switch (op)
{
case CompareOp.Never:
case CompareOp.NeverGl:
return All.Never;
case CompareOp.Less:
case CompareOp.LessGl:
return All.Less;
case CompareOp.Equal:
case CompareOp.EqualGl:
return All.Equal;
case CompareOp.LessOrEqual:
case CompareOp.LessOrEqualGl:
return All.Lequal;
case CompareOp.Greater:
case CompareOp.GreaterGl:
return All.Greater;
case CompareOp.NotEqual:
case CompareOp.NotEqualGl:
return All.Notequal;
case CompareOp.GreaterOrEqual:
case CompareOp.GreaterOrEqualGl:
return All.Gequal;
case CompareOp.Always:
case CompareOp.AlwaysGl:
return All.Always;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(CompareOp)} enum value: {op}.");
return All.Never;
}
public static ClipDepthMode Convert(this DepthMode mode)
{
switch (mode)
{
case DepthMode.MinusOneToOne:
return ClipDepthMode.NegativeOneToOne;
case DepthMode.ZeroToOne:
return ClipDepthMode.ZeroToOne;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(DepthMode)} enum value: {mode}.");
return ClipDepthMode.NegativeOneToOne;
}
public static All Convert(this DepthStencilMode mode)
{
switch (mode)
{
case DepthStencilMode.Depth:
return All.Depth;
case DepthStencilMode.Stencil:
return All.Stencil;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(DepthStencilMode)} enum value: {mode}.");
return All.Depth;
}
public static CullFaceMode Convert(this Face face)
{
switch (face)
{
case Face.Back:
return CullFaceMode.Back;
case Face.Front:
return CullFaceMode.Front;
case Face.FrontAndBack:
return CullFaceMode.FrontAndBack;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(Face)} enum value: {face}.");
return CullFaceMode.Back;
}
public static FrontFaceDirection Convert(this FrontFace frontFace)
{
switch (frontFace)
{
case FrontFace.Clockwise:
return FrontFaceDirection.Cw;
case FrontFace.CounterClockwise:
return FrontFaceDirection.Ccw;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(FrontFace)} enum value: {frontFace}.");
return FrontFaceDirection.Cw;
}
public static DrawElementsType Convert(this IndexType type)
{
switch (type)
{
case IndexType.UByte:
return DrawElementsType.UnsignedByte;
case IndexType.UShort:
return DrawElementsType.UnsignedShort;
case IndexType.UInt:
return DrawElementsType.UnsignedInt;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(IndexType)} enum value: {type}.");
return DrawElementsType.UnsignedByte;
}
public static TextureMagFilter Convert(this MagFilter filter)
{
switch (filter)
{
case MagFilter.Nearest:
return TextureMagFilter.Nearest;
case MagFilter.Linear:
return TextureMagFilter.Linear;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(MagFilter)} enum value: {filter}.");
return TextureMagFilter.Nearest;
}
public static TextureMinFilter Convert(this MinFilter filter)
{
switch (filter)
{
case MinFilter.Nearest:
return TextureMinFilter.Nearest;
case MinFilter.Linear:
return TextureMinFilter.Linear;
case MinFilter.NearestMipmapNearest:
return TextureMinFilter.NearestMipmapNearest;
case MinFilter.LinearMipmapNearest:
return TextureMinFilter.LinearMipmapNearest;
case MinFilter.NearestMipmapLinear:
return TextureMinFilter.NearestMipmapLinear;
case MinFilter.LinearMipmapLinear:
return TextureMinFilter.LinearMipmapLinear;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(MinFilter)} enum value: {filter}.");
return TextureMinFilter.Nearest;
}
public static PrimitiveType Convert(this PrimitiveTopology topology)
{
switch (topology)
{
case PrimitiveTopology.Points:
return PrimitiveType.Points;
case PrimitiveTopology.Lines:
return PrimitiveType.Lines;
case PrimitiveTopology.LineLoop:
return PrimitiveType.LineLoop;
case PrimitiveTopology.LineStrip:
return PrimitiveType.LineStrip;
case PrimitiveTopology.Triangles:
return PrimitiveType.Triangles;
case PrimitiveTopology.TriangleStrip:
return PrimitiveType.TriangleStrip;
case PrimitiveTopology.TriangleFan:
return PrimitiveType.TriangleFan;
case PrimitiveTopology.Quads:
return PrimitiveType.Quads;
case PrimitiveTopology.QuadStrip:
return PrimitiveType.QuadStrip;
case PrimitiveTopology.Polygon:
return PrimitiveType.Polygon;
case PrimitiveTopology.LinesAdjacency:
return PrimitiveType.LinesAdjacency;
case PrimitiveTopology.LineStripAdjacency:
return PrimitiveType.LineStripAdjacency;
case PrimitiveTopology.TrianglesAdjacency:
return PrimitiveType.TrianglesAdjacency;
case PrimitiveTopology.TriangleStripAdjacency:
return PrimitiveType.TriangleStripAdjacency;
case PrimitiveTopology.Patches:
return PrimitiveType.Patches;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(PrimitiveTopology)} enum value: {topology}.");
return PrimitiveType.Points;
}
public static StencilOp Convert(this GAL.DepthStencil.StencilOp op)
{
switch (op)
{
case GAL.DepthStencil.StencilOp.Keep:
return StencilOp.Keep;
case GAL.DepthStencil.StencilOp.Zero:
return StencilOp.Zero;
case GAL.DepthStencil.StencilOp.Replace:
return StencilOp.Replace;
case GAL.DepthStencil.StencilOp.IncrementAndClamp:
return StencilOp.Incr;
case GAL.DepthStencil.StencilOp.DecrementAndClamp:
return StencilOp.Decr;
case GAL.DepthStencil.StencilOp.Invert:
return StencilOp.Invert;
case GAL.DepthStencil.StencilOp.IncrementAndWrap:
return StencilOp.IncrWrap;
case GAL.DepthStencil.StencilOp.DecrementAndWrap:
return StencilOp.DecrWrap;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(GAL.DepthStencil.StencilOp)} enum value: {op}.");
return StencilOp.Keep;
}
public static All Convert(this SwizzleComponent swizzleComponent)
{
switch (swizzleComponent)
{
case SwizzleComponent.Zero:
return All.Zero;
case SwizzleComponent.One:
return All.One;
case SwizzleComponent.Red:
return All.Red;
case SwizzleComponent.Green:
return All.Green;
case SwizzleComponent.Blue:
return All.Blue;
case SwizzleComponent.Alpha:
return All.Alpha;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(SwizzleComponent)} enum value: {swizzleComponent}.");
return All.Zero;
}
public static ImageTarget ConvertToImageTarget(this Target target)
{
return (ImageTarget)target.Convert();
}
public static TextureTarget Convert(this Target target)
{
switch (target)
{
case Target.Texture1D:
return TextureTarget.Texture1D;
case Target.Texture2D:
return TextureTarget.Texture2D;
case Target.Texture3D:
return TextureTarget.Texture3D;
case Target.Texture1DArray:
return TextureTarget.Texture1DArray;
case Target.Texture2DArray:
return TextureTarget.Texture2DArray;
case Target.Texture2DMultisample:
return TextureTarget.Texture2DMultisample;
case Target.Rectangle:
return TextureTarget.TextureRectangle;
case Target.Cubemap:
return TextureTarget.TextureCubeMap;
case Target.CubemapArray:
return TextureTarget.TextureCubeMapArray;
case Target.TextureBuffer:
return TextureTarget.TextureBuffer;
}
Logger.PrintError(LogClass.Gpu, $"Invalid {nameof(Target)} enum value: {target}.");
return TextureTarget.Texture2D;
}
}
}

View file

@ -1,6 +1,6 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
namespace Ryujinx.Graphics.OpenGL.Formats namespace Ryujinx.Graphics.OpenGL
{ {
struct FormatInfo struct FormatInfo
{ {

View file

@ -2,7 +2,7 @@ using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using System; using System;
namespace Ryujinx.Graphics.OpenGL.Formats namespace Ryujinx.Graphics.OpenGL
{ {
struct FormatTable struct FormatTable
{ {

View file

@ -1,10 +1,10 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Blend; using Ryujinx.Graphics.GAL.Blend;
using Ryujinx.Graphics.GAL.Color; using Ryujinx.Graphics.GAL.Color;
using Ryujinx.Graphics.GAL.DepthStencil; using Ryujinx.Graphics.GAL.DepthStencil;
using Ryujinx.Graphics.GAL.InputAssembler; using Ryujinx.Graphics.GAL.InputAssembler;
using Ryujinx.Graphics.OpenGL.Formats;
using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader;
using System; using System;
@ -114,6 +114,10 @@ namespace Ryujinx.Graphics.OpenGL
{ {
((Sampler)sampler).Bind(unit); ((Sampler)sampler).Bind(unit);
} }
else if (unit == -1)
{
Logger.PrintError(LogClass.Gpu, $"Invalid binding point: {stage} {index}.");
}
} }
public void BindTexture(int index, ShaderStage stage, ITexture texture) public void BindTexture(int index, ShaderStage stage, ITexture texture)
@ -131,6 +135,10 @@ namespace Ryujinx.Graphics.OpenGL
((TextureView)texture).Bind(unit); ((TextureView)texture).Bind(unit);
} }
} }
else if (unit == -1)
{
Logger.PrintError(LogClass.Gpu, $"Invalid binding point: {stage} {index}.");
}
} }
public void BindStorageBuffer(int index, ShaderStage stage, BufferRange buffer) public void BindStorageBuffer(int index, ShaderStage stage, BufferRange buffer)
@ -151,6 +159,8 @@ namespace Ryujinx.Graphics.OpenGL
if (bindingPoint == -1) if (bindingPoint == -1)
{ {
Logger.PrintError(LogClass.Gpu, $"Invalid binding point: {stage} {index}.");
return; return;
} }
@ -289,6 +299,8 @@ namespace Ryujinx.Graphics.OpenGL
{ {
if (!_program.IsLinked) if (!_program.IsLinked)
{ {
Logger.PrintError(LogClass.Gpu, "Dispatch error, shader not linked.");
return; return;
} }
@ -301,6 +313,8 @@ namespace Ryujinx.Graphics.OpenGL
{ {
if (!_program.IsLinked) if (!_program.IsLinked)
{ {
Logger.PrintError(LogClass.Gpu, "Draw error, shader not linked.");
return; return;
} }
@ -407,13 +421,13 @@ namespace Ryujinx.Graphics.OpenGL
{ {
if (!_program.IsLinked) if (!_program.IsLinked)
{ {
Logger.PrintError(LogClass.Gpu, "Draw error, shader not linked.");
return; return;
} }
PrepareForDraw(); PrepareForDraw();
int firstIndexOffset = firstIndex;
int indexElemSize = 1; int indexElemSize = 1;
switch (_elementsType) switch (_elementsType)
@ -450,7 +464,6 @@ namespace Ryujinx.Graphics.OpenGL
indexCount, indexCount,
instanceCount, instanceCount,
indexBaseOffset, indexBaseOffset,
indexElemSize,
firstVertex, firstVertex,
firstInstance); firstInstance);
} }
@ -536,7 +549,6 @@ namespace Ryujinx.Graphics.OpenGL
int indexCount, int indexCount,
int instanceCount, int instanceCount,
IntPtr indexBaseOffset, IntPtr indexBaseOffset,
int indexElemSize,
int firstVertex, int firstVertex,
int firstInstance) int firstInstance)
{ {

View file

@ -1,6 +1,7 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader;
using OpenTK.Graphics.OpenGL;
namespace Ryujinx.Graphics.OpenGL namespace Ryujinx.Graphics.OpenGL
{ {
@ -190,13 +191,11 @@ namespace Ryujinx.Graphics.OpenGL
private void CheckProgramLink() private void CheckProgramLink()
{ {
int status = 0; GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out int status);
GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out status);
if (status == 0) if (status == 0)
{ {
// throw new System.Exception(GL.GetProgramInfoLog(Handle)); Logger.PrintError(LogClass.Gpu, $"Shader linking failed: {GL.GetProgramInfoLog(Handle)}");
} }
else else
{ {

View file

@ -10,6 +10,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.GAL\Ryujinx.Graphics.GAL.csproj" /> <ProjectReference Include="..\Ryujinx.Graphics.GAL\Ryujinx.Graphics.GAL.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Shader\Ryujinx.Graphics.Shader.csproj" /> <ProjectReference Include="..\Ryujinx.Graphics.Shader\Ryujinx.Graphics.Shader.csproj" />
</ItemGroup> </ItemGroup>

View file

@ -1,7 +1,7 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Texture; using Ryujinx.Graphics.GAL.Texture;
using Ryujinx.Graphics.OpenGL.Formats;
using OpenTK.Graphics.OpenGL;
namespace Ryujinx.Graphics.OpenGL namespace Ryujinx.Graphics.OpenGL
{ {
@ -135,13 +135,15 @@ namespace Ryujinx.Graphics.OpenGL
_info.Height, _info.Height,
_info.Depth); _info.Depth);
break; break;
default:
Logger.PrintError(LogClass.Gpu, $"Invalid or unsupported texture target: {target}.");
break;
} }
} }
public ITexture CreateDefaultView() public ITexture CreateDefaultView()
{ {
int layers = _info.GetLayers();
return CreateView(_info, 0, 0); return CreateView(_info, 0, 0);
} }

View file

@ -1,7 +1,6 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Texture; using Ryujinx.Graphics.GAL.Texture;
using Ryujinx.Graphics.OpenGL.Formats;
using OpenTK.Graphics.OpenGL;
using System; using System;
namespace Ryujinx.Graphics.OpenGL namespace Ryujinx.Graphics.OpenGL

View file

@ -1,6 +1,5 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL.InputAssembler; using Ryujinx.Graphics.GAL.InputAssembler;
using Ryujinx.Graphics.OpenGL.Formats;
using System; using System;
namespace Ryujinx.Graphics.OpenGL namespace Ryujinx.Graphics.OpenGL