From a63001a3f9f4588ba7f8f6ffedec5ad4c0cf5ed8 Mon Sep 17 00:00:00 2001 From: Alessandro Proto Date: Sat, 21 Jan 2023 11:40:39 +0100 Subject: [PATCH] FAST GPU BUFFERS!!!!! --- Capy64/LuaRuntime/Libraries/FileSystem.cs | 2 +- Capy64/LuaRuntime/Libraries/GPU.cs | 58 +++++++++ Capy64/LuaRuntime/Libraries/HTTP.cs | 2 +- Capy64/LuaRuntime/Objects/GPUBuffer.cs | 117 ++++++++++++++++++ .../Handlers/BinaryReadHandle.cs | 2 +- .../Handlers/BinaryWriteHandle.cs | 2 +- .../{ => Objects}/Handlers/IHandle.cs | 2 +- .../{ => Objects}/Handlers/ReadHandle.cs | 2 +- .../{ => Objects}/Handlers/WebSocketHandle.cs | 2 +- .../{ => Objects}/Handlers/WriteHandle.cs | 2 +- 10 files changed, 183 insertions(+), 8 deletions(-) create mode 100644 Capy64/LuaRuntime/Objects/GPUBuffer.cs rename Capy64/LuaRuntime/{ => Objects}/Handlers/BinaryReadHandle.cs (99%) rename Capy64/LuaRuntime/{ => Objects}/Handlers/BinaryWriteHandle.cs (99%) rename Capy64/LuaRuntime/{ => Objects}/Handlers/IHandle.cs (68%) rename Capy64/LuaRuntime/{ => Objects}/Handlers/ReadHandle.cs (98%) rename Capy64/LuaRuntime/{ => Objects}/Handlers/WebSocketHandle.cs (98%) rename Capy64/LuaRuntime/{ => Objects}/Handlers/WriteHandle.cs (98%) diff --git a/Capy64/LuaRuntime/Libraries/FileSystem.cs b/Capy64/LuaRuntime/Libraries/FileSystem.cs index 32b9847..f746bb5 100644 --- a/Capy64/LuaRuntime/Libraries/FileSystem.cs +++ b/Capy64/LuaRuntime/Libraries/FileSystem.cs @@ -1,6 +1,6 @@ using Capy64.API; using Capy64.LuaRuntime.Extensions; -using Capy64.LuaRuntime.Handlers; +using Capy64.LuaRuntime.Objects.Handlers; using KeraLua; using System; using System.Collections.Generic; diff --git a/Capy64/LuaRuntime/Libraries/GPU.cs b/Capy64/LuaRuntime/Libraries/GPU.cs index 27e348c..be97a06 100644 --- a/Capy64/LuaRuntime/Libraries/GPU.cs +++ b/Capy64/LuaRuntime/Libraries/GPU.cs @@ -1,4 +1,5 @@ using Capy64.API; +using Capy64.LuaRuntime.Objects; using KeraLua; using Microsoft.Xna.Framework; using System; @@ -91,6 +92,21 @@ public class GPU : IPlugin name = "measureString", function = L_MeasureString }, + new() + { + name = "getBuffer", + function = L_GetBuffer, + }, + new() + { + name = "setBuffer", + function = L_SetBuffer, + }, + new() + { + name = "newBuffer", + function = L_NewBuffer, + }, new(), // NULL }; @@ -361,4 +377,46 @@ public class GPU : IPlugin return 2; } + + private static int L_GetBuffer(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + var buffer = new uint[_game.Width * _game.Height]; + _game.Drawing.Canvas.GetData(buffer); + + var handle = new GPUBuffer(_game, buffer); + + handle.Push(L); + + return 1; + } + + private static int L_SetBuffer(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + var buffer = L.CheckObject(1, GPUBuffer.ObjectType, false); + if (buffer is null) + { + L.ArgumentError(1, GPUBuffer.ObjectType + " expected, got " + L.TypeName(L.Type(1))); + } + + _game.Drawing.Canvas.SetData(buffer); + + return 0; + } + + private static int L_NewBuffer(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + var buffer = new uint[_game.Width * _game.Height]; + + var handle = new GPUBuffer(_game, buffer); + + handle.Push(L); + + return 1; + } } diff --git a/Capy64/LuaRuntime/Libraries/HTTP.cs b/Capy64/LuaRuntime/Libraries/HTTP.cs index 5a73e28..dc7b1d7 100644 --- a/Capy64/LuaRuntime/Libraries/HTTP.cs +++ b/Capy64/LuaRuntime/Libraries/HTTP.cs @@ -1,6 +1,6 @@ using Capy64.API; using Capy64.LuaRuntime.Extensions; -using Capy64.LuaRuntime.Handlers; +using Capy64.LuaRuntime.Objects.Handlers; using KeraLua; using Microsoft.Extensions.Configuration; using System; diff --git a/Capy64/LuaRuntime/Objects/GPUBuffer.cs b/Capy64/LuaRuntime/Objects/GPUBuffer.cs new file mode 100644 index 0000000..9878b8c --- /dev/null +++ b/Capy64/LuaRuntime/Objects/GPUBuffer.cs @@ -0,0 +1,117 @@ +using KeraLua; +using System; + +namespace Capy64.LuaRuntime.Objects; + +public class GPUBuffer +{ + public const string ObjectType = "GPUBuffer"; + + private static IGame _game; + private uint[] _buffer; + public GPUBuffer(IGame game, uint[] buffer) + { + _game = game; + _buffer = buffer; + } + + public void Push(Lua L) + { + if (L.NewMetaTable(ObjectType)) + { + L.PushString("__index"); + L.PushCFunction(LM_Index); + L.SetTable(-3); + + L.PushString("__newindex"); + L.PushCFunction(LM_NewIndex); + L.SetTable(-3); + + L.PushString("__gc"); + L.PushCFunction(LM_GC); + L.SetTable(-3); + } + + L.PushObject(_buffer); + L.SetMetaTable(ObjectType); + } + + private static int LM_Index(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + var buffer = L.CheckObject(1, ObjectType, false); + + if (!L.IsInteger(2)) + { + L.PushNil(); + return 1; + } + + var key = L.ToInteger(2); + + if (key < 0 || key >= buffer.Length) + { + L.PushNil(); + return 1; + } + + var value = buffer[key]; + + // ABGR to RGB + value = + (value & 0x00_00_00_FFU) << 16 | // move R + (value & 0x00_00_FF_00U) | // move G + (value & 0x00_FF_00_00U) >> 16; // move B + + L.PushInteger(value); + + return 1; + } + + private static int LM_NewIndex(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + var buffer = L.CheckObject(1, ObjectType, false); + if (!L.IsInteger(2)) + { + return 0; + } + + var key = L.ToInteger(2); + + if (key < 0 || key >= buffer.Length) + { + return 0; + } + + if (!L.IsInteger(3)) + { + return 0; + } + + var value = (uint)L.ToInteger(3); + + // RGB to ABGR + value = + (value & 0x00_FF_00_00U) >> 16 | // move R + (value & 0x00_00_FF_00U) | // move G + (value & 0x00_00_00_FFU) << 16 | // move B + 0xFF_00_00_00U; + + + buffer[key] = value; + + return 0; + } + + private static int LM_GC(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + L.CheckObject(1, ObjectType, true); + + return 0; + } +} diff --git a/Capy64/LuaRuntime/Handlers/BinaryReadHandle.cs b/Capy64/LuaRuntime/Objects/Handlers/BinaryReadHandle.cs similarity index 99% rename from Capy64/LuaRuntime/Handlers/BinaryReadHandle.cs rename to Capy64/LuaRuntime/Objects/Handlers/BinaryReadHandle.cs index 4a8e248..3975fe0 100644 --- a/Capy64/LuaRuntime/Handlers/BinaryReadHandle.cs +++ b/Capy64/LuaRuntime/Objects/Handlers/BinaryReadHandle.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.IO; using System.Text; -namespace Capy64.LuaRuntime.Handlers; +namespace Capy64.LuaRuntime.Objects.Handlers; public class BinaryReadHandle : IHandle { diff --git a/Capy64/LuaRuntime/Handlers/BinaryWriteHandle.cs b/Capy64/LuaRuntime/Objects/Handlers/BinaryWriteHandle.cs similarity index 99% rename from Capy64/LuaRuntime/Handlers/BinaryWriteHandle.cs rename to Capy64/LuaRuntime/Objects/Handlers/BinaryWriteHandle.cs index 5055c98..494340c 100644 --- a/Capy64/LuaRuntime/Handlers/BinaryWriteHandle.cs +++ b/Capy64/LuaRuntime/Objects/Handlers/BinaryWriteHandle.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.IO; using System.Text; -namespace Capy64.LuaRuntime.Handlers; +namespace Capy64.LuaRuntime.Objects.Handlers; public class BinaryWriteHandle : IHandle { diff --git a/Capy64/LuaRuntime/Handlers/IHandle.cs b/Capy64/LuaRuntime/Objects/Handlers/IHandle.cs similarity index 68% rename from Capy64/LuaRuntime/Handlers/IHandle.cs rename to Capy64/LuaRuntime/Objects/Handlers/IHandle.cs index 5b3fbcc..ecf02c8 100644 --- a/Capy64/LuaRuntime/Handlers/IHandle.cs +++ b/Capy64/LuaRuntime/Objects/Handlers/IHandle.cs @@ -1,6 +1,6 @@ using KeraLua; -namespace Capy64.LuaRuntime.Handlers; +namespace Capy64.LuaRuntime.Objects.Handlers; public interface IHandle { diff --git a/Capy64/LuaRuntime/Handlers/ReadHandle.cs b/Capy64/LuaRuntime/Objects/Handlers/ReadHandle.cs similarity index 98% rename from Capy64/LuaRuntime/Handlers/ReadHandle.cs rename to Capy64/LuaRuntime/Objects/Handlers/ReadHandle.cs index 5152869..7719df6 100644 --- a/Capy64/LuaRuntime/Handlers/ReadHandle.cs +++ b/Capy64/LuaRuntime/Objects/Handlers/ReadHandle.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; using System.IO; -namespace Capy64.LuaRuntime.Handlers; +namespace Capy64.LuaRuntime.Objects.Handlers; public class ReadHandle : IHandle { diff --git a/Capy64/LuaRuntime/Handlers/WebSocketHandle.cs b/Capy64/LuaRuntime/Objects/Handlers/WebSocketHandle.cs similarity index 98% rename from Capy64/LuaRuntime/Handlers/WebSocketHandle.cs rename to Capy64/LuaRuntime/Objects/Handlers/WebSocketHandle.cs index a5ba4d3..702150b 100644 --- a/Capy64/LuaRuntime/Handlers/WebSocketHandle.cs +++ b/Capy64/LuaRuntime/Objects/Handlers/WebSocketHandle.cs @@ -8,7 +8,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -namespace Capy64.LuaRuntime.Handlers; +namespace Capy64.LuaRuntime.Objects.Handlers; public class WebSocketHandle : IHandle { diff --git a/Capy64/LuaRuntime/Handlers/WriteHandle.cs b/Capy64/LuaRuntime/Objects/Handlers/WriteHandle.cs similarity index 98% rename from Capy64/LuaRuntime/Handlers/WriteHandle.cs rename to Capy64/LuaRuntime/Objects/Handlers/WriteHandle.cs index 4771036..b0c16d5 100644 --- a/Capy64/LuaRuntime/Handlers/WriteHandle.cs +++ b/Capy64/LuaRuntime/Objects/Handlers/WriteHandle.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; using System.IO; -namespace Capy64.LuaRuntime.Handlers; +namespace Capy64.LuaRuntime.Objects.Handlers; public class WriteHandle : IHandle {