aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Memory/AMemoryWin32.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-06-08 21:15:56 -0300
committerGitHub <noreply@github.com>2018-06-08 21:15:56 -0300
commit231fae1a4c97d7588655e9775f37c1dc9bd55fb0 (patch)
tree1c0e7b298ec33d5bf5b6a5693dd69a8c7e0bd23b /ChocolArm64/Memory/AMemoryWin32.cs
parent6fe51f970501fe732276c17ed0dacb564b92a73d (diff)
Texture/Vertex/Index data cache (#132)
* Initial implementation of the texture cache * Cache vertex and index data aswell, some cleanup * Improve handling of the cache by storing cached ranges on a list for each page * Delete old data from the caches automatically, ensure that the cache is cleaned when the mapping/size changes, and some general cleanup
Diffstat (limited to 'ChocolArm64/Memory/AMemoryWin32.cs')
-rw-r--r--ChocolArm64/Memory/AMemoryWin32.cs73
1 files changed, 73 insertions, 0 deletions
diff --git a/ChocolArm64/Memory/AMemoryWin32.cs b/ChocolArm64/Memory/AMemoryWin32.cs
new file mode 100644
index 00000000..d097dc87
--- /dev/null
+++ b/ChocolArm64/Memory/AMemoryWin32.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace ChocolArm64.Memory
+{
+ static class AMemoryWin32
+ {
+ private const int MEM_COMMIT = 0x00001000;
+ private const int MEM_RESERVE = 0x00002000;
+ private const int MEM_WRITE_WATCH = 0x00200000;
+
+ private const int PAGE_READWRITE = 0x04;
+
+ private const int MEM_RELEASE = 0x8000;
+
+ private const int WRITE_WATCH_FLAG_RESET = 1;
+
+ [DllImport("kernel32.dll")]
+ private static extern IntPtr VirtualAlloc(IntPtr lpAddress, IntPtr dwSize, int flAllocationType, int flProtect);
+
+ [DllImport("kernel32.dll")]
+ private static extern bool VirtualFree(IntPtr lpAddress, IntPtr dwSize, int dwFreeType);
+
+ [DllImport("kernel32.dll")]
+ private unsafe static extern int GetWriteWatch(
+ int dwFlags,
+ IntPtr lpBaseAddress,
+ IntPtr dwRegionSize,
+ IntPtr[] lpAddresses,
+ long* lpdwCount,
+ long* lpdwGranularity);
+
+ public static IntPtr Allocate(IntPtr Size)
+ {
+ const int Flags = MEM_COMMIT | MEM_RESERVE | MEM_WRITE_WATCH;
+
+ IntPtr Address = VirtualAlloc(IntPtr.Zero, Size, Flags, PAGE_READWRITE);
+
+ if (Address == IntPtr.Zero)
+ {
+ throw new InvalidOperationException();
+ }
+
+ return Address;
+ }
+
+ public static void Free(IntPtr Address)
+ {
+ VirtualFree(Address, IntPtr.Zero, MEM_RELEASE);
+ }
+
+ public unsafe static long IsRegionModified(IntPtr Address, IntPtr Size, bool Reset)
+ {
+ IntPtr[] Addresses = new IntPtr[1];
+
+ long Count = Addresses.Length;
+
+ long Granularity;
+
+ int Flags = Reset ? WRITE_WATCH_FLAG_RESET : 0;
+
+ GetWriteWatch(
+ Flags,
+ Address,
+ Size,
+ Addresses,
+ &Count,
+ &Granularity);
+
+ return Count != 0 ? Granularity : 0;
+ }
+ }
+} \ No newline at end of file