aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorZephyron <zephyron@citron-emu.org>2025-04-12 16:15:51 +1000
committerMrPurple666 <antoniosacramento666usa@gmail.com>2025-04-12 23:42:24 -0300
commit34693001aa6e86bb543e5b8b18b3c9dc919ddde7 (patch)
tree7922910b70085858b30ca084db6d75a79db476a6 /src/video_core/renderer_vulkan
parent9615e910f90ea0af0c616eed5329b176d4700d7f (diff)
Add Windows support to Hybrid Memory Manager
This commit adds Windows-specific implementation of the fault-managed memory system, providing similar functionality to the existing Linux/Android implementation. Key changes: - Added Windows-specific memory management using VirtualAlloc/VirtualFree - Implemented Windows vectored exception handler for page fault handling - Added proper memory protection and page fault handling on Windows - Updated memory snapshot functionality to work on Windows - Added proper cleanup of Windows-specific resources - Fixed type conversion issues in memory management code - Added proper error handling for Windows memory operations - Fixed VRAM Memory Layout Mode to allow up to 12Gb The implementation uses Windows-specific APIs: - VirtualAlloc/VirtualFree for memory management - AddVectoredExceptionHandler for page fault handling - VirtualProtect for memory protection management This change maintains feature parity with the Linux/Android implementation while using Windows-native APIs for better performance and reliability. Signed-off-by: Zephyron <zephyron@citron-emu.org>
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp50
1 files changed, 37 insertions, 13 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index c9f6f0836c..041fb9e054 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -9,6 +9,8 @@
#include <optional>
#include <string>
#include <vector>
+#include <fstream>
+#include <filesystem>
#include <fmt/ranges.h>
@@ -135,15 +137,37 @@ RendererVulkan::RendererVulkan(Core::Frontend::EmuWindow& emu_window,
// Initialize HybridMemory system
if (Settings::values.use_gpu_memory_manager.GetValue()) {
-#if defined(__linux__) || defined(__ANDROID__)
+#if defined(__linux__) || defined(__ANDROID__) || defined(_WIN32)
try {
- void* guest_memory_base = std::aligned_alloc(4096, 64 * 1024 * 1024);
- if (guest_memory_base) {
+ // Define memory size with explicit types to avoid conversion warnings
+ constexpr size_t memory_size_mb = 64;
+ constexpr size_t memory_size_bytes = memory_size_mb * 1024 * 1024;
+
+ void* guest_memory_base = nullptr;
+#if defined(_WIN32)
+ // On Windows, use VirtualAlloc to reserve (but not commit) memory
+ const SIZE_T win_size = static_cast<SIZE_T>(memory_size_bytes);
+ LPVOID result = VirtualAlloc(nullptr, win_size, MEM_RESERVE, PAGE_NOACCESS);
+ if (result != nullptr) {
+ guest_memory_base = result;
+ }
+#else
+ // On Linux/Android, use aligned_alloc
+ guest_memory_base = std::aligned_alloc(4096, memory_size_bytes);
+#endif
+ if (guest_memory_base != nullptr) {
try {
- hybrid_memory->InitializeGuestMemory(guest_memory_base, 64 * 1024 * 1024);
- LOG_INFO(Render_Vulkan, "HybridMemory initialized with {} MB of fault-managed memory", 64);
- } catch (const std::exception& e) {
+ hybrid_memory->InitializeGuestMemory(guest_memory_base, memory_size_bytes);
+ LOG_INFO(Render_Vulkan, "HybridMemory initialized with {} MB of fault-managed memory", memory_size_mb);
+ } catch (const std::exception&) {
+#if defined(_WIN32)
+ if (guest_memory_base != nullptr) {
+ const LPVOID win_ptr = static_cast<LPVOID>(guest_memory_base);
+ VirtualFree(win_ptr, 0, MEM_RELEASE);
+ }
+#else
std::free(guest_memory_base);
+#endif
throw;
}
}
@@ -167,10 +191,10 @@ RendererVulkan::RendererVulkan(Core::Frontend::EmuWindow& emu_window,
// Add paths to common shaders that should be preloaded
// These will be compiled in parallel for faster startup
- if (std::filesystem::exists(shader_dir)) {
- try {
+ try {
+ if (std::filesystem::exists(shader_dir)) {
for (const auto& entry : std::filesystem::directory_iterator(shader_dir)) {
- if (entry.path().extension() == ".spv") {
+ if (entry.is_regular_file() && entry.path().extension() == ".spv") {
common_shaders.push_back(entry.path().string());
}
}
@@ -179,11 +203,11 @@ RendererVulkan::RendererVulkan(Core::Frontend::EmuWindow& emu_window,
LOG_INFO(Render_Vulkan, "Preloading {} common shaders", common_shaders.size());
shader_manager.PreloadShaders(common_shaders);
}
- } catch (const std::exception& e) {
- LOG_ERROR(Render_Vulkan, "Error during shader preloading: {}", e.what());
+ } else {
+ LOG_INFO(Render_Vulkan, "Shader directory not found at {}", shader_dir);
}
- } else {
- LOG_INFO(Render_Vulkan, "Shader directory not found at {}", shader_dir);
+ } catch (const std::exception& e) {
+ LOG_ERROR(Render_Vulkan, "Error during shader preloading: {}", e.what());
}
}