Skip to content

Commit

Permalink
add graphics tests and improve buffer mapping APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
LeNitrous committed Jun 30, 2023
1 parent b383618 commit 76115f1
Show file tree
Hide file tree
Showing 29 changed files with 705 additions and 157 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ jobs:
with:
dotnet-version: "7.0.x"

- name: Install Dependencies
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
sudo apt-get update
sudo apt-get install -y \
libgl1-mesa-dev \
llvm-dev \
xvfb \
xauth
mkdir .staging
wget -O Xvfb.service https://gist.githubusercontent.com/ypandit/f4fe751bcbf3ee6a32ca/raw/f2f3a955e430e1f574c985cec0947d55496066d3/Xvfb.service
sudo mv Xvfb.service /etc/systemd/system/Xvfb.service
sudo systemctl daemon-reload
sudo systemctl start Xvfb
sudo systemctl status Xvfb
- name: Test
run: dotnet test /p:ContinuousIntegrationBuild=true /p:IncludeTestAssembly=true /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput="../results/coverage.info" /p:MergeWith="../results/coverage.info" --logger trx --results-directory "./tests/results/"

Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"coverage.info",
],
"dotnet-test-explorer.testProjectPath": "**/*Tests.@(csproj|vbproj|fsproj)",
"dotnet-test-explorer.testArguments": "/p:IncludeTestAssembly=true /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=\"../results/coverage.info\" /p:MergeWith=\"../results/coverage.info\"",
"dotnet-test-explorer.testArguments": "/p:IncludeTestAssembly=true /p:CollectCoverage=true /p:CoverletOutputFormat=lcov",
"dotnet.defaultSolution": "Sekai.sln"
}
14 changes: 14 additions & 0 deletions Sekai.sln
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{AA2A0BAF
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sekai.Tests", "tests\Sekai.Tests\Sekai.Tests.csproj", "{16938759-E0A6-48CF-8148-A696175B4186}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sekai.Graphics.Tests", "tests\Sekai.Graphics.Tests\Sekai.Graphics.Tests.csproj", "{FBB0C86C-78AA-420F-A6B7-D4AB7A6D8201}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sekai.OpenGL.Tests", "tests\Sekai.OpenGL.Tests\Sekai.OpenGL.Tests.csproj", "{E7DBB11D-0308-4AF9-B83A-2E5822B28158}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -73,6 +77,14 @@ Global
{16938759-E0A6-48CF-8148-A696175B4186}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16938759-E0A6-48CF-8148-A696175B4186}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16938759-E0A6-48CF-8148-A696175B4186}.Release|Any CPU.Build.0 = Release|Any CPU
{FBB0C86C-78AA-420F-A6B7-D4AB7A6D8201}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FBB0C86C-78AA-420F-A6B7-D4AB7A6D8201}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FBB0C86C-78AA-420F-A6B7-D4AB7A6D8201}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FBB0C86C-78AA-420F-A6B7-D4AB7A6D8201}.Release|Any CPU.Build.0 = Release|Any CPU
{E7DBB11D-0308-4AF9-B83A-2E5822B28158}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7DBB11D-0308-4AF9-B83A-2E5822B28158}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7DBB11D-0308-4AF9-B83A-2E5822B28158}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7DBB11D-0308-4AF9-B83A-2E5822B28158}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -85,6 +97,8 @@ Global
{1C2DC723-C5DD-4AD8-BED8-AB0DE2360C75} = {11EBA343-73D5-4FC5-ADB9-2921D759C406}
{F47079E6-4606-4991-81B7-D91FB0FDDD51} = {11EBA343-73D5-4FC5-ADB9-2921D759C406}
{16938759-E0A6-48CF-8148-A696175B4186} = {AA2A0BAF-1A4D-4D5F-99E6-950849C75EAB}
{FBB0C86C-78AA-420F-A6B7-D4AB7A6D8201} = {AA2A0BAF-1A4D-4D5F-99E6-950849C75EAB}
{E7DBB11D-0308-4AF9-B83A-2E5822B28158} = {AA2A0BAF-1A4D-4D5F-99E6-950849C75EAB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B6237647-4791-4690-81D9-284B3F1F63D2}
Expand Down
24 changes: 3 additions & 21 deletions source/Sekai.Desktop/DesktopPlatform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public DesktopPlatform(HostOptions options)

for (int i = 0; i < count; i++)
{
var m = createMonitorFromHandle(i, ms[i]);
var m = Monitor.From(i, glfw, ms[i]);
monitors.Add(m.Name, m);
}
}
Expand Down Expand Up @@ -76,7 +76,7 @@ public override unsafe void Dispose()

public override IWindow CreateWindow()
{
return new Window(this, glfw, Options.Name);
return new Window(glfw, Options.Name);
}

public override Storage CreateStorage()
Expand Down Expand Up @@ -123,7 +123,7 @@ private void handleMonitorChanged(Silk.NET.GLFW.Monitor* m, Silk.NET.GLFW.Connec

if (state is Silk.NET.GLFW.ConnectedState.Connected)
{
monitor = createMonitorFromHandle(monitors.Count, m);
monitor = Monitor.From(monitors.Count, glfw, m);
monitors.Add(monitor.Name, monitor);
}
else
Expand All @@ -132,24 +132,6 @@ private void handleMonitorChanged(Silk.NET.GLFW.Monitor* m, Silk.NET.GLFW.Connec
}
}

private Monitor createMonitorFromHandle(int index, Silk.NET.GLFW.Monitor* monitor)
{
glfw.GetMonitorPos(monitor, out int x, out int y);

var modes = glfw.GetVideoModes(monitor, out int modeCount);
var ms = new VideoMode[modeCount];
var mc = glfw.GetVideoMode(monitor);

for (int i = 0; i < modeCount; i++)
{
ms[i] = new(new(modes[i].Width, modes[i].Height), modes[i].RefreshRate);
}

string name = glfw.GetMonitorName(monitor);

return new(index, name, monitor, new(x, y), new(new(mc->Width, mc->Height), mc->RefreshRate), ms);
}

IEnumerable<IInputDevice> IInputSource.Devices => devices.Values;

event Action<IInputDevice, bool>? IInputSource.ConnectionChanged
Expand Down
2 changes: 2 additions & 0 deletions source/Sekai.Desktop/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright (c) Cosyne
// Licensed under MIT. See LICENSE for details.

using System.Runtime.CompilerServices;
using Sekai.Desktop;
using Sekai.Hosting;

[assembly: PlatformProvider(typeof(DesktopProvider))]
[assembly: InternalsVisibleTo("Sekai.OpenGL.Tests")]
20 changes: 19 additions & 1 deletion source/Sekai.Desktop/Windowing/Monitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Sekai.Desktop.Windowing;

private readonly IEnumerable<VideoMode> modes;

public Monitor(int index, string name, Silk.NET.GLFW.Monitor* handle, Point position, VideoMode mode, IEnumerable<VideoMode> modes)
private Monitor(int index, string name, Silk.NET.GLFW.Monitor* handle, Point position, VideoMode mode, IEnumerable<VideoMode> modes)
{
Mode = mode;
Name = name;
Expand All @@ -27,5 +27,23 @@ public Monitor(int index, string name, Silk.NET.GLFW.Monitor* handle, Point posi
this.modes = modes;
}

public static Monitor From(int index, Silk.NET.GLFW.Glfw glfw, Silk.NET.GLFW.Monitor* handle)
{
glfw.GetMonitorPos(handle, out int x, out int y);

var modes = glfw.GetVideoModes(handle, out int modeCount);
var ms = new VideoMode[modeCount];
var mc = glfw.GetVideoMode(handle);

for (int i = 0; i < modeCount; i++)
{
ms[i] = new(new(modes[i].Width, modes[i].Height), modes[i].RefreshRate);
}

string name = glfw.GetMonitorName(handle);

return new(index, name, handle, new(x, y), new(new(mc->Width, mc->Height), mc->RefreshRate), ms);
}

public IEnumerable<VideoMode> GetSupportedVideoModes() => modes;
}
35 changes: 31 additions & 4 deletions source/Sekai.Desktop/Windowing/Window.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,12 @@ public IMonitor Monitor

IMonitor? bestMonitor = null;

foreach (var monitor in plat.Monitors)
var monitorHandles = glfw.GetMonitors(out int monitorCount);

for (int i = 0; i < monitorCount; i++)
{
var monitor = Windowing.Monitor.From(i, glfw, monitorHandles[i]);

int mx = monitor.Position.X;
int my = monitor.Position.Y;
int mw = monitor.Mode.Resolution.Width;
Expand Down Expand Up @@ -334,16 +338,34 @@ public string Title
private string title = string.Empty;
private bool isDisposed;
private GLContext? source;
private readonly bool owns;
private readonly Glfw glfw;
private readonly Platform plat;
private readonly WindowHandle* window;
private readonly IInputDevice[] devices = new IInputDevice[2];
private readonly Dictionary<int, IController> controllers = new();

public Window(Platform plat, Glfw glfw, string className)
public Window(string className)
: this(Glfw.GetApi(), className, true)
{
}

public Window(Glfw glfw, string className)
: this(glfw, className, false)
{
}

private Window(Glfw glfw, string className, bool owns)
{
this.glfw = glfw;
this.plat = plat;
this.owns = owns;

if (owns)
{
if (!glfw.Init())
{
throw new InvalidOperationException("Failed to initialize GLFW.");
}
}

glfw.WindowHint(WindowHintInt.ContextVersionMajor, 3);
glfw.WindowHint(WindowHintInt.ContextVersionMinor, 3);
Expand Down Expand Up @@ -531,6 +553,11 @@ public void Dispose()

glfw.DestroyWindow(window);

if (owns)
{
glfw.Terminate();
}

GC.SuppressFinalize(this);
}

Expand Down
32 changes: 23 additions & 9 deletions source/Sekai.OpenGL/GLBlendState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,43 @@ namespace Sekai.OpenGL;

internal sealed class GLBlendState : BlendState
{
public readonly bool Enabled;
public override bool Enabled { get; }
public override BlendType SourceColor { get; }
public override BlendType DestinationColor { get; }
public override BlendOperation ColorOperation { get; }
public override BlendType SourceAlpha { get; }
public override BlendType DestinationAlpha { get; }
public override BlendOperation AlphaOperation { get; }
public override ColorWriteMask WriteMask { get; }
public readonly bool Red;
public readonly bool Green;
public readonly bool Blue;
public readonly bool Alpha;
public readonly BlendingFactor SourceColor;
public readonly BlendingFactor DestinationColor;
public readonly BlendingFactor SourceAlpha;
public readonly BlendingFactor DestinationAlpha;
public readonly BlendingFactor SrcColor;
public readonly BlendingFactor DstColor;
public readonly BlendingFactor SrcAlpha;
public readonly BlendingFactor DstAlpha;
public readonly BlendEquationModeEXT ColorEquation;
public readonly BlendEquationModeEXT AlphaEquation;

public GLBlendState(BlendStateDescription description)
{
Enabled = description.Enabled;
SourceColor = description.SourceColor;
SourceAlpha = description.SourceAlpha;
DestinationColor = description.DestinationColor;
DestinationAlpha = description.DestinationAlpha;
ColorOperation = description.ColorOperation;
AlphaOperation = description.AlphaOperation;
WriteMask = description.WriteMask;
Red = (description.WriteMask & ColorWriteMask.Red) == ColorWriteMask.Red;
Green = (description.WriteMask & ColorWriteMask.Green) == ColorWriteMask.Green;
Blue = (description.WriteMask & ColorWriteMask.Blue) == ColorWriteMask.Blue;
Alpha = (description.WriteMask & ColorWriteMask.Alpha) == ColorWriteMask.Alpha;
SourceColor = description.SourceColor.AsFactor();
SourceAlpha = description.SourceAlpha.AsFactor();
DestinationColor = description.DestinationColor.AsFactor();
DestinationAlpha = description.DestinationAlpha.AsFactor();
SrcColor = description.SourceColor.AsFactor();
SrcAlpha = description.SourceAlpha.AsFactor();
DstColor = description.DestinationColor.AsFactor();
DstAlpha = description.DestinationAlpha.AsFactor();
ColorEquation = description.ColorOperation.AsEquation();
AlphaEquation = description.AlphaOperation.AsEquation();
}
Expand Down
32 changes: 7 additions & 25 deletions source/Sekai.OpenGL/GLBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@ public GLBuffer(GL gl, BufferType type, uint size, bool dynamic)
GL.BufferData(target, size, null, dynamic ? BufferUsageARB.DynamicDraw : BufferUsageARB.StaticDraw);
}

public override nint Map(MapMode mode)
protected override nint Map(MapMode mode)
{
if (isDisposed)
{
throw new ObjectDisposedException(nameof(GLBuffer));
}
ObjectDisposedException.ThrowIf(isDisposed, this);

if (isMapped)
{
Expand All @@ -55,12 +52,9 @@ public override nint Map(MapMode mode)
return (nint)GL.MapBuffer(target, mode.AsAccess());
}

public override void Unmap()
protected override void Unmap()
{
if (isDisposed)
{
throw new ObjectDisposedException(nameof(GLBuffer));
}
ObjectDisposedException.ThrowIf(isDisposed, this);

if (!isMapped)
{
Expand All @@ -74,33 +68,21 @@ public override void Unmap()

public override void SetData(nint data, uint size, uint offset)
{
if (isDisposed)
{
throw new ObjectDisposedException(nameof(GLBuffer));
}

ObjectDisposedException.ThrowIf(isDisposed, this);
GL.BindBuffer(target, handle);
GL.BufferSubData(target, (nint)offset, size, (void*)data);
}

public override void GetData(nint data, uint size, uint offset = 0)
{
if (isDisposed)
{
throw new ObjectDisposedException(nameof(GLBuffer));
}

ObjectDisposedException.ThrowIf(isDisposed, this);
GL.BindBuffer(target, handle);
GL.GetBufferSubData(target, (nint)offset, size, (void*)data);
}

public void Bind()
{
if (isDisposed)
{
throw new ObjectDisposedException(nameof(GLBuffer));
}

ObjectDisposedException.ThrowIf(isDisposed, this);
GL.BindBuffer(target, handle);
}

Expand Down
12 changes: 10 additions & 2 deletions source/Sekai.OpenGL/GLGraphicsDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ public GLGraphicsDevice(GLContext source)

GL.GenVertexArrays(1, out vao);
GL.BindVertexArray(vao);

GL.Enable(EnableCap.DebugOutput);
GL.DebugMessageCallback(debugProc, null);
}

private static void debugProc(GLEnum source, GLEnum type, int id, GLEnum severity, int length, nint message, nint userParam)
{
Console.WriteLine($"{source} {type} {severity} {System.Text.Encoding.UTF8.GetString((byte*)message, length)}");
}

public override void MakeCurrent()
Expand Down Expand Up @@ -267,7 +275,7 @@ public override void SetBlendState(BlendState state)
}

GL.Enable(EnableCap.Blend);
GL.BlendFuncSeparate(s.SourceColor, s.DestinationColor, s.SourceAlpha, s.DestinationAlpha);
GL.BlendFuncSeparate(s.SrcColor, s.DstColor, s.SrcAlpha, s.DstAlpha);
GL.BlendEquationSeparate(s.ColorEquation, s.AlphaEquation);
}

Expand Down Expand Up @@ -317,7 +325,7 @@ public override void SetRasterizerState(RasterizerState state)
{
var s = (GLRasterizerState)state;

if (!s.Culling)
if (!s.CullingEnabled)
{
GL.Disable(EnableCap.CullFace);
}
Expand Down
Loading

0 comments on commit 76115f1

Please sign in to comment.