我正在为Mupen64Plus模拟器做一个前端,它支持自定义脚本,可以绘制它的视频输出。然而,我的实现在Windows上似乎是错误的(由于某种原因,在Linux上没有)。
这个MVE模仿了我用来渲染图形的系统。要编译它,你需要安装NuGet的Silk.NET.OpenGL
、Silk.NET.SDL
和SkiaSharp
。
- 视频插件控制着大部分的渲染循环,它的动作通过调用
Render()
来表示。 - 下面的行表示当视频插件请求交换缓冲区时发生的情况:
- OpenGL输出被刷新
- 它切换到一个单独的上下文来呈现Skia的输出
- Skia的输出被刷新了
- OpenGL渲染
它将在Windows上的第72行触发访问违规。
using System.Diagnostics;
using Silk.NET.OpenGL;
using Silk.NET.SDL;
using SkiaSharp;
Sdl sdl = Sdl.GetApi();
unsafe
{
sdl.SetHint(Sdl.HintVideodriver, "x11");
if (sdl.Init(Sdl.InitVideo | Sdl.InitEvents) != 0)
SdlAbort();
sdl.GLSetAttribute(GLattr.ContextMajorVersion, 4);
sdl.GLSetAttribute(GLattr.ContextMinorVersion, 1);
sdl.GLSetAttribute(GLattr.ContextProfileMask, (int) GLprofile.Compatibility);
sdl.GLSetAttribute(GLattr.RedSize, 8);
sdl.GLSetAttribute(GLattr.GreenSize, 8);
sdl.GLSetAttribute(GLattr.BlueSize, 8);
sdl.GLSetAttribute(GLattr.AlphaSize, 8);
sdl.GLSetAttribute(GLattr.Doublebuffer, 1);
sdl.GLSetAttribute(GLattr.StencilSize, 8);
Window* window = sdl.CreateWindow("Test", Sdl.WindowposCentered, Sdl.WindowposCentered, 800, 600, (uint) WindowFlags.Opengl);
void* mainCtx = sdl.GLCreateContext(window);
GL mainGL = GL.GetApi(x => (IntPtr) sdl.GLGetProcAddress(x));
void* skiaCtx = sdl.GLCreateContext(window);
if (sdl.GLMakeCurrent(window, skiaCtx) != 0)
SdlAbort();
using var grContext = GRContext.CreateGl();
Debug.Assert(grContext != null);
using var surface =
SKSurface.Create(grContext,
new GRBackendRenderTarget(800, 600, 0, 8, new GRGlFramebufferInfo(0, (uint) GLEnum.Rgba8)),
SKColorType.Rgba8888);
Debug.Assert(surface != null);
if (sdl.GLMakeCurrent(window, mainCtx) != 0)
SdlAbort();
Init(mainGL);
bool shouldClose = false;
while (true)
{
Event evt = new();
while (sdl.PollEvent(ref evt) != 0)
{
switch ((EventType) evt.Type)
{
case EventType.Windowevent:
switch ((WindowEventID) evt.Window.Event)
{
case WindowEventID.Close:
shouldClose = true;
break;
}
break;
}
}
Render(mainGL);
mainGL.Flush();
if (sdl.GLMakeCurrent(window, skiaCtx) != 0)
SdlAbort();
Render2(surface.Canvas);
surface.Flush();
if (sdl.GLMakeCurrent(window, mainCtx) != 0)
SdlAbort();
sdl.GLSwapWindow(window);
if (shouldClose)
break;
}
sdl.GLDeleteContext(mainCtx);
sdl.DestroyWindow(window);
sdl.QuitSubSystem(Sdl.InitVideo | Sdl.InitEvents);
}
void SdlAbort()
{
throw new Exception($"SDL: {sdl.GetErrorS()}");
}
void Init(GL gl)
{
}
void Render(GL gl)
{
gl.ClearColor(0.0f, 0.0f, 1.0f, 1.0f);
gl.Clear(ClearBufferMask.ColorBufferBit);
}
void Render2(SKCanvas canvas)
{
using var lime = new SKPaint
{
Color = SKColors.Lime
};
canvas.DrawCircle(300, 300, 100, lime);
}
字符串
是什么导致了这些类型的segfaults,我应该做些什么来避免它们?
1条答案
按热度按时间qq24tv8q1#
事实证明,我所描述的错误是由我的虚拟机设置中错误的图形驱动程序引起的;使用不同的驱动程序可以工作。
我在这里记录了这个问题,现在已经修复了:https://gitlab.freedesktop.org/mesa/mesa/-/issues/9460