aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services/SurfaceFlinger
diff options
context:
space:
mode:
authorThomas Guillemard <me@thog.eu>2019-11-03 18:26:29 +0100
committerAc_K <Acoustik666@gmail.com>2019-11-03 18:26:29 +0100
commitb29950dbd6657f6f6511bc2df2efc4b0ff40e8b9 (patch)
tree204cba19b5fd54744d247119c0b725c89d524cc0 /Ryujinx.HLE/HOS/Services/SurfaceFlinger
parent9426ef3f06916f4206213b28b1ca162c851d4e07 (diff)
hle: Fix some inconsistencies in namespace naming in Services (#808)
Also fix IShopServiceAccessSystemInterface being in the wrong namespace.
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/SurfaceFlinger')
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/NvFlinger.cs413
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs58
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferEntry.cs13
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferState.cs10
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorBytePerPixel.cs17
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorComponent.cs42
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorDataType.cs9
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorFormat.cs235
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorShift.cs10
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSpace.cs33
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSwizzle.cs31
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Fence.cs11
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GbpBuffer.cs37
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBufferHeader.cs21
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/HalTransform.cs14
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/MultiFence.cs23
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBuffer.cs41
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurface.cs44
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurfaceArray.cs39
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/QueueBufferObject.cs35
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Rect.cs13
21 files changed, 1149 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NvFlinger.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NvFlinger.cs
new file mode 100644
index 00000000..e3e4a1a4
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NvFlinger.cs
@@ -0,0 +1,413 @@
+using Ryujinx.Common.Logging;
+using Ryujinx.Graphics.Gal;
+using Ryujinx.Graphics.Memory;
+using Ryujinx.HLE.HOS.Kernel.Threading;
+using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu;
+using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+
+using static Ryujinx.HLE.HOS.Services.SurfaceFlinger.Parcel;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ class NvFlinger : IDisposable
+ {
+ private delegate ResultCode ServiceProcessParcel(ServiceCtx context, BinaryReader parcelReader);
+
+ private Dictionary<(string, int), ServiceProcessParcel> _commands;
+
+ private KEvent _binderEvent;
+
+ private IGalRenderer _renderer;
+
+ private const int BufferQueueCount = 0x40;
+ private const int BufferQueueMask = BufferQueueCount - 1;
+
+ private BufferEntry[] _bufferQueue;
+
+ private AutoResetEvent _waitBufferFree;
+
+ private bool _disposed;
+
+ public NvFlinger(IGalRenderer renderer, KEvent binderEvent)
+ {
+ _commands = new Dictionary<(string, int), ServiceProcessParcel>
+ {
+ { ("android.gui.IGraphicBufferProducer", 0x1), GbpRequestBuffer },
+ { ("android.gui.IGraphicBufferProducer", 0x3), GbpDequeueBuffer },
+ { ("android.gui.IGraphicBufferProducer", 0x4), GbpDetachBuffer },
+ { ("android.gui.IGraphicBufferProducer", 0x7), GbpQueueBuffer },
+ { ("android.gui.IGraphicBufferProducer", 0x8), GbpCancelBuffer },
+ { ("android.gui.IGraphicBufferProducer", 0x9), GbpQuery },
+ { ("android.gui.IGraphicBufferProducer", 0xa), GbpConnect },
+ { ("android.gui.IGraphicBufferProducer", 0xb), GbpDisconnect },
+ { ("android.gui.IGraphicBufferProducer", 0xe), GbpPreallocBuffer }
+ };
+
+ _renderer = renderer;
+ _binderEvent = binderEvent;
+
+ _bufferQueue = new BufferEntry[0x40];
+
+ _waitBufferFree = new AutoResetEvent(false);
+ }
+
+ public ResultCode ProcessParcelRequest(ServiceCtx context, byte[] parcelData, int code)
+ {
+ using (MemoryStream ms = new MemoryStream(parcelData))
+ {
+ BinaryReader reader = new BinaryReader(ms);
+
+ ms.Seek(4, SeekOrigin.Current);
+
+ int strSize = reader.ReadInt32();
+
+ string interfaceName = Encoding.Unicode.GetString(reader.ReadBytes(strSize * 2));
+
+ long remainder = ms.Position & 0xf;
+
+ if (remainder != 0)
+ {
+ ms.Seek(0x10 - remainder, SeekOrigin.Current);
+ }
+
+ ms.Seek(0x50, SeekOrigin.Begin);
+
+ if (_commands.TryGetValue((interfaceName, code), out ServiceProcessParcel procReq))
+ {
+ Logger.PrintDebug(LogClass.ServiceVi, $"{interfaceName} {procReq.Method.Name}");
+
+ return procReq(context, reader);
+ }
+ else
+ {
+ throw new NotImplementedException($"{interfaceName} {code}");
+ }
+ }
+ }
+
+ private ResultCode GbpRequestBuffer(ServiceCtx context, BinaryReader parcelReader)
+ {
+ int slot = parcelReader.ReadInt32();
+
+ using (MemoryStream ms = new MemoryStream())
+ {
+ BinaryWriter writer = new BinaryWriter(ms);
+
+ BufferEntry entry = _bufferQueue[slot];
+
+ int bufferCount = 1; //?
+ long bufferSize = entry.Data.Size;
+
+ writer.Write(bufferCount);
+ writer.Write(bufferSize);
+
+ entry.Data.Write(writer);
+
+ writer.Write(0);
+
+ return MakeReplyParcel(context, ms.ToArray());
+ }
+ }
+
+ private ResultCode GbpDequeueBuffer(ServiceCtx context, BinaryReader parcelReader)
+ {
+ // TODO: Errors.
+ int format = parcelReader.ReadInt32();
+ int width = parcelReader.ReadInt32();
+ int height = parcelReader.ReadInt32();
+ int getTimestamps = parcelReader.ReadInt32();
+ int usage = parcelReader.ReadInt32();
+
+ int slot = GetFreeSlotBlocking(width, height);
+
+ return MakeReplyParcel(context, slot, 1, 0x24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ }
+
+ private ResultCode GbpQueueBuffer(ServiceCtx context, BinaryReader parcelReader)
+ {
+ context.Device.Statistics.RecordGameFrameTime();
+
+ // TODO: Errors.
+ int slot = parcelReader.ReadInt32();
+
+ long Position = parcelReader.BaseStream.Position;
+
+ QueueBufferObject queueBufferObject = ReadFlattenedObject<QueueBufferObject>(parcelReader);
+
+ parcelReader.BaseStream.Position = Position;
+
+ _bufferQueue[slot].Transform = queueBufferObject.Transform;
+ _bufferQueue[slot].Crop = queueBufferObject.Crop;
+
+ _bufferQueue[slot].State = BufferState.Queued;
+
+ SendFrameBuffer(context, slot);
+
+ if (context.Device.EnableDeviceVsync)
+ {
+ context.Device.VsyncEvent.WaitOne();
+ }
+
+ return MakeReplyParcel(context, 1280, 720, 0, 0, 0);
+ }
+
+ private ResultCode GbpDetachBuffer(ServiceCtx context, BinaryReader parcelReader)
+ {
+ return MakeReplyParcel(context, 0);
+ }
+
+ private ResultCode GbpCancelBuffer(ServiceCtx context, BinaryReader parcelReader)
+ {
+ // TODO: Errors.
+ int slot = parcelReader.ReadInt32();
+
+ MultiFence fence = ReadFlattenedObject<MultiFence>(parcelReader);
+
+ _bufferQueue[slot].State = BufferState.Free;
+
+ _waitBufferFree.Set();
+
+ return MakeReplyParcel(context, 0);
+ }
+
+ private ResultCode GbpQuery(ServiceCtx context, BinaryReader parcelReader)
+ {
+ return MakeReplyParcel(context, 0, 0);
+ }
+
+ private ResultCode GbpConnect(ServiceCtx context, BinaryReader parcelReader)
+ {
+ return MakeReplyParcel(context, 1280, 720, 0, 0, 0);
+ }
+
+ private ResultCode GbpDisconnect(ServiceCtx context, BinaryReader parcelReader)
+ {
+ return MakeReplyParcel(context, 0);
+ }
+
+ private ResultCode GbpPreallocBuffer(ServiceCtx context, BinaryReader parcelReader)
+ {
+ int slot = parcelReader.ReadInt32();
+
+ bool hasInput = parcelReader.ReadInt32() == 1;
+
+ if (hasInput)
+ {
+ byte[] graphicBuffer = ReadFlattenedObject(parcelReader);
+
+ _bufferQueue[slot].State = BufferState.Free;
+
+ using (BinaryReader graphicBufferReader = new BinaryReader(new MemoryStream(graphicBuffer)))
+ {
+ _bufferQueue[slot].Data = new GbpBuffer(graphicBufferReader);
+ }
+
+ }
+
+ return MakeReplyParcel(context, 0);
+ }
+
+ private byte[] ReadFlattenedObject(BinaryReader reader)
+ {
+ long flattenedObjectSize = reader.ReadInt64();
+
+ return reader.ReadBytes((int)flattenedObjectSize);
+ }
+
+ private unsafe T ReadFlattenedObject<T>(BinaryReader reader) where T: struct
+ {
+ byte[] data = ReadFlattenedObject(reader);
+
+ fixed (byte* ptr = data)
+ {
+ return Marshal.PtrToStructure<T>((IntPtr)ptr);
+ }
+ }
+
+ private ResultCode MakeReplyParcel(ServiceCtx context, params int[] ints)
+ {
+ using (MemoryStream ms = new MemoryStream())
+ {
+ BinaryWriter writer = new BinaryWriter(ms);
+
+ foreach (int Int in ints)
+ {
+ writer.Write(Int);
+ }
+
+ return MakeReplyParcel(context, ms.ToArray());
+ }
+ }
+
+ private ResultCode MakeReplyParcel(ServiceCtx context, byte[] data)
+ {
+ (long replyPos, long replySize) = context.Request.GetBufferType0x22();
+
+ byte[] reply = MakeParcel(data, new byte[0]);
+
+ context.Memory.WriteBytes(replyPos, reply);
+
+ return ResultCode.Success;
+ }
+
+ private GalImageFormat ConvertColorFormat(ColorFormat colorFormat)
+ {
+ switch (colorFormat)
+ {
+ case ColorFormat.A8B8G8R8:
+ return GalImageFormat.Rgba8 | GalImageFormat.Unorm;
+ case ColorFormat.X8B8G8R8:
+ return GalImageFormat.Rgbx8 | GalImageFormat.Unorm;
+ case ColorFormat.R5G6B5:
+ return GalImageFormat.Bgr565 | GalImageFormat.Unorm;
+ case ColorFormat.A8R8G8B8:
+ return GalImageFormat.Bgra8 | GalImageFormat.Unorm;
+ case ColorFormat.A4B4G4R4:
+ return GalImageFormat.Rgba4 | GalImageFormat.Unorm;
+ default:
+ throw new NotImplementedException($"Color Format \"{colorFormat}\" not implemented!");
+ }
+ }
+
+ // TODO: support multi surface
+ private void SendFrameBuffer(ServiceCtx context, int slot)
+ {
+ int fbWidth = _bufferQueue[slot].Data.Header.Width;
+ int fbHeight = _bufferQueue[slot].Data.Header.Height;
+
+ int nvMapHandle = _bufferQueue[slot].Data.Buffer.Surfaces[0].NvMapHandle;
+
+ if (nvMapHandle == 0)
+ {
+ nvMapHandle = _bufferQueue[slot].Data.Buffer.NvMapId;
+ }
+
+ int bufferOffset = _bufferQueue[slot].Data.Buffer.Surfaces[0].Offset;
+
+ NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(context.Process, nvMapHandle);
+
+ long fbAddr = map.Address + bufferOffset;
+
+ _bufferQueue[slot].State = BufferState.Acquired;
+
+ Rect crop = _bufferQueue[slot].Crop;
+
+ bool flipX = _bufferQueue[slot].Transform.HasFlag(HalTransform.FlipX);
+ bool flipY = _bufferQueue[slot].Transform.HasFlag(HalTransform.FlipY);
+
+ GalImageFormat imageFormat = ConvertColorFormat(_bufferQueue[slot].Data.Buffer.Surfaces[0].ColorFormat);
+
+ int BlockHeight = 1 << _bufferQueue[slot].Data.Buffer.Surfaces[0].BlockHeightLog2;
+
+ // Note: Rotation is being ignored.
+
+ int top = crop.Top;
+ int left = crop.Left;
+ int right = crop.Right;
+ int bottom = crop.Bottom;
+
+ NvGpuVmm vmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(context.Process).Vmm;
+
+ _renderer.QueueAction(() =>
+ {
+ if (!_renderer.Texture.TryGetImage(fbAddr, out GalImage image))
+ {
+ image = new GalImage(
+ fbWidth,
+ fbHeight, 1, 1, 1, BlockHeight, 1,
+ GalMemoryLayout.BlockLinear,
+ imageFormat,
+ GalTextureTarget.TwoD);
+ }
+
+ context.Device.Gpu.ResourceManager.ClearPbCache();
+ context.Device.Gpu.ResourceManager.SendTexture(vmm, fbAddr, image);
+
+ _renderer.RenderTarget.SetTransform(flipX, flipY, top, left, right, bottom);
+ _renderer.RenderTarget.Present(fbAddr);
+
+ ReleaseBuffer(slot);
+ });
+ }
+
+ private void ReleaseBuffer(int slot)
+ {
+ _bufferQueue[slot].State = BufferState.Free;
+
+ _binderEvent.ReadableEvent.Signal();
+
+ _waitBufferFree.Set();
+ }
+
+ private int GetFreeSlotBlocking(int width, int height)
+ {
+ int slot;
+
+ do
+ {
+ if ((slot = GetFreeSlot(width, height)) != -1)
+ {
+ break;
+ }
+
+ if (_disposed)
+ {
+ break;
+ }
+
+ _waitBufferFree.WaitOne();
+ }
+ while (!_disposed);
+
+ return slot;
+ }
+
+ private int GetFreeSlot(int width, int height)
+ {
+ lock (_bufferQueue)
+ {
+ for (int slot = 0; slot < _bufferQueue.Length; slot++)
+ {
+ if (_bufferQueue[slot].State != BufferState.Free)
+ {
+ continue;
+ }
+
+ GbpBuffer data = _bufferQueue[slot].Data;
+
+ if (data.Header.Width == width &&
+ data.Header.Height == height)
+ {
+ _bufferQueue[slot].State = BufferState.Dequeued;
+
+ return slot;
+ }
+ }
+ }
+
+ return -1;
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing && !_disposed)
+ {
+ _disposed = true;
+
+ _waitBufferFree.Set();
+ _waitBufferFree.Dispose();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs
new file mode 100644
index 00000000..f5d93423
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs
@@ -0,0 +1,58 @@
+using System;
+using System.IO;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ static class Parcel
+ {
+ public static byte[] GetParcelData(byte[] parcel)
+ {
+ if (parcel == null)
+ {
+ throw new ArgumentNullException(nameof(parcel));
+ }
+
+ using (MemoryStream ms = new MemoryStream(parcel))
+ {
+ BinaryReader reader = new BinaryReader(ms);
+
+ int dataSize = reader.ReadInt32();
+ int dataOffset = reader.ReadInt32();
+ int objsSize = reader.ReadInt32();
+ int objsOffset = reader.ReadInt32();
+
+ ms.Seek(dataOffset - 0x10, SeekOrigin.Current);
+
+ return reader.ReadBytes(dataSize);
+ }
+ }
+
+ public static byte[] MakeParcel(byte[] data, byte[] objs)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException(nameof(data));
+ }
+
+ if (objs == null)
+ {
+ throw new ArgumentNullException(nameof(objs));
+ }
+
+ using (MemoryStream ms = new MemoryStream())
+ {
+ BinaryWriter writer = new BinaryWriter(ms);
+
+ writer.Write(data.Length);
+ writer.Write(0x10);
+ writer.Write(objs.Length);
+ writer.Write(data.Length + 0x10);
+
+ writer.Write(data);
+ writer.Write(objs);
+
+ return ms.ToArray();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferEntry.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferEntry.cs
new file mode 100644
index 00000000..cc4e07d9
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferEntry.cs
@@ -0,0 +1,13 @@
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ struct BufferEntry
+ {
+ public BufferState State;
+
+ public HalTransform Transform;
+
+ public Rect Crop;
+
+ public GbpBuffer Data;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferState.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferState.cs
new file mode 100644
index 00000000..673da860
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferState.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ enum BufferState
+ {
+ Free,
+ Dequeued,
+ Queued,
+ Acquired
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorBytePerPixel.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorBytePerPixel.cs
new file mode 100644
index 00000000..b47d35b4
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorBytePerPixel.cs
@@ -0,0 +1,17 @@
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ enum ColorBytePerPixel
+ {
+ Bpp1 = 1,
+ Bpp2 = 2,
+ Bpp4 = 4,
+ Bpp8 = 8,
+ Bpp16 = 16,
+ Bpp24 = 24,
+ Bpp32 = 32,
+ Bpp48 = 48,
+ Bpp64 = 64,
+ Bpp96 = 96,
+ Bpp128 = 128
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorComponent.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorComponent.cs
new file mode 100644
index 00000000..e9669f12
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorComponent.cs
@@ -0,0 +1,42 @@
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ enum ColorComponent : uint
+ {
+ X1 = (0x01 << ColorShift.Component) | ColorBytePerPixel.Bpp1,
+ X2 = (0x02 << ColorShift.Component) | ColorBytePerPixel.Bpp2,
+ X4 = (0x03 << ColorShift.Component) | ColorBytePerPixel.Bpp4,
+ X8 = (0x04 << ColorShift.Component) | ColorBytePerPixel.Bpp8,
+ Y4X4 = (0x05 << ColorShift.Component) | ColorBytePerPixel.Bpp8,
+ X3Y3Z2 = (0x06 << ColorShift.Component) | ColorBytePerPixel.Bpp8,
+ X8Y8 = (0x07 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X8Y8X8Z8 = (0x08 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ Y8X8Z8X8 = (0x09 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X16 = (0x0A << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ Y2X14 = (0x0B << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ Y4X12 = (0x0C << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ Y6X10 = (0x0D << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ Y8X8 = (0x0E << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X10 = (0x0F << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X12 = (0x10 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ Z5Y5X6 = (0x11 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X5Y6Z5 = (0x12 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X6Y5Z5 = (0x13 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X1Y5Z5W5 = (0x14 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X4Y4Z4W4 = (0x15 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X5Y1Z5W5 = (0x16 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X5Y5Z1W5 = (0x17 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X5Y5Z5W1 = (0x18 << ColorShift.Component) | ColorBytePerPixel.Bpp16,
+ X8Y8Z8 = (0x19 << ColorShift.Component) | ColorBytePerPixel.Bpp24,
+ X24 = (0x1A << ColorShift.Component) | ColorBytePerPixel.Bpp24,
+ X32 = (0x1C << ColorShift.Component) | ColorBytePerPixel.Bpp32,
+ X16Y16 = (0x1D << ColorShift.Component) | ColorBytePerPixel.Bpp32,
+ X11Y11Z10 = (0x1E << ColorShift.Component) | ColorBytePerPixel.Bpp32,
+ X2Y10Z10W10 = (0x20 << ColorShift.Component) | ColorBytePerPixel.Bpp32,
+ X8Y8Z8W8 = (0x21 << ColorShift.Component) | ColorBytePerPixel.Bpp32,
+ Y10X10 = (0x22 << ColorShift.Component) | ColorBytePerPixel.Bpp32,
+ X10Y10Z10W2 = (0x23 << ColorShift.Component) | ColorBytePerPixel.Bpp32,
+ Y12X12 = (0x24 << ColorShift.Component) | ColorBytePerPixel.Bpp32,
+ X20Y20Z20 = (0x26 << ColorShift.Component) | ColorBytePerPixel.Bpp64,
+ X16Y16Z16W16 = (0x27 << ColorShift.Component) | ColorBytePerPixel.Bpp64,
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorDataType.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorDataType.cs
new file mode 100644
index 00000000..cfa3b018
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorDataType.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ enum ColorDataType
+ {
+ Integer = 0x0 << ColorShift.DataType,
+ Float = 0x1 << ColorShift.DataType,
+ Stencil = 0x2 << ColorShift.DataType
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorFormat.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorFormat.cs
new file mode 100644
index 00000000..227d648a
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorFormat.cs
@@ -0,0 +1,235 @@
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ enum ColorFormat : ulong
+ {
+ NonColor8 = ColorSpace.NonColor | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ NonColor16 = ColorSpace.NonColor | ColorSwizzle.X000 | ColorComponent.X16 | ColorDataType.Integer,
+ NonColor24 = ColorSpace.NonColor | ColorSwizzle.X000 | ColorComponent.X24 | ColorDataType.Integer,
+ NonColor32 = ColorSpace.NonColor | ColorSwizzle.X000 | ColorComponent.X32 | ColorDataType.Integer,
+ X4C4 = ColorSpace.NonColor | ColorSwizzle.Y000 | ColorComponent.Y4X4 | ColorDataType.Integer,
+ A4L4 = ColorSpace.LinearRGBA | ColorSwizzle.YYYX | ColorComponent.Y4X4 | ColorDataType.Integer,
+ A8L8 = ColorSpace.LinearRGBA | ColorSwizzle.YYYX | ColorComponent.Y8X8 | ColorDataType.Integer,
+ Float_A16L16 = ColorSpace.LinearRGBA | ColorSwizzle.YYYX | ColorComponent.X16Y16 | ColorDataType.Float,
+ A1B5G5R5 = ColorSpace.LinearRGBA | ColorSwizzle.WZYX | ColorComponent.X1Y5Z5W5 | ColorDataType.Integer,
+ A4B4G4R4 = ColorSpace.LinearRGBA | ColorSwizzle.WZYX | ColorComponent.X4Y4Z4W4 | ColorDataType.Integer,
+ A5B5G5R1 = ColorSpace.LinearRGBA | ColorSwizzle.WZYX | ColorComponent.X5Y5Z5W1 | ColorDataType.Integer,
+ A2B10G10R10 = ColorSpace.LinearRGBA | ColorSwizzle.WZYX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ A8B8G8R8 = ColorSpace.LinearRGBA | ColorSwizzle.WZYX | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ A16B16G16R16 = ColorSpace.LinearRGBA | ColorSwizzle.WZYX | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ Float_A16B16G16R16 = ColorSpace.LinearRGBA | ColorSwizzle.WZYX | ColorComponent.X16Y16Z16W16 | ColorDataType.Float,
+ A1R5G5B5 = ColorSpace.LinearRGBA | ColorSwizzle.YZWX | ColorComponent.X1Y5Z5W5 | ColorDataType.Integer,
+ A4R4G4B4 = ColorSpace.LinearRGBA | ColorSwizzle.YZWX | ColorComponent.X4Y4Z4W4 | ColorDataType.Integer,
+ A5R1G5B5 = ColorSpace.LinearRGBA | ColorSwizzle.YZWX | ColorComponent.X5Y1Z5W5 | ColorDataType.Integer,
+ A2R10G10B10 = ColorSpace.LinearRGBA | ColorSwizzle.YZWX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ A8R8G8B8 = ColorSpace.LinearRGBA | ColorSwizzle.YZWX | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ A1 = ColorSpace.LinearRGBA | ColorSwizzle._000X | ColorComponent.X1 | ColorDataType.Integer,
+ A2 = ColorSpace.LinearRGBA | ColorSwizzle._000X | ColorComponent.X2 | ColorDataType.Integer,
+ A4 = ColorSpace.LinearRGBA | ColorSwizzle._000X | ColorComponent.X4 | ColorDataType.Integer,
+ A8 = ColorSpace.LinearRGBA | ColorSwizzle._000X | ColorComponent.X8 | ColorDataType.Integer,
+ A16 = ColorSpace.LinearRGBA | ColorSwizzle._000X | ColorComponent.X16 | ColorDataType.Integer,
+ A32 = ColorSpace.LinearRGBA | ColorSwizzle._000X | ColorComponent.X32 | ColorDataType.Integer,
+ Float_A16 = ColorSpace.LinearRGBA | ColorSwizzle._000X | ColorComponent.X16 | ColorDataType.Float,
+ L4A4 = ColorSpace.LinearRGBA | ColorSwizzle.XXXY | ColorComponent.Y4X4 | ColorDataType.Integer,
+ L8A8 = ColorSpace.LinearRGBA | ColorSwizzle.XXXY | ColorComponent.Y8X8 | ColorDataType.Integer,
+ B4G4R4A4 = ColorSpace.LinearRGBA | ColorSwizzle.ZYXW | ColorComponent.X4Y4Z4W4 | ColorDataType.Integer,
+ B5G5R1A5 = ColorSpace.LinearRGBA | ColorSwizzle.ZYXW | ColorComponent.X5Y5Z1W5 | ColorDataType.Integer,
+ B5G5R5A1 = ColorSpace.LinearRGBA | ColorSwizzle.ZYXW | ColorComponent.X5Y5Z5W1 | ColorDataType.Integer,
+ B8G8R8A8 = ColorSpace.LinearRGBA | ColorSwizzle.ZYXW | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ B10G10R10A2 = ColorSpace.LinearRGBA | ColorSwizzle.ZYXW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ R1G5B5A5 = ColorSpace.LinearRGBA | ColorSwizzle.XYZW | ColorComponent.X1Y5Z5W5 | ColorDataType.Integer,
+ R4G4B4A4 = ColorSpace.LinearRGBA | ColorSwizzle.XYZW | ColorComponent.X4Y4Z4W4 | ColorDataType.Integer,
+ R5G5B5A1 = ColorSpace.LinearRGBA | ColorSwizzle.XYZW | ColorComponent.X5Y5Z5W1 | ColorDataType.Integer,
+ R8G8B8A8 = ColorSpace.LinearRGBA | ColorSwizzle.XYZW | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ R10G10B10A2 = ColorSpace.LinearRGBA | ColorSwizzle.XYZW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ L1 = ColorSpace.LinearRGBA | ColorSwizzle.XXX1 | ColorComponent.X1 | ColorDataType.Integer,
+ L2 = ColorSpace.LinearRGBA | ColorSwizzle.XXX1 | ColorComponent.X2 | ColorDataType.Integer,
+ L4 = ColorSpace.LinearRGBA | ColorSwizzle.XXX1 | ColorComponent.X4 | ColorDataType.Integer,
+ L8 = ColorSpace.LinearRGBA | ColorSwizzle.XXX1 | ColorComponent.X8 | ColorDataType.Integer,
+ L16 = ColorSpace.LinearRGBA | ColorSwizzle.XXX1 | ColorComponent.X16 | ColorDataType.Integer,
+ L32 = ColorSpace.LinearRGBA | ColorSwizzle.XXX1 | ColorComponent.X32 | ColorDataType.Integer,
+ Float_L16 = ColorSpace.LinearRGBA | ColorSwizzle.XXX1 | ColorComponent.X16 | ColorDataType.Float,
+ B5G6R5 = ColorSpace.LinearRGBA | ColorSwizzle.ZYX1 | ColorComponent.X5Y6Z5 | ColorDataType.Integer,
+ B6G5R5 = ColorSpace.LinearRGBA | ColorSwizzle.ZYX1 | ColorComponent.X6Y5Z5 | ColorDataType.Integer,
+ B5G5R5X1 = ColorSpace.LinearRGBA | ColorSwizzle.ZYX1 | ColorComponent.X5Y5Z5W1 | ColorDataType.Integer,
+ B8_G8_R8 = ColorSpace.LinearRGBA | ColorSwizzle.ZYX1 | ColorComponent.X8Y8Z8 | ColorDataType.Integer,
+ B8G8R8X8 = ColorSpace.LinearRGBA | ColorSwizzle.ZYX1 | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ Float_B10G11R11 = ColorSpace.LinearRGBA | ColorSwizzle.ZYX1 | ColorComponent.X11Y11Z10 | ColorDataType.Float,
+ X1B5G5R5 = ColorSpace.LinearRGBA | ColorSwizzle.WZY1 | ColorComponent.X1Y5Z5W5 | ColorDataType.Integer,
+ X8B8G8R8 = ColorSpace.LinearRGBA | ColorSwizzle.WZY1 | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ X16B16G16R16 = ColorSpace.LinearRGBA | ColorSwizzle.WZY1 | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ Float_X16B16G16R16 = ColorSpace.LinearRGBA | ColorSwizzle.WZY1 | ColorComponent.X16Y16Z16W16 | ColorDataType.Float,
+ R3G3B2 = ColorSpace.LinearRGBA | ColorSwizzle.XYZ1 | ColorComponent.X3Y3Z2 | ColorDataType.Integer,
+ R5G5B6 = ColorSpace.LinearRGBA | ColorSwizzle.XYZ1 | ColorComponent.Z5Y5X6 | ColorDataType.Integer,
+ R5G6B5 = ColorSpace.LinearRGBA | ColorSwizzle.XYZ1 | ColorComponent.X5Y6Z5 | ColorDataType.Integer,
+ R5G5B5X1 = ColorSpace.LinearRGBA | ColorSwizzle.XYZ1 | ColorComponent.X5Y5Z5W1 | ColorDataType.Integer,
+ R8_G8_B8 = ColorSpace.LinearRGBA | ColorSwizzle.XYZ1 | ColorComponent.X8Y8Z8 | ColorDataType.Integer,
+ R8G8B8X8 = ColorSpace.LinearRGBA | ColorSwizzle.XYZ1 | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ X1R5G5B5 = ColorSpace.LinearRGBA | ColorSwizzle.YZW1 | ColorComponent.X1Y5Z5W5 | ColorDataType.Integer,
+ X8R8G8B8 = ColorSpace.LinearRGBA | ColorSwizzle.YZW1 | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ RG8 = ColorSpace.LinearRGBA | ColorSwizzle.XY01 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ R16G16 = ColorSpace.LinearRGBA | ColorSwizzle.XY01 | ColorComponent.X16Y16 | ColorDataType.Integer,
+ Float_R16G16 = ColorSpace.LinearRGBA | ColorSwizzle.XY01 | ColorComponent.X16Y16 | ColorDataType.Float,
+ R8 = ColorSpace.LinearRGBA | ColorSwizzle.X001 | ColorComponent.X8 | ColorDataType.Integer,
+ R16 = ColorSpace.LinearRGBA | ColorSwizzle.X001 | ColorComponent.X16 | ColorDataType.Integer,
+ Float_R16 = ColorSpace.LinearRGBA | ColorSwizzle.X001 | ColorComponent.X16 | ColorDataType.Float,
+ A2B10G10R10_sRGB = ColorSpace.SRGB | ColorSwizzle.WZYX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ A8B8G8R8_sRGB = ColorSpace.SRGB | ColorSwizzle.WZYX | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ A16B16G16R16_sRGB = ColorSpace.SRGB | ColorSwizzle.WZYX | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ A2R10G10B10_sRGB = ColorSpace.SRGB | ColorSwizzle.YZWX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ B10G10R10A2_sRGB = ColorSpace.SRGB | ColorSwizzle.ZYXW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ R10G10B10A2_sRGB = ColorSpace.SRGB | ColorSwizzle.XYZW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ X8B8G8R8_sRGB = ColorSpace.SRGB | ColorSwizzle.WZY1 | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ X16B16G16R16_sRGB = ColorSpace.SRGB | ColorSwizzle.WZY1 | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ A2B10G10R10_709 = ColorSpace.RGB709 | ColorSwizzle.WZYX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ A8B8G8R8_709 = ColorSpace.RGB709 | ColorSwizzle.WZYX | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ A16B16G16R16_709 = ColorSpace.RGB709 | ColorSwizzle.WZYX | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ A2R10G10B10_709 = ColorSpace.RGB709 | ColorSwizzle.YZWX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ B10G10R10A2_709 = ColorSpace.RGB709 | ColorSwizzle.ZYXW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ R10G10B10A2_709 = ColorSpace.RGB709 | ColorSwizzle.XYZW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ X8B8G8R8_709 = ColorSpace.RGB709 | ColorSwizzle.WZY1 | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ X16B16G16R16_709 = ColorSpace.RGB709 | ColorSwizzle.WZY1 | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ A2B10G10R10_709_Linear = ColorSpace.LinearRGB709 | ColorSwizzle.WZYX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ A8B8G8R8_709_Linear = ColorSpace.LinearRGB709 | ColorSwizzle.WZYX | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ A16B16G16R16_709_Linear = ColorSpace.LinearRGB709 | ColorSwizzle.WZYX | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ A2R10G10B10_709_Linear = ColorSpace.LinearRGB709 | ColorSwizzle.YZWX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ B10G10R10A2_709_Linear = ColorSpace.LinearRGB709 | ColorSwizzle.ZYXW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ R10G10B10A2_709_Linear = ColorSpace.LinearRGB709 | ColorSwizzle.XYZW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ X8B8G8R8_709_Linear = ColorSpace.LinearRGB709 | ColorSwizzle.WZY1 | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ X16B16G16R16_709_Linear = ColorSpace.LinearRGB709 | ColorSwizzle.WZY1 | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ Float_A16B16G16R16_scRGB_Linear = ColorSpace.LinearScRGB | ColorSwizzle.WZYX | ColorComponent.X16Y16Z16W16 | ColorDataType.Float,
+ A2B10G10R10_2020 = ColorSpace.RGB2020 | ColorSwizzle.WZYX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ A8B8G8R8_2020 = ColorSpace.RGB2020 | ColorSwizzle.WZYX | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ A16B16G16R16_2020 = ColorSpace.RGB2020 | ColorSwizzle.WZYX | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ A2R10G10B10_2020 = ColorSpace.RGB2020 | ColorSwizzle.YZWX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ B10G10R10A2_2020 = ColorSpace.RGB2020 | ColorSwizzle.ZYXW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ R10G10B10A2_2020 = ColorSpace.RGB2020 | ColorSwizzle.XYZW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ X8B8G8R8_2020 = ColorSpace.RGB2020 | ColorSwizzle.WZY1 | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ X16B16G16R16_2020 = ColorSpace.RGB2020 | ColorSwizzle.WZY1 | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ A2B10G10R10_2020_Linear = ColorSpace.LinearRGB2020 | ColorSwizzle.WZYX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ A8B8G8R8_2020_Linear = ColorSpace.LinearRGB2020 | ColorSwizzle.WZYX | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ A16B16G16R16_2020_Linear = ColorSpace.LinearRGB2020 | ColorSwizzle.WZYX | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ Float_A16B16G16R16_2020_Linear = ColorSpace.LinearRGB2020 | ColorSwizzle.WZYX | ColorComponent.X16Y16Z16W16 | ColorDataType.Float,
+ A2R10G10B10_2020_Linear = ColorSpace.LinearRGB2020 | ColorSwizzle.YZWX | ColorComponent.X2Y10Z10W10 | ColorDataType.Integer,
+ B10G10R10A2_2020_Linear = ColorSpace.LinearRGB2020 | ColorSwizzle.ZYXW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ R10G10B10A2_2020_Linear = ColorSpace.LinearRGB2020 | ColorSwizzle.XYZW | ColorComponent.X10Y10Z10W2 | ColorDataType.Integer,
+ X8B8G8R8_2020_Linear = ColorSpace.LinearRGB2020 | ColorSwizzle.WZY1 | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ X16B16G16R16_2020_Linear = ColorSpace.LinearRGB2020 | ColorSwizzle.WZY1 | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ Float_A16B16G16R16_2020_PQ = ColorSpace.RGB2020_PQ | ColorSwizzle.WZYX | ColorComponent.X16Y16Z16W16 | ColorDataType.Float,
+ A4I4 = ColorSpace.ColorIndex | ColorSwizzle.X00X | ColorComponent.Y4X4 | ColorDataType.Integer,
+ A8I8 = ColorSpace.ColorIndex | ColorSwizzle.X00X | ColorComponent.Y8X8 | ColorDataType.Integer,
+ I4A4 = ColorSpace.ColorIndex | ColorSwizzle.X00Y | ColorComponent.Y4X4 | ColorDataType.Integer,
+ I8A8 = ColorSpace.ColorIndex | ColorSwizzle.X00Y | ColorComponent.Y8X8 | ColorDataType.Integer,
+ I1 = ColorSpace.ColorIndex | ColorSwizzle.X000 | ColorComponent.X1 | ColorDataType.Integer,
+ I2 = ColorSpace.ColorIndex | ColorSwizzle.X000 | ColorComponent.X2 | ColorDataType.Integer,
+ I4 = ColorSpace.ColorIndex | ColorSwizzle.X000 | ColorComponent.X4 | ColorDataType.Integer,
+ I8 = ColorSpace.ColorIndex | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ A8Y8U8V8 = ColorSpace.YCbCr601 | ColorSwizzle.YZWX | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ A16Y16U16V16 = ColorSpace.YCbCr601 | ColorSwizzle.YZWX | ColorComponent.X16Y16Z16W16 | ColorDataType.Integer,
+ Y8U8V8A8 = ColorSpace.YCbCr601 | ColorSwizzle.XYZW | ColorComponent.X8Y8Z8W8 | ColorDataType.Integer,
+ V8_U8 = ColorSpace.YCbCr601 | ColorSwizzle._0YX0 | ColorComponent.X8Y8 | ColorDataType.Integer,
+ V8U8 = ColorSpace.YCbCr601 | ColorSwizzle._0YX0 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ V10U10 = ColorSpace.YCbCr601 | ColorSwizzle._0ZY0 | ColorComponent.Y10X10 | ColorDataType.Integer,
+ V12U12 = ColorSpace.YCbCr601 | ColorSwizzle._0ZY0 | ColorComponent.Y12X12 | ColorDataType.Integer,
+ V8 = ColorSpace.YCbCr601 | ColorSwizzle._00X0 | ColorComponent.X8 | ColorDataType.Integer,
+ V10 = ColorSpace.YCbCr601 | ColorSwizzle._00X0 | ColorComponent.X10 | ColorDataType.Integer,
+ V12 = ColorSpace.YCbCr601 | ColorSwizzle._00X0 | ColorComponent.X12 | ColorDataType.Integer,
+ U8_V8 = ColorSpace.YCbCr601 | ColorSwizzle._0XY0 | ColorComponent.X8Y8 | ColorDataType.Integer,
+ U8V8 = ColorSpace.YCbCr601 | ColorSwizzle._0XY0 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ U10V10 = ColorSpace.YCbCr601 | ColorSwizzle._0XZ0 | ColorComponent.Y10X10 | ColorDataType.Integer,
+ U12V12 = ColorSpace.YCbCr601 | ColorSwizzle._0XZ0 | ColorComponent.Y12X12 | ColorDataType.Integer,
+ U8 = ColorSpace.YCbCr601 | ColorSwizzle._0X00 | ColorComponent.X8 | ColorDataType.Integer,
+ U10 = ColorSpace.YCbCr601 | ColorSwizzle._0X00 | ColorComponent.X10 | ColorDataType.Integer,
+ U12 = ColorSpace.YCbCr601 | ColorSwizzle._0X00 | ColorComponent.X12 | ColorDataType.Integer,
+ Y8 = ColorSpace.YCbCr601 | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ Y10 = ColorSpace.YCbCr601 | ColorSwizzle.X000 | ColorComponent.X10 | ColorDataType.Integer,
+ Y12 = ColorSpace.YCbCr601 | ColorSwizzle.X000 | ColorComponent.X12 | ColorDataType.Integer,
+ YVYU = ColorSpace.YCbCr601 | ColorSwizzle.XZY1 | ColorComponent.X8Y8X8Z8 | ColorDataType.Integer,
+ VYUY = ColorSpace.YCbCr601 | ColorSwizzle.XZY1 | ColorComponent.Y8X8Z8X8 | ColorDataType.Integer,
+ UYVY = ColorSpace.YCbCr601 | ColorSwizzle.XYZ1 | ColorComponent.Y8X8Z8X8 | ColorDataType.Integer,
+ YUYV = ColorSpace.YCbCr601 | ColorSwizzle.XYZ1 | ColorComponent.X8Y8X8Z8 | ColorDataType.Integer,
+ Y8_U8_V8 = ColorSpace.YCbCr601 | ColorSwizzle.XYZ1 | ColorComponent.X8Y8Z8 | ColorDataType.Integer,
+ V8_U8_RR = ColorSpace.YCbCr601_RR | ColorSwizzle._0YX0 | ColorComponent.X8Y8 | ColorDataType.Integer,
+ V8U8_RR = ColorSpace.YCbCr601_RR | ColorSwizzle._0YX0 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ V8_RR = ColorSpace.YCbCr601_RR | ColorSwizzle._00X0 | ColorComponent.X8 | ColorDataType.Integer,
+ U8_V8_RR = ColorSpace.YCbCr601_RR | ColorSwizzle._0XY0 | ColorComponent.X8Y8 | ColorDataType.Integer,
+ U8V8_RR = ColorSpace.YCbCr601_RR | ColorSwizzle._0XY0 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ U8_RR = ColorSpace.YCbCr601_RR | ColorSwizzle._0X00 | ColorComponent.X8 | ColorDataType.Integer,
+ Y8_RR = ColorSpace.YCbCr601_RR | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ V8_U8_ER = ColorSpace.YCbCr601_ER | ColorSwizzle._0YX0 | ColorComponent.X8Y8 | ColorDataType.Integer,
+ V8U8_ER = ColorSpace.YCbCr601_ER | ColorSwizzle._0YX0 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ V8_ER = ColorSpace.YCbCr601_ER | ColorSwizzle._00X0 | ColorComponent.X8 | ColorDataType.Integer,
+ U8_V8_ER = ColorSpace.YCbCr601_ER | ColorSwizzle._0XY0 | ColorComponent.X8Y8 | ColorDataType.Integer,
+ U8V8_ER = ColorSpace.YCbCr601_ER | ColorSwizzle._0XY0 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ U8_ER = ColorSpace.YCbCr601_ER | ColorSwizzle._0X00 | ColorComponent.X8 | ColorDataType.Integer,
+ Y8_ER = ColorSpace.YCbCr601_ER | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ V8_U8_709 = ColorSpace.YCbCr709 | ColorSwizzle._0YX0 | ColorComponent.X8Y8 | ColorDataType.Integer,
+ V8U8_709 = ColorSpace.YCbCr709 | ColorSwizzle._0YX0 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ V10U10_709 = ColorSpace.YCbCr709 | ColorSwizzle._0ZY0 | ColorComponent.Y10X10 | ColorDataType.Integer,
+ V12U12_709 = ColorSpace.YCbCr709 | ColorSwizzle._0ZY0 | ColorComponent.Y12X12 | ColorDataType.Integer,
+ V8_709 = ColorSpace.YCbCr709 | ColorSwizzle._00X0 | ColorComponent.X8 | ColorDataType.Integer,
+ V10_709 = ColorSpace.YCbCr709 | ColorSwizzle._00X0 | ColorComponent.X10 | ColorDataType.Integer,
+ V12_709 = ColorSpace.YCbCr709 | ColorSwizzle._00X0 | ColorComponent.X12 | ColorDataType.Integer,
+ U8_V8_709 = ColorSpace.YCbCr709 | ColorSwizzle._0XY0 | ColorComponent.X8Y8 | ColorDataType.Integer,
+ U8V8_709 = ColorSpace.YCbCr709 | ColorSwizzle._0XY0 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ U10V10_709 = ColorSpace.YCbCr709 | ColorSwizzle._0XZ0 | ColorComponent.Y10X10 | ColorDataType.Integer,
+ U12V12_709 = ColorSpace.YCbCr709 | ColorSwizzle._0XZ0 | ColorComponent.Y12X12 | ColorDataType.Integer,
+ U8_709 = ColorSpace.YCbCr709 | ColorSwizzle._0X00 | ColorComponent.X8 | ColorDataType.Integer,
+ U10_709 = ColorSpace.YCbCr709 | ColorSwizzle._0X00 | ColorComponent.X10 | ColorDataType.Integer,
+ U12_709 = ColorSpace.YCbCr709 | ColorSwizzle._0X00 | ColorComponent.X12 | ColorDataType.Integer,
+ Y8_709 = ColorSpace.YCbCr709 | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ Y10_709 = ColorSpace.YCbCr709 | ColorSwizzle.X000 | ColorComponent.X10 | ColorDataType.Integer,
+ Y12_709 = ColorSpace.YCbCr709 | ColorSwizzle.X000 | ColorComponent.X12 | ColorDataType.Integer,
+ V8_U8_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0YX0 | ColorComponent.X8Y8 | ColorDataType.Integer,
+ V8U8_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0YX0 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ V10U10_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0ZY0 | ColorComponent.Y10X10 | ColorDataType.Integer,
+ V12U12_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0ZY0 | ColorComponent.Y12X12 | ColorDataType.Integer,
+ V8_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._00X0 | ColorComponent.X8 | ColorDataType.Integer,
+ V10_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._00X0 | ColorComponent.X10 | ColorDataType.Integer,
+ V12_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._00X0 | ColorComponent.X12 | ColorDataType.Integer,
+ U8_V8_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0XY0 | ColorComponent.X8Y8 | ColorDataType.Integer,
+ U8V8_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0XY0 | ColorComponent.Y8X8 | ColorDataType.Integer,
+ U10V10_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0XZ0 | ColorComponent.Y10X10 | ColorDataType.Integer,
+ U12V12_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0XZ0 | ColorComponent.Y12X12 | ColorDataType.Integer,
+ U8_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0X00 | ColorComponent.X8 | ColorDataType.Integer,
+ U10_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0X00 | ColorComponent.X10 | ColorDataType.Integer,
+ U12_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle._0X00 | ColorComponent.X12 | ColorDataType.Integer,
+ Y8_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ Y10_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle.X000 | ColorComponent.X10 | ColorDataType.Integer,
+ Y12_709_ER = ColorSpace.YCbCr709_ER | ColorSwizzle.X000 | ColorComponent.X12 | ColorDataType.Integer,
+ V10U10_2020 = ColorSpace.YCbCr709_ER | ColorSwizzle._0ZY0 | ColorComponent.Y10X10 | ColorDataType.Integer,
+ V12U12_2020 = ColorSpace.YCbCr709_ER | ColorSwizzle._0ZY0 | ColorComponent.Y12X12 | ColorDataType.Integer,
+ V10_2020 = ColorSpace.YCbCr709_ER | ColorSwizzle._00X0 | ColorComponent.X10 | ColorDataType.Integer,
+ V12_2020 = ColorSpace.YCbCr709_ER | ColorSwizzle._00X0 | ColorComponent.X12 | ColorDataType.Integer,
+ U10V10_2020 = ColorSpace.YCbCr709_ER | ColorSwizzle._0XZ0 | ColorComponent.Y10X10 | ColorDataType.Integer,
+ U12V12_2020 = ColorSpace.YCbCr709_ER | ColorSwizzle._0XZ0 | ColorComponent.Y12X12 | ColorDataType.Integer,
+ U10_2020 = ColorSpace.YCbCr709_ER | ColorSwizzle._0X00 | ColorComponent.X10 | ColorDataType.Integer,
+ U12_2020 = ColorSpace.YCbCr709_ER | ColorSwizzle._0X00 | ColorComponent.X12 | ColorDataType.Integer,
+ Y10_2020 = ColorSpace.YCbCr709_ER | ColorSwizzle.X000 | ColorComponent.X10 | ColorDataType.Integer,
+ Y12_2020 = ColorSpace.YCbCr709_ER | ColorSwizzle.X000 | ColorComponent.X12 | ColorDataType.Integer,
+ Bayer8RGGB = ColorSpace.BayerRGGB | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ Bayer16RGGB = ColorSpace.BayerRGGB | ColorSwizzle.X000 | ColorComponent.X16 | ColorDataType.Integer,
+ BayerS16RGGB = ColorSpace.BayerRGGB | ColorSwizzle.X000 | ColorComponent.X16 | ColorDataType.Stencil,
+ X2Bayer14RGGB = ColorSpace.BayerRGGB | ColorSwizzle.Y000 | ColorComponent.Y2X14 | ColorDataType.Integer,
+ X4Bayer12RGGB = ColorSpace.BayerRGGB | ColorSwizzle.Y000 | ColorComponent.Y4X12 | ColorDataType.Integer,
+ X6Bayer10RGGB = ColorSpace.BayerRGGB | ColorSwizzle.Y000 | ColorComponent.Y6X10 | ColorDataType.Integer,
+ Bayer8BGGR = ColorSpace.BayerBGGR | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ Bayer16BGGR = ColorSpace.BayerBGGR | ColorSwizzle.X000 | ColorComponent.X16 | ColorDataType.Integer,
+ BayerS16BGGR = ColorSpace.BayerBGGR | ColorSwizzle.X000 | ColorComponent.X16 | ColorDataType.Stencil,
+ X2Bayer14BGGR = ColorSpace.BayerBGGR | ColorSwizzle.Y000 | ColorComponent.Y2X14 | ColorDataType.Integer,
+ X4Bayer12BGGR = ColorSpace.BayerBGGR | ColorSwizzle.Y000 | ColorComponent.Y4X12 | ColorDataType.Integer,
+ X6Bayer10BGGR = ColorSpace.BayerBGGR | ColorSwizzle.Y000 | ColorComponent.Y6X10 | ColorDataType.Integer,
+ Bayer8GRBG = ColorSpace.BayerGRBG | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ Bayer16GRBG = ColorSpace.BayerGRBG | ColorSwizzle.X000 | ColorComponent.X16 | ColorDataType.Integer,
+ BayerS16GRBG = ColorSpace.BayerGRBG | ColorSwizzle.X000 | ColorComponent.X16 | ColorDataType.Stencil,
+ X2Bayer14GRBG = ColorSpace.BayerGRBG | ColorSwizzle.Y000 | ColorComponent.Y2X14 | ColorDataType.Integer,
+ X4Bayer12GRBG = ColorSpace.BayerGRBG | ColorSwizzle.Y000 | ColorComponent.Y4X12 | ColorDataType.Integer,
+ X6Bayer10GRBG = ColorSpace.BayerGRBG | ColorSwizzle.Y000 | ColorComponent.Y6X10 | ColorDataType.Integer,
+ Bayer8GBRG = ColorSpace.BayerGBRG | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
+ Bayer16GBRG = ColorSpace.BayerGBRG | ColorSwizzle.X000 | ColorComponent.X16 | ColorDataType.Integer,
+ BayerS16GBRG = ColorSpace.BayerGBRG | ColorSwizzle.X000 | ColorComponent.X16 | ColorDataType.Stencil,
+ X2Bayer14GBRG = ColorSpace.BayerGBRG | ColorSwizzle.Y000 | ColorComponent.Y2X14 | ColorDataType.Integer,
+ X4Bayer12GBRG = ColorSpace.BayerGBRG | ColorSwizzle.Y000 | ColorComponent.Y4X12 | ColorDataType.Integer,
+ X6Bayer10GBRG = ColorSpace.BayerGBRG | ColorSwizzle.Y000 | ColorComponent.Y6X10 | ColorDataType.Integer,
+ XYZ = ColorSpace.XYZ | ColorSwizzle.XYZ1 | ColorComponent.X20Y20Z20 | ColorDataType.Float,
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorShift.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorShift.cs
new file mode 100644
index 00000000..3ad216a8
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorShift.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ class ColorShift
+ {
+ public const int Swizzle = 16;
+ public const int DataType = 14;
+ public const int Space = 32;
+ public const int Component = 8;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSpace.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSpace.cs
new file mode 100644
index 00000000..9003a00b
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSpace.cs
@@ -0,0 +1,33 @@
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ enum ColorSpace : ulong
+ {
+ NonColor = 0x0L << ColorShift.Space,
+ LinearRGBA = 0x1L << ColorShift.Space,
+ SRGB = 0x2L << ColorShift.Space,
+
+ RGB709 = 0x3L << ColorShift.Space,
+ LinearRGB709 = 0x4L << ColorShift.Space,
+
+ LinearScRGB = 0x5L << ColorShift.Space,
+
+ RGB2020 = 0x6L << ColorShift.Space,
+ LinearRGB2020 = 0x7L << ColorShift.Space,
+ RGB2020_PQ = 0x8L << ColorShift.Space,
+
+ ColorIndex = 0x9L << ColorShift.Space,
+
+ YCbCr601 = 0xAL << ColorShift.Space,
+ YCbCr601_RR = 0xBL << ColorShift.Space,
+ YCbCr601_ER = 0xCL << ColorShift.Space,
+ YCbCr709 = 0xDL << ColorShift.Space,
+ YCbCr709_ER = 0xEL << ColorShift.Space,
+
+ BayerRGGB = 0x10L << ColorShift.Space,
+ BayerBGGR = 0x11L << ColorShift.Space,
+ BayerGRBG = 0x12L << ColorShift.Space,
+ BayerGBRG = 0x13L << ColorShift.Space,
+
+ XYZ = 0x14L << ColorShift.Space,
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSwizzle.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSwizzle.cs
new file mode 100644
index 00000000..4c1370c7
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSwizzle.cs
@@ -0,0 +1,31 @@
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ enum ColorSwizzle
+ {
+ XYZW = 0x688 << ColorShift.Swizzle,
+ ZYXW = 0x60a << ColorShift.Swizzle,
+ WZYX = 0x053 << ColorShift.Swizzle,
+ YZWX = 0x0d1 << ColorShift.Swizzle,
+ XYZ1 = 0xa88 << ColorShift.Swizzle,
+ YZW1 = 0xad1 << ColorShift.Swizzle,
+ XXX1 = 0xa00 << ColorShift.Swizzle,
+ XZY1 = 0xa50 << ColorShift.Swizzle,
+ ZYX1 = 0xa0a << ColorShift.Swizzle,
+ WZY1 = 0xa53 << ColorShift.Swizzle,
+ X000 = 0x920 << ColorShift.Swizzle,
+ Y000 = 0x921 << ColorShift.Swizzle,
+ XY01 = 0xb08 << ColorShift.Swizzle,
+ X001 = 0xb20 << ColorShift.Swizzle,
+ X00X = 0x121 << ColorShift.Swizzle,
+ X00Y = 0x320 << ColorShift.Swizzle,
+ _0YX0 = 0x80c << ColorShift.Swizzle,
+ _0ZY0 = 0x814 << ColorShift.Swizzle,
+ _0XZ0 = 0x884 << ColorShift.Swizzle,
+ _0X00 = 0x904 << ColorShift.Swizzle,
+ _00X0 = 0x824 << ColorShift.Swizzle,
+ _000X = 0x124 << ColorShift.Swizzle,
+ _0XY0 = 0x844 << ColorShift.Swizzle,
+ XXXY = 0x200 << ColorShift.Swizzle,
+ YYYX = 0x049 << ColorShift.Swizzle
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Fence.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Fence.cs
new file mode 100644
index 00000000..356a1232
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Fence.cs
@@ -0,0 +1,11 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ [StructLayout(LayoutKind.Sequential, Size = 0x8)]
+ struct Fence
+ {
+ public int Id;
+ public int Value;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GbpBuffer.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GbpBuffer.cs
new file mode 100644
index 00000000..b93947fd
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GbpBuffer.cs
@@ -0,0 +1,37 @@
+using Ryujinx.Common;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ struct GbpBuffer
+ {
+ public GraphicBufferHeader Header { get; private set; }
+ public NvGraphicBuffer Buffer { get; private set; }
+
+ public int Size => Marshal.SizeOf<NvGraphicBuffer>() + Marshal.SizeOf<GraphicBufferHeader>();
+
+ public GbpBuffer(BinaryReader reader)
+ {
+ Header = reader.ReadStruct<GraphicBufferHeader>();
+
+ // ignore fds
+ // TODO: check if that is used in official implementation
+ reader.BaseStream.Position += Header.FdsCount * 4;
+
+ if (Header.IntsCount != 0x51)
+ {
+ throw new NotImplementedException($"Unexpected Graphic Buffer ints count (expected 0x51, found 0x{Header.IntsCount:x}");
+ }
+
+ Buffer = reader.ReadStruct<NvGraphicBuffer>();
+ }
+
+ public void Write(BinaryWriter writer)
+ {
+ writer.WriteStruct(Header);
+ writer.WriteStruct(Buffer);
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBufferHeader.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBufferHeader.cs
new file mode 100644
index 00000000..fae0002f
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBufferHeader.cs
@@ -0,0 +1,21 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ [StructLayout(LayoutKind.Sequential, Size = 0x28)]
+ struct GraphicBufferHeader
+ {
+ public int Magic;
+ public int Width;
+ public int Height;
+ public int Stride;
+ public int Format;
+ public int Usage;
+
+ public int Pid;
+ public int RefCount;
+
+ public int FdsCount;
+ public int IntsCount;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/HalTransform.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/HalTransform.cs
new file mode 100644
index 00000000..a1efed0b
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/HalTransform.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ [Flags]
+ enum HalTransform
+ {
+ FlipX = 1,
+ FlipY = 2,
+ Rotate90 = 4,
+ Rotate180 = FlipX | FlipY,
+ Rotate270 = Rotate90 | Rotate180
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/MultiFence.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/MultiFence.cs
new file mode 100644
index 00000000..97ad3e20
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/MultiFence.cs
@@ -0,0 +1,23 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ [StructLayout(LayoutKind.Explicit, Size = 0x24)]
+ struct MultiFence
+ {
+ [FieldOffset(0x0)]
+ public int FenceCount;
+
+ [FieldOffset(0x4)]
+ public Fence Fence0;
+
+ [FieldOffset(0xC)]
+ public Fence Fence1;
+
+ [FieldOffset(0x14)]
+ public Fence Fence2;
+
+ [FieldOffset(0x1C)]
+ public Fence Fence3;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBuffer.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBuffer.cs
new file mode 100644
index 00000000..9a52245c
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBuffer.cs
@@ -0,0 +1,41 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ [StructLayout(LayoutKind.Explicit, Size = 0x144)]
+ struct NvGraphicBuffer
+ {
+ [FieldOffset(0x4)]
+ public int NvMapId;
+
+ [FieldOffset(0xC)]
+ public int Magic;
+
+ [FieldOffset(0x10)]
+ public int Pid;
+
+ [FieldOffset(0x14)]
+ public int Type;
+
+ [FieldOffset(0x18)]
+ public int Usage;
+
+ [FieldOffset(0x1C)]
+ public int PixelFormat;
+
+ [FieldOffset(0x20)]
+ public int ExternalPixelFormat;
+
+ [FieldOffset(0x24)]
+ public int Stride;
+
+ [FieldOffset(0x28)]
+ public int FrameBufferSize;
+
+ [FieldOffset(0x2C)]
+ public int PlanesCount;
+
+ [FieldOffset(0x34)]
+ public NvGraphicBufferSurfaceArray Surfaces;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurface.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurface.cs
new file mode 100644
index 00000000..e084bc73
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurface.cs
@@ -0,0 +1,44 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ [StructLayout(LayoutKind.Explicit, Size = 0x58)]
+ struct NvGraphicBufferSurface
+ {
+ [FieldOffset(0)]
+ public uint Width;
+
+ [FieldOffset(0x4)]
+ public uint Height;
+
+ [FieldOffset(0x8)]
+ public ColorFormat ColorFormat;
+
+ [FieldOffset(0x10)]
+ public int Layout;
+
+ [FieldOffset(0x14)]
+ public int Pitch;
+
+ [FieldOffset(0x18)]
+ public int NvMapHandle;
+
+ [FieldOffset(0x1C)]
+ public int Offset;
+
+ [FieldOffset(0x20)]
+ public int Kind;
+
+ [FieldOffset(0x24)]
+ public int BlockHeightLog2;
+
+ [FieldOffset(0x28)]
+ public int ScanFormat;
+
+ [FieldOffset(0x30)]
+ public long Flags;
+
+ [FieldOffset(0x38)]
+ public long Size;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurfaceArray.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurfaceArray.cs
new file mode 100644
index 00000000..7327b559
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurfaceArray.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ [StructLayout(LayoutKind.Explicit)]
+ struct NvGraphicBufferSurfaceArray
+ {
+ [FieldOffset(0x0)]
+ private NvGraphicBufferSurface Surface0;
+
+ [FieldOffset(0x58)]
+ private NvGraphicBufferSurface Surface1;
+
+ [FieldOffset(0xb0)]
+ private NvGraphicBufferSurface Surface2;
+
+ public NvGraphicBufferSurface this[int index]
+ {
+ get
+ {
+ if (index == 0)
+ {
+ return Surface0;
+ }
+ else if (index == 1)
+ {
+ return Surface1;
+ }
+ else if (index == 2)
+ {
+ return Surface2;
+ }
+
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/QueueBufferObject.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/QueueBufferObject.cs
new file mode 100644
index 00000000..684f856a
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/QueueBufferObject.cs
@@ -0,0 +1,35 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ [StructLayout(LayoutKind.Explicit)]
+ struct QueueBufferObject
+ {
+ [FieldOffset(0x0)]
+ public long Timestamp;
+
+ [FieldOffset(0x8)]
+ public int IsAutoTimestamp;
+
+ [FieldOffset(0xC)]
+ public Rect Crop;
+
+ [FieldOffset(0x1C)]
+ public int ScalingMode;
+
+ [FieldOffset(0x20)]
+ public HalTransform Transform;
+
+ [FieldOffset(0x24)]
+ public int StickyTransform;
+
+ [FieldOffset(0x28)]
+ public int Unknown;
+
+ [FieldOffset(0x2C)]
+ public int SwapInterval;
+
+ [FieldOffset(0x30)]
+ public MultiFence Fence;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Rect.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Rect.cs
new file mode 100644
index 00000000..c2f51eea
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Rect.cs
@@ -0,0 +1,13 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ [StructLayout(LayoutKind.Sequential, Size = 0x10)]
+ struct Rect
+ {
+ public int Top;
+ public int Left;
+ public int Right;
+ public int Bottom;
+ }
+} \ No newline at end of file