diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-06-08 21:15:56 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-06-08 21:15:56 -0300 |
| commit | 231fae1a4c97d7588655e9775f37c1dc9bd55fb0 (patch) | |
| tree | 1c0e7b298ec33d5bf5b6a5693dd69a8c7e0bd23b /ChocolArm64/Memory/AMemoryWin32.cs | |
| parent | 6fe51f970501fe732276c17ed0dacb564b92a73d (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.cs | 73 |
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 |
