mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-11 01:15:26 +00:00
[KMS] Create window surface
This commit is contained in:
parent
6f6798de62
commit
6454822116
|
@ -34,6 +34,15 @@ namespace OpenTK.Platform.Egl
|
|||
{
|
||||
class EglGraphicsMode
|
||||
{
|
||||
public GraphicsMode SelectGraphicsMode(EglWindowInfo window,
|
||||
GraphicsMode mode, RenderableFlags flags)
|
||||
{
|
||||
return SelectGraphicsMode(window,
|
||||
mode.ColorFormat, mode.Depth, mode.Stencil,
|
||||
mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
|
||||
flags);
|
||||
}
|
||||
|
||||
public GraphicsMode SelectGraphicsMode(EglWindowInfo window,
|
||||
ColorFormat color, int depth, int stencil,
|
||||
int samples, ColorFormat accum, int buffers, bool stereo,
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace OpenTK.Platform.Egl
|
|||
|
||||
#region Public Members
|
||||
|
||||
public IntPtr Handle { get { return handle; } private set { handle = value; } }
|
||||
public IntPtr Handle { get { return handle; } set { handle = value; } }
|
||||
|
||||
public IntPtr Display { get { return display; } private set { display = value; } }
|
||||
|
||||
|
@ -87,7 +87,7 @@ namespace OpenTK.Platform.Egl
|
|||
if (Surface==IntPtr.Zero)
|
||||
{
|
||||
throw new GraphicsContextException(String.Format(
|
||||
"[Error] Failed to create EGL window surface, error {0}.", Egl.GetError()));
|
||||
"[EGL] Failed to create window surface, error {0}.", Egl.GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,21 +32,111 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
using GbmDevice = IntPtr; // opaque pointer "struct gbm_device*"
|
||||
|
||||
class Gbm
|
||||
{
|
||||
const string lib = "gbm";
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_create_device", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr CreateDevice(int fd);
|
||||
public static extern GbmDevice CreateDevice(int fd);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_surface_create", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr CreateSurface(GbmDevice gbm, int width, int height, SurfaceFormat format, SurfaceFlags flags);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_surface_destroy", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void DestroySurface(IntPtr surface);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_device_is_format_supported", CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool IsFormatSupported(GbmDevice gbm, SurfaceFormat format, SurfaceFlags usage);
|
||||
}
|
||||
|
||||
struct GbmDevice
|
||||
enum SurfaceFormat
|
||||
{
|
||||
public int id;
|
||||
public int fd;
|
||||
public IntPtr name;
|
||||
public int refcount;
|
||||
public Stat stat;
|
||||
BigEndian = 1 << 31,
|
||||
C8 = ((int)('C') | ((int)('8') << 8) | ((int)(' ') << 16) | ((int)(' ') << 24)),
|
||||
|
||||
RGB332 = ((int)('R') | ((int)('G') << 8) | ((int)('B') << 16) | ((int)('8') << 24)),
|
||||
BGR233 = ((int)('B') | ((int)('G') << 8) | ((int)('R') << 16) | ((int)('8') << 24)),
|
||||
|
||||
XRGB4444 = ((int)('X') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
XBGR4444 = ((int)('X') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
RGBX4444 = ((int)('R') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
BGRX4444 = ((int)('B') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
|
||||
ARGB4444 = ((int)('A') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
ABGR4444 = ((int)('A') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
RGBA4444 = ((int)('R') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
BGRA4444 = ((int)('B') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
|
||||
XRGB1555 = ((int)('X') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
XBGR1555 = ((int)('X') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
RGBX5551 = ((int)('R') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
BGRX5551 = ((int)('B') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
|
||||
ARGB1555 = ((int)('A') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
ABGR1555 = ((int)('A') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
RGBA5551 = ((int)('R') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
BGRA5551 = ((int)('B') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
|
||||
RGB565 = ((int)('R') | ((int)('G') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
|
||||
BGR565 = ((int)('B') | ((int)('G') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
|
||||
|
||||
RGB888 = ((int)('R') | ((int)('G') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
BGR888 = ((int)('B') | ((int)('G') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
|
||||
XRGB8888 = ((int)('X') | ((int)('R') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
XBGR8888 = ((int)('X') | ((int)('B') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
RGBX8888 = ((int)('R') | ((int)('X') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
BGRX8888 = ((int)('B') | ((int)('X') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
|
||||
ARGB8888 = ((int)('A') | ((int)('R') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
ABGR8888 = ((int)('A') | ((int)('B') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
RGBA8888 = ((int)('R') | ((int)('A') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
BGRA8888 = ((int)('B') | ((int)('A') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
|
||||
XRGB2101010 = ((int)('X') | ((int)('R') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
XBGR2101010 = ((int)('X') | ((int)('B') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
RGBX1010102 = ((int)('R') | ((int)('X') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
BGRX1010102 = ((int)('B') | ((int)('X') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
|
||||
ARGB2101010 = ((int)('A') | ((int)('R') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
ABGR2101010 = ((int)('A') | ((int)('B') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
RGBA1010102 = ((int)('R') | ((int)('A') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
BGRA1010102 = ((int)('B') | ((int)('A') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
|
||||
YUYV = ((int)('Y') | ((int)('U') << 8) | ((int)('Y') << 16) | ((int)('V') << 24)),
|
||||
YVYU = ((int)('Y') | ((int)('V') << 8) | ((int)('Y') << 16) | ((int)('U') << 24)),
|
||||
UYVY = ((int)('U') | ((int)('Y') << 8) | ((int)('V') << 16) | ((int)('Y') << 24)),
|
||||
VYUY = ((int)('V') | ((int)('Y') << 8) | ((int)('U') << 16) | ((int)('Y') << 24)),
|
||||
|
||||
AYUV = ((int)('A') | ((int)('Y') << 8) | ((int)('U') << 16) | ((int)('V') << 24)),
|
||||
|
||||
NV12 = ((int)('N') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
NV21 = ((int)('N') | ((int)('V') << 8) | ((int)('2') << 16) | ((int)('1') << 24)),
|
||||
NV16 = ((int)('N') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
|
||||
NV61 = ((int)('N') | ((int)('V') << 8) | ((int)('6') << 16) | ((int)('1') << 24)),
|
||||
|
||||
YUV410 = ((int)('Y') | ((int)('U') << 8) | ((int)('V') << 16) | ((int)('9') << 24)),
|
||||
YVU410 = ((int)('Y') | ((int)('V') << 8) | ((int)('U') << 16) | ((int)('9') << 24)),
|
||||
YUV411 = ((int)('Y') | ((int)('U') << 8) | ((int)('1') << 16) | ((int)('1') << 24)),
|
||||
YVU411 = ((int)('Y') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('1') << 24)),
|
||||
YUV420 = ((int)('Y') | ((int)('U') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
YVU420 = ((int)('Y') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
YUV422 = ((int)('Y') | ((int)('U') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
|
||||
YVU422 = ((int)('Y') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
|
||||
YUV444 = ((int)('Y') | ((int)('U') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
YVU444 = ((int)('Y') | ((int)('V') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum SurfaceFlags
|
||||
{
|
||||
Scanout = (1 << 0),
|
||||
Cursor64x64 = (1 << 1),
|
||||
Rendering = (1 << 2),
|
||||
Write = (1 << 3),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,6 @@ namespace OpenTK.Platform.Linux
|
|||
}
|
||||
|
||||
readonly int FD;
|
||||
readonly GbmDevice Device;
|
||||
readonly Dictionary<int, int> DisplayIds =
|
||||
new Dictionary<int, int>();
|
||||
|
||||
|
@ -203,19 +202,16 @@ namespace OpenTK.Platform.Linux
|
|||
0,
|
||||
current.Width,
|
||||
current.Height);
|
||||
|
||||
DisplayDevice device = new DisplayDevice(
|
||||
current,
|
||||
AvailableDevices.Count == 0,
|
||||
modes,
|
||||
bounds,
|
||||
display);
|
||||
bool is_primary = AvailableDevices.Count == 0;
|
||||
DisplayDevice device = new DisplayDevice(current, is_primary,
|
||||
modes, bounds, display);
|
||||
|
||||
if (AvailableDevices.Count == 0)
|
||||
{
|
||||
Primary = device;
|
||||
}
|
||||
|
||||
Debug.Print("[KMS] Detected display {0}", device);
|
||||
AvailableDevices.Add(device);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace OpenTK.Platform.Linux
|
|||
class LinuxFactory : PlatformFactoryBase
|
||||
{
|
||||
int fd;
|
||||
GbmDevice gbm_device;
|
||||
IntPtr gbm_device;
|
||||
IntPtr display;
|
||||
|
||||
IJoystickDriver2 JoystickDriver;
|
||||
|
@ -66,15 +66,14 @@ namespace OpenTK.Platform.Linux
|
|||
}
|
||||
Debug.Print("[KMS] GPU '{0}' opened as fd:{1}", gpu, fd);
|
||||
|
||||
IntPtr dev = Gbm.CreateDevice(fd);
|
||||
if (dev == IntPtr.Zero)
|
||||
gbm_device = Gbm.CreateDevice(fd);
|
||||
if (gbm_device == IntPtr.Zero)
|
||||
{
|
||||
throw new NotSupportedException("[KMS] Failed to create GBM device");
|
||||
}
|
||||
gbm_device = (GbmDevice)Marshal.PtrToStructure(dev, typeof(GbmDevice));
|
||||
Debug.Print("[KMS] GBM {0:x} created successfully", dev);
|
||||
Debug.Print("[KMS] GBM {0:x} created successfully; ", gbm_device);
|
||||
|
||||
display = Egl.GetDisplay(dev);
|
||||
display = Egl.GetDisplay(gbm_device);
|
||||
if (display == IntPtr.Zero)
|
||||
{
|
||||
throw new NotSupportedException("[KMS] Failed to create EGL display");
|
||||
|
@ -96,7 +95,7 @@ namespace OpenTK.Platform.Linux
|
|||
|
||||
public override INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice display_device)
|
||||
{
|
||||
return new LinuxNativeWindow(display, gbm_device, width, height, title, mode, options, display_device);
|
||||
return new LinuxNativeWindow(display, gbm_device, x, y, width, height, title, mode, options, display_device);
|
||||
}
|
||||
|
||||
public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform.Egl;
|
||||
|
||||
|
@ -38,27 +40,89 @@ namespace OpenTK.Platform.Linux
|
|||
|
||||
class LinuxNativeWindow : NativeWindowBase
|
||||
{
|
||||
LinuxWindowInfo window_info;
|
||||
LinuxWindowInfo window;
|
||||
string title;
|
||||
Icon icon;
|
||||
bool exists;
|
||||
Rectangle bounds;
|
||||
Size client_size;
|
||||
|
||||
public LinuxNativeWindow(IntPtr display, GbmDevice device,
|
||||
int width, int height, string title, GraphicsMode mode, GameWindowFlags options,
|
||||
public LinuxNativeWindow(IntPtr display, IntPtr gbm,
|
||||
int x, int y, int width, int height, string title,
|
||||
GraphicsMode mode, GameWindowFlags options,
|
||||
DisplayDevice display_device)
|
||||
{
|
||||
Debug.Print("[KMS] Creating window on display {0:x}", display);
|
||||
|
||||
Title = title;
|
||||
bounds = new Rectangle(0, 0, width, height);
|
||||
client_size = bounds.Size;
|
||||
|
||||
//window_info = new LinuxWindowInfo(
|
||||
// Egl.CreateWindowSurface(
|
||||
window = new LinuxWindowInfo(display);
|
||||
if (!mode.Index.HasValue)
|
||||
{
|
||||
mode = new EglGraphicsMode().SelectGraphicsMode(window, mode, 0);
|
||||
}
|
||||
Debug.Print("[KMS] Selected EGL mode {0}", mode);
|
||||
|
||||
unsafe
|
||||
{
|
||||
SurfaceFormat format = GetSurfaceFormat(mode);
|
||||
SurfaceFlags usage = SurfaceFlags.Rendering | SurfaceFlags.Scanout;
|
||||
if (!Gbm.IsFormatSupported(gbm, format, usage))
|
||||
{
|
||||
format = SurfaceFormat.XBGR8888;
|
||||
}
|
||||
|
||||
Debug.Print("[KMS] Creating GBM surface on {0:x} with {1}x{2} {3} {4}",
|
||||
gbm, width, height, format, usage);
|
||||
IntPtr gbm_surface = Gbm.CreateSurface(gbm,
|
||||
width, height, format, usage);
|
||||
if (gbm_surface == IntPtr.Zero)
|
||||
{
|
||||
throw new NotSupportedException("[KMS] Failed to create GBM surface for rendering");
|
||||
}
|
||||
|
||||
window.Handle = gbm_surface;
|
||||
Debug.Print("[KMS] Created GBM surface {0:x}", window.Handle);
|
||||
}
|
||||
|
||||
window.CreateWindowSurface(mode.Index.Value);
|
||||
Debug.Print("[KMS] Created EGL surface {0:x}", window.Surface);
|
||||
|
||||
// Todo: create mouse cursor
|
||||
exists = true;
|
||||
}
|
||||
|
||||
SurfaceFormat GetSurfaceFormat(GraphicsMode mode)
|
||||
{
|
||||
int r = mode.ColorFormat.Red;
|
||||
int g = mode.ColorFormat.Green;
|
||||
int b = mode.ColorFormat.Blue;
|
||||
int a = mode.ColorFormat.Alpha;
|
||||
|
||||
if (mode.ColorFormat.IsIndexed)
|
||||
return SurfaceFormat.C8;
|
||||
if (r == 3 && g == 3 && b == 2 && a == 0)
|
||||
return SurfaceFormat.RGB332;
|
||||
if (r == 5 && g == 6 && b == 5 && a == 0)
|
||||
return SurfaceFormat.RGB565;
|
||||
if (r == 5 && g == 6 && b == 5 && a == 0)
|
||||
return SurfaceFormat.RGB565;
|
||||
if (r == 8 && g == 8 && b == 8 && a == 0)
|
||||
return SurfaceFormat.RGB888;
|
||||
if (r == 5 && g == 5 && b == 5 && a == 1)
|
||||
return SurfaceFormat.RGBA5551;
|
||||
if (r == 10 && g == 10 && b == 10 && a == 2)
|
||||
return SurfaceFormat.RGBA1010102;
|
||||
if (r == 4 && g == 4 && b == 4 && a == 4)
|
||||
return SurfaceFormat.RGBA4444;
|
||||
if (r == 8 && g == 8 && b == 8 && a == 8)
|
||||
return SurfaceFormat.RGBA8888;
|
||||
|
||||
return SurfaceFormat.RGBA8888;
|
||||
}
|
||||
|
||||
#region INativeWindow Members
|
||||
|
||||
public override void Close()
|
||||
|
@ -80,7 +144,11 @@ namespace OpenTK.Platform.Linux
|
|||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
// Todo
|
||||
if (disposing)
|
||||
{
|
||||
window.Dispose();
|
||||
Gbm.DestroySurface(window.Handle);
|
||||
}
|
||||
}
|
||||
|
||||
public override Icon Icon
|
||||
|
@ -146,7 +214,7 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
get
|
||||
{
|
||||
return window_info;
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,9 +34,11 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
class LinuxWindowInfo : EglWindowInfo
|
||||
{
|
||||
public LinuxWindowInfo(IntPtr handle, IntPtr display, IntPtr surface)
|
||||
: base(handle, display, surface)
|
||||
public LinuxWindowInfo(IntPtr display)
|
||||
: base(IntPtr.Zero, display, IntPtr.Zero)
|
||||
{
|
||||
// The window handle and surface handle must
|
||||
// be filled in manually once they are known.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue