FAST GPU BUFFERS!!!!!

This commit is contained in:
Alessandro Proto 2023-01-21 11:40:39 +01:00
parent 5398405f77
commit a63001a3f9
10 changed files with 183 additions and 8 deletions

View file

@ -1,6 +1,6 @@
using Capy64.API; using Capy64.API;
using Capy64.LuaRuntime.Extensions; using Capy64.LuaRuntime.Extensions;
using Capy64.LuaRuntime.Handlers; using Capy64.LuaRuntime.Objects.Handlers;
using KeraLua; using KeraLua;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

View file

@ -1,4 +1,5 @@
using Capy64.API; using Capy64.API;
using Capy64.LuaRuntime.Objects;
using KeraLua; using KeraLua;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using System; using System;
@ -91,6 +92,21 @@ public class GPU : IPlugin
name = "measureString", name = "measureString",
function = L_MeasureString function = L_MeasureString
}, },
new()
{
name = "getBuffer",
function = L_GetBuffer,
},
new()
{
name = "setBuffer",
function = L_SetBuffer,
},
new()
{
name = "newBuffer",
function = L_NewBuffer,
},
new(), // NULL new(), // NULL
}; };
@ -361,4 +377,46 @@ public class GPU : IPlugin
return 2; 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<uint[]>(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;
}
} }

View file

@ -1,6 +1,6 @@
using Capy64.API; using Capy64.API;
using Capy64.LuaRuntime.Extensions; using Capy64.LuaRuntime.Extensions;
using Capy64.LuaRuntime.Handlers; using Capy64.LuaRuntime.Objects.Handlers;
using KeraLua; using KeraLua;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using System; using System;

View file

@ -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<uint[]>(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<uint[]>(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<uint[]>(1, ObjectType, true);
return 0;
}
}

View file

@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
namespace Capy64.LuaRuntime.Handlers; namespace Capy64.LuaRuntime.Objects.Handlers;
public class BinaryReadHandle : IHandle public class BinaryReadHandle : IHandle
{ {

View file

@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
namespace Capy64.LuaRuntime.Handlers; namespace Capy64.LuaRuntime.Objects.Handlers;
public class BinaryWriteHandle : IHandle public class BinaryWriteHandle : IHandle
{ {

View file

@ -1,6 +1,6 @@
using KeraLua; using KeraLua;
namespace Capy64.LuaRuntime.Handlers; namespace Capy64.LuaRuntime.Objects.Handlers;
public interface IHandle public interface IHandle
{ {

View file

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
namespace Capy64.LuaRuntime.Handlers; namespace Capy64.LuaRuntime.Objects.Handlers;
public class ReadHandle : IHandle public class ReadHandle : IHandle
{ {

View file

@ -8,7 +8,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Capy64.LuaRuntime.Handlers; namespace Capy64.LuaRuntime.Objects.Handlers;
public class WebSocketHandle : IHandle public class WebSocketHandle : IHandle
{ {

View file

@ -3,7 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
namespace Capy64.LuaRuntime.Handlers; namespace Capy64.LuaRuntime.Objects.Handlers;
public class WriteHandle : IHandle public class WriteHandle : IHandle
{ {