first attempt to write inline ASM in C#, failed due to proteted ram
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
using Steamworks;
|
||||
using StgSharp.Control;
|
||||
using StgSharp.Math;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
|
||||
namespace StgSharp.Geometries
|
||||
{
|
||||
public class Polygon6 : IPlainGeometry
|
||||
{
|
||||
internal Point _refOrigin;
|
||||
internal Point vertex1;
|
||||
internal Point vertex2;
|
||||
internal Point vertex3;
|
||||
internal Point vertex4;
|
||||
internal Point vertex5;
|
||||
internal Point vertex6;
|
||||
internal readonly int _vertexCount;
|
||||
|
||||
public override Point RefPoint01 => vertex1;
|
||||
|
||||
public override Point RefPoint02 => vertex2;
|
||||
|
||||
public override Point RefPoint03 => vertex3;
|
||||
|
||||
|
||||
internal GetLocationHandler movP01Operation = default;
|
||||
internal GetLocationHandler movP02Operation = default;
|
||||
internal GetLocationHandler movP03Operation = default;
|
||||
internal GetLocationHandler movP04Operation = default;
|
||||
internal GetLocationHandler movP05Operation = default;
|
||||
internal GetLocationHandler movP06Operation = default;
|
||||
|
||||
public GetLocationHandler MovP01Operation { get => movP01Operation; }
|
||||
public GetLocationHandler MovP02Operation { get => movP02Operation; }
|
||||
public GetLocationHandler MovP03Operation { get => movP03Operation; }
|
||||
public GetLocationHandler MovP04Operation { get => movP04Operation; }
|
||||
public GetLocationHandler MovP05Operation { get => movP05Operation; }
|
||||
public GetLocationHandler MovP06Operation { get => movP06Operation; }
|
||||
|
||||
public virtual vec3d movPoint01(uint tick)
|
||||
{
|
||||
return movP01Operation.Invoke(GameTimeLine.tickCounter._value);
|
||||
}
|
||||
|
||||
public virtual vec3d movPoint02(uint tick)
|
||||
{
|
||||
return movP02Operation.Invoke(GameTimeLine.tickCounter._value);
|
||||
}
|
||||
|
||||
public virtual vec3d movPoint03(uint tick)
|
||||
{
|
||||
return movP03Operation.Invoke(GameTimeLine.tickCounter._value);
|
||||
}
|
||||
|
||||
public virtual vec3d movPoint04(uint tick)
|
||||
{
|
||||
return movP04Operation.Invoke(GameTimeLine.tickCounter._value);
|
||||
}
|
||||
|
||||
public virtual vec3d movPoint05(uint tick)
|
||||
{
|
||||
return movP05Operation.Invoke(GameTimeLine.tickCounter._value);
|
||||
}
|
||||
|
||||
public virtual vec3d movPoint06(uint tick)
|
||||
{
|
||||
return movP06Operation.Invoke(GameTimeLine.tickCounter._value);
|
||||
}
|
||||
|
||||
internal override void OnRender(uint tick)
|
||||
{
|
||||
uint nowTick = tick - BornTime;
|
||||
vertex1._position = RefOrigin._position + movPoint01(nowTick);
|
||||
vertex2._position = RefOrigin._position + movPoint02(nowTick);
|
||||
vertex3._position = RefOrigin._position + movPoint03(nowTick);
|
||||
vertex4._position = RefOrigin._position + movPoint04(nowTick);
|
||||
vertex5._position = RefOrigin._position + movPoint05(nowTick);
|
||||
vertex6._position = RefOrigin._position + movPoint06(nowTick);
|
||||
}
|
||||
|
||||
public override Line[] GetAllSides()
|
||||
{
|
||||
return new Line[6]
|
||||
{
|
||||
new Line(vertex1,vertex2),
|
||||
new Line(vertex2,vertex3),
|
||||
new Line(vertex3,vertex4),
|
||||
new Line(vertex4,vertex5),
|
||||
new Line(vertex5,vertex6),
|
||||
new Line(vertex6,vertex1)
|
||||
};
|
||||
}
|
||||
|
||||
public override Plain GetPlain()
|
||||
{
|
||||
return new Plain(vertex1,vertex2,vertex3);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace StgSharp.Optimization
|
||||
{
|
||||
public class CpuInfo : IDisposable
|
||||
{
|
||||
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
|
||||
public delegate void CpuIDDelegate(int level, byte[] buffer);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr VirtualAlloc(
|
||||
IntPtr lpAddress,
|
||||
UIntPtr dwSize,
|
||||
AllocationType flAllocationType,
|
||||
MemoryProtection flProtect
|
||||
);
|
||||
|
||||
[DllImport("kernel32")]
|
||||
private static extern bool VirtualFree(
|
||||
IntPtr lpAddress,
|
||||
UInt32 dwSize,
|
||||
UInt32 dwFreeType
|
||||
);
|
||||
|
||||
[Flags()]
|
||||
public enum AllocationType : uint
|
||||
{
|
||||
COMMIT = 0x1000,
|
||||
RESERVE = 0x2000,
|
||||
RESET = 0x80000,
|
||||
LARGE_PAGES = 0x20000000,
|
||||
PHYSICAL = 0x400000,
|
||||
TOP_DOWN = 0x100000,
|
||||
WRITE_WATCH = 0x200000
|
||||
}
|
||||
|
||||
[Flags()]
|
||||
public enum MemoryProtection : uint
|
||||
{
|
||||
EXECUTE = 0x10,
|
||||
EXECUTE_READ = 0x20,
|
||||
EXECUTE_READWRITE = 0x40,
|
||||
EXECUTE_WRITECOPY = 0x80,
|
||||
NOACCESS = 0x01,
|
||||
READONLY = 0x02,
|
||||
READWRITE = 0x04,
|
||||
WRITECOPY = 0x08,
|
||||
GUARD_Modifierflag = 0x100,
|
||||
NOCACHE_Modifierflag = 0x200,
|
||||
WRITECOMBINE_Modifierflag = 0x400
|
||||
}
|
||||
|
||||
private CpuIDDelegate cpuIdDelg;
|
||||
|
||||
private IntPtr codePointer;
|
||||
|
||||
// void x86CpuId(int level, byte* buffer)
|
||||
// {
|
||||
// eax = level
|
||||
// cpuid
|
||||
// buffer[0] = eax
|
||||
// buffer[4] = ebx
|
||||
// buffer[8] = ecx
|
||||
// buffer[12] = edx
|
||||
// }
|
||||
/*
|
||||
private byte[] x86CodeBytes =
|
||||
{
|
||||
0x55, // push ebp
|
||||
0x8B, 0xEC, // mov ebp,esp
|
||||
0x53, // push ebx
|
||||
0x57, // push edi
|
||||
|
||||
0x8B, 0x45, 0x08, // mov eax, dword ptr [ebp+8] (move level into eax)
|
||||
0x0F, 0xA2, // cpuid
|
||||
|
||||
0x8B, 0x7D, 0x0C, // mov edi, dword ptr [ebp+12] (move address of buffer into edi)
|
||||
0x89, 0x07, // mov dword ptr [edi+0], eax (write eax, ... to buffer)
|
||||
0x89, 0x5F, 0x04, // mov dword ptr [edi+4], ebx
|
||||
0x89, 0x4F, 0x08, // mov dword ptr [edi+8], ecx
|
||||
0x89, 0x57, 0x0C, // mov dword ptr [edi+12],edx
|
||||
|
||||
0x5F, // pop edi
|
||||
0x5B, // pop ebx
|
||||
0x8B, 0xE5, // mov esp,ebp
|
||||
0x5D, // pop ebp
|
||||
0xc3 // ret
|
||||
};
|
||||
*/
|
||||
|
||||
//x64
|
||||
private byte[] CodeBytes =
|
||||
{
|
||||
0x53, // push rbx this gets clobbered by cpuid
|
||||
|
||||
// rcx is level
|
||||
// rdx is buffer.
|
||||
// Need to save buffer elsewhere, cpuid overwrites rdx
|
||||
// Put buffer in r8, use r8 to reference buffer later.
|
||||
|
||||
// Save rdx (buffer addy) to r8
|
||||
0x49, 0x89, 0xd0, // mov r8, rdx
|
||||
|
||||
// Move ecx (level) to eax to call cpuid, call cpuid
|
||||
0x89, 0xc8, // mov eax, ecx
|
||||
0x0F, 0xA2, // cpuid
|
||||
|
||||
// Write eax et al to buffer
|
||||
0x41, 0x89, 0x40, 0x00, // mov dword ptr [r8+0], eax
|
||||
0x41, 0x89, 0x58, 0x04, // mov dword ptr [r8+4], ebx
|
||||
0x41, 0x89, 0x48, 0x08, // mov dword ptr [r8+8], ecx
|
||||
0x41, 0x89, 0x50, 0x0c, // mov dword ptr [r8+12], edx
|
||||
|
||||
0x5b, // pop rbx
|
||||
0xc3 // ret
|
||||
};
|
||||
|
||||
public CpuInfo()
|
||||
{
|
||||
Compile();
|
||||
}
|
||||
|
||||
~CpuInfo()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
private void Compile()
|
||||
{
|
||||
byte[] codeBytes = CodeBytes;
|
||||
|
||||
if (IntPtr.Size != 8)
|
||||
{
|
||||
throw new Exception("This class supports 64bits OS only presently");
|
||||
}
|
||||
|
||||
this.codePointer = VirtualAlloc(
|
||||
IntPtr.Zero,
|
||||
new UIntPtr((uint)codeBytes.Length),
|
||||
AllocationType.COMMIT | AllocationType.RESERVE,
|
||||
MemoryProtection.EXECUTE_READWRITE
|
||||
);
|
||||
|
||||
Marshal.Copy(codeBytes, 0, this.codePointer, codeBytes.Length);
|
||||
|
||||
this.cpuIdDelg = (CpuIDDelegate)Marshal.GetDelegateForFunctionPointer(this.codePointer, typeof(CpuIDDelegate));
|
||||
}
|
||||
|
||||
public void Invoke(int level, byte[] buffer)
|
||||
{
|
||||
GCHandle handle = default(GCHandle);
|
||||
if (buffer.Length < 16)
|
||||
{
|
||||
throw new ArgumentException("buffer must be at least 16 bytes long");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
|
||||
|
||||
this.cpuIdDelg(level, buffer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (handle != default(GCHandle))
|
||||
{
|
||||
handle.Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
public void Dispose(bool disposing)
|
||||
{
|
||||
if (this.codePointer != IntPtr.Zero)
|
||||
{
|
||||
VirtualFree(this.codePointer, 0, 0x8000);
|
||||
this.codePointer = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using StgSharp.Math;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace StgSharp.Optimization
|
||||
{
|
||||
public static unsafe partial class SSE
|
||||
{
|
||||
|
||||
public static m128 ToM128(this vec2d vec)
|
||||
{
|
||||
return *(m128*)&vec;
|
||||
}
|
||||
|
||||
public static m128 ToVec4D(this m128 m)
|
||||
{
|
||||
return *(m128*)&m;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using StgSharp.Math;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using static StgSharp.Optimization.CpuInfo;
|
||||
|
||||
namespace StgSharp.Optimization
|
||||
{
|
||||
public static unsafe partial class SSE
|
||||
{
|
||||
public static m128 sqrtssM128Cache = new m128();
|
||||
|
||||
private static IntPtr sqrtssCodePointer;
|
||||
|
||||
private static sqrtssDelegate sqrtssDele;
|
||||
|
||||
private static byte[] sqrtssCodeBytes
|
||||
= new byte[]
|
||||
{
|
||||
0x48,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // mov rax, [m128 location]
|
||||
0xf3,0x0f,0x6f,0x00, // movqdu xmm0,xmmword ptr [rax]
|
||||
0xf3,0x0f,0x51,0xc0, // sqrtss xmm0,xmm0
|
||||
0xf3,0x0f,0x7f,0x00 // movdqu xmmword ptr [rax],xmm0
|
||||
};
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr VirtualAlloc(
|
||||
IntPtr lpAddress,
|
||||
UIntPtr dwSize,
|
||||
AllocationType flAllocationType,
|
||||
MemoryProtection flProtect
|
||||
);
|
||||
|
||||
[DllImport("kernel32")]
|
||||
private static extern bool VirtualFree(
|
||||
IntPtr lpAddress,
|
||||
UInt32 dwSize,
|
||||
UInt32 dwFreeType
|
||||
);
|
||||
|
||||
private unsafe static void InitSqrtss()
|
||||
{
|
||||
var marshalPtr = Marshal.AllocHGlobal(32);
|
||||
var m128ptr = new IntPtr(16*((long)marshalPtr/16+1));
|
||||
m128* sqrtssCachePointer = (m128*)m128ptr.ToPointer();
|
||||
|
||||
sqrtssM128Cache = *sqrtssCachePointer;
|
||||
byte[] sqrtssM128PointerBytes = BitConverter.GetBytes((ulong)sqrtssCachePointer);
|
||||
for (int i = 0; i < sqrtssM128PointerBytes.Length; i++)
|
||||
{
|
||||
sqrtssCodeBytes[2+i] = sqrtssCodeBytes[7-i];
|
||||
}
|
||||
|
||||
if (IntPtr.Size!=8)
|
||||
{
|
||||
throw new Exception("This SSE class support 64bits OS only presently!");
|
||||
}
|
||||
|
||||
sqrtssCodePointer = VirtualAlloc(
|
||||
IntPtr.Zero,
|
||||
new UIntPtr((uint)sqrtssCodeBytes.Length),
|
||||
AllocationType.COMMIT | AllocationType.RESERVE,
|
||||
MemoryProtection.EXECUTE_READWRITE
|
||||
);
|
||||
|
||||
Marshal.Copy(sqrtssCodeBytes, 0, sqrtssCodePointer, sqrtssCodeBytes.Length);
|
||||
sqrtssDele = (sqrtssDelegate)Marshal.GetDelegateForFunctionPointer(sqrtssCodePointer,typeof(sqrtssDelegate));
|
||||
}
|
||||
|
||||
public static float Sqrtss(float a)
|
||||
{
|
||||
sqrtssM128Cache.float0 = a;
|
||||
sqrtssDele();
|
||||
return sqrtssM128Cache.float0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
|
||||
internal delegate void sqrtssDelegate();
|
||||
}
|
||||
@@ -4,9 +4,13 @@ using System.Text;
|
||||
|
||||
namespace StgSharp.Optimization
|
||||
{
|
||||
public unsafe class SSE
|
||||
public static unsafe partial class SSE
|
||||
{
|
||||
|
||||
static SSE()
|
||||
{
|
||||
//编译模拟Sqrtss指令
|
||||
InitSqrtss();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
0bd409a23d12a7e03a996538d35e30898336817d
|
||||
508c7d643da3ffba0187af6df00e8fd1f0a8c855
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user