mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-06-27 18:36:35 +02:00
[android] gpu logs functions (#3389)
Since Android is a pain when it comes to checking GPU logs in more depth, this is a better way to see what's going on, especially for testers... This should be expanded to Mali, Xclipse, and Tensor in the future. Since I don't own any of these devices, it's up to developers with similar capabilities to add support for this system. ~~The GPU log sharing button should also be added in the future... For now, they are available in the same location as the traditional logs.~~ Added on 572810e022 Co-authored-by: DraVee <dravee@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3389 Reviewed-by: DraVee <dravee@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Co-authored-by: MrPurple666 <antoniosacramento666usa@gmail.com> Co-committed-by: MrPurple666 <antoniosacramento666usa@gmail.com>
This commit is contained in:
parent
8118557c17
commit
6637810fe6
31 changed files with 1669 additions and 17 deletions
|
|
@ -1,12 +1,26 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <string_view>
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "video_core/vulkan_common/vulkan_debug_callback.h"
|
||||
#include "video_core/gpu_logging/gpu_logging.h"
|
||||
|
||||
namespace Vulkan {
|
||||
namespace {
|
||||
|
||||
// Helper to get message type as string for GPU logging
|
||||
const char* GetMessageTypeName(VkDebugUtilsMessageTypeFlagsEXT type) {
|
||||
if (type & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) {
|
||||
return "Validation";
|
||||
} else if (type & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) {
|
||||
return "Performance";
|
||||
} else {
|
||||
return "General";
|
||||
}
|
||||
}
|
||||
|
||||
VkBool32 DebugUtilCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT type,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* data,
|
||||
|
|
@ -60,6 +74,28 @@ VkBool32 DebugUtilCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
|||
} else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
|
||||
LOG_DEBUG(Render_Vulkan, "{}", message);
|
||||
}
|
||||
|
||||
// Route to GPU logger for tracking Vulkan validation messages
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
Settings::values.gpu_log_vulkan_calls.GetValue()) {
|
||||
// Convert severity to result code for logging (negative = error)
|
||||
int result_code = 0;
|
||||
if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
|
||||
result_code = -1;
|
||||
} else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
|
||||
result_code = -2;
|
||||
}
|
||||
|
||||
// Get message ID name or use generic name
|
||||
const char* call_name = data->pMessageIdName ? data->pMessageIdName : "VulkanDebug";
|
||||
|
||||
GPU::Logging::GPULogger::GetInstance().LogVulkanCall(
|
||||
call_name,
|
||||
std::string(GetMessageTypeName(type)) + ": " + std::string(message),
|
||||
result_code
|
||||
);
|
||||
}
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/literals.h"
|
||||
#include <ranges>
|
||||
|
|
@ -22,6 +24,7 @@
|
|||
#include "video_core/vulkan_common/vma.h"
|
||||
#include "video_core/vulkan_common/vulkan_device.h"
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
#include "video_core/gpu_logging/gpu_logging.h"
|
||||
|
||||
#if defined(ANDROID) && defined(ARCHITECTURE_arm64)
|
||||
#include <adrenotools/bcenabler.h>
|
||||
|
|
@ -734,9 +737,13 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
|||
};
|
||||
|
||||
vk::Check(vmaCreateAllocator(&allocator_info, &allocator));
|
||||
|
||||
// Initialize GPU logging if enabled
|
||||
InitializeGPULogging();
|
||||
}
|
||||
|
||||
Device::~Device() {
|
||||
ShutdownGPULogging();
|
||||
vmaDestroyAllocator(allocator);
|
||||
}
|
||||
|
||||
|
|
@ -1622,4 +1629,106 @@ std::vector<VkDeviceQueueCreateInfo> Device::GetDeviceQueueCreateInfos() const {
|
|||
return queue_cis;
|
||||
}
|
||||
|
||||
void Device::InitializeGPULogging() {
|
||||
if (!Settings::values.gpu_logging_enabled.GetValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Detect driver type
|
||||
const auto driver_id = GetDriverID();
|
||||
GPU::Logging::DriverType detected_driver = GPU::Logging::DriverType::Unknown;
|
||||
|
||||
if (driver_id == VK_DRIVER_ID_MESA_TURNIP) {
|
||||
detected_driver = GPU::Logging::DriverType::Turnip;
|
||||
} else if (driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY) {
|
||||
detected_driver = GPU::Logging::DriverType::Qualcomm;
|
||||
}
|
||||
|
||||
// Get log level from settings
|
||||
const auto log_level = static_cast<GPU::Logging::LogLevel>(
|
||||
static_cast<u32>(Settings::values.gpu_log_level.GetValue()));
|
||||
|
||||
// Initialize GPU logger
|
||||
GPU::Logging::GPULogger::GetInstance().Initialize(log_level, detected_driver);
|
||||
|
||||
// Configure feature flags
|
||||
GPU::Logging::GPULogger::GetInstance().EnableVulkanCallTracking(
|
||||
Settings::values.gpu_log_vulkan_calls.GetValue());
|
||||
GPU::Logging::GPULogger::GetInstance().EnableShaderDumps(
|
||||
Settings::values.gpu_log_shader_dumps.GetValue());
|
||||
GPU::Logging::GPULogger::GetInstance().EnableMemoryTracking(
|
||||
Settings::values.gpu_log_memory_tracking.GetValue());
|
||||
GPU::Logging::GPULogger::GetInstance().EnableDriverDebugInfo(
|
||||
Settings::values.gpu_log_driver_debug.GetValue());
|
||||
GPU::Logging::GPULogger::GetInstance().SetRingBufferSize(
|
||||
Settings::values.gpu_log_ring_buffer_size.GetValue());
|
||||
|
||||
// Log comprehensive driver and extension information
|
||||
if (Settings::values.gpu_log_driver_debug.GetValue()) {
|
||||
std::string driver_info;
|
||||
|
||||
// Device information
|
||||
const auto& props = properties.properties;
|
||||
driver_info += fmt::format("Device: {}\n", props.deviceName);
|
||||
driver_info += fmt::format("Driver Name: {}\n", properties.driver.driverName);
|
||||
driver_info += fmt::format("Driver Info: {}\n", properties.driver.driverInfo);
|
||||
|
||||
// Version information
|
||||
const u32 driver_version = props.driverVersion;
|
||||
const u32 api_version = props.apiVersion;
|
||||
driver_info += fmt::format("Driver Version: {}.{}.{}\n",
|
||||
VK_API_VERSION_MAJOR(driver_version),
|
||||
VK_API_VERSION_MINOR(driver_version),
|
||||
VK_API_VERSION_PATCH(driver_version));
|
||||
driver_info += fmt::format("Vulkan API Version: {}.{}.{}\n",
|
||||
VK_API_VERSION_MAJOR(api_version),
|
||||
VK_API_VERSION_MINOR(api_version),
|
||||
VK_API_VERSION_PATCH(api_version));
|
||||
driver_info += fmt::format("Driver ID: {}\n", static_cast<u32>(driver_id));
|
||||
|
||||
// Vendor and device IDs
|
||||
driver_info += fmt::format("Vendor ID: 0x{:04X}\n", props.vendorID);
|
||||
driver_info += fmt::format("Device ID: 0x{:04X}\n", props.deviceID);
|
||||
|
||||
// Extensions - separate QCOM extensions from others
|
||||
driver_info += "\n=== Loaded Vulkan Extensions ===\n";
|
||||
std::vector<std::string> qcom_exts;
|
||||
std::vector<std::string> other_exts;
|
||||
|
||||
for (const auto& ext : loaded_extensions) {
|
||||
if (ext.find("QCOM") != std::string::npos || ext.find("qcom") != std::string::npos) {
|
||||
qcom_exts.push_back(ext);
|
||||
} else {
|
||||
other_exts.push_back(ext);
|
||||
}
|
||||
}
|
||||
|
||||
// Log QCOM extensions first
|
||||
if (!qcom_exts.empty()) {
|
||||
driver_info += "\nQualcomm Proprietary Extensions:\n";
|
||||
for (const auto& ext : qcom_exts) {
|
||||
driver_info += fmt::format(" - {}\n", ext);
|
||||
}
|
||||
}
|
||||
|
||||
// Log other extensions
|
||||
if (!other_exts.empty()) {
|
||||
driver_info += "\nStandard Extensions:\n";
|
||||
for (const auto& ext : other_exts) {
|
||||
driver_info += fmt::format(" - {}\n", ext);
|
||||
}
|
||||
}
|
||||
|
||||
driver_info += fmt::format("\nTotal Extensions Loaded: {}\n", loaded_extensions.size());
|
||||
|
||||
GPU::Logging::GPULogger::GetInstance().LogDriverDebugInfo(driver_info);
|
||||
}
|
||||
}
|
||||
|
||||
void Device::ShutdownGPULogging() {
|
||||
if (GPU::Logging::GPULogger::GetInstance().IsInitialized()) {
|
||||
GPU::Logging::GPULogger::GetInstance().Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
|
|||
|
|
@ -929,6 +929,10 @@ public:
|
|||
return nvidia_arch;
|
||||
}
|
||||
|
||||
/// GPU logging integration
|
||||
void InitializeGPULogging();
|
||||
void ShutdownGPULogging();
|
||||
|
||||
private:
|
||||
/// Checks if the physical device is suitable and configures the object state
|
||||
/// with all necessary info about its properties.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
|
|
@ -22,6 +22,8 @@
|
|||
#include "video_core/vulkan_common/vulkan_device.h"
|
||||
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
#include "video_core/gpu_logging/gpu_logging.h"
|
||||
#include "common/settings.h"
|
||||
|
||||
namespace Vulkan {
|
||||
namespace {
|
||||
|
|
@ -107,7 +109,17 @@ namespace Vulkan {
|
|||
MemoryCommit::MemoryCommit(VmaAllocator alloc, VmaAllocation a,
|
||||
const VmaAllocationInfo &info) noexcept
|
||||
: allocator{alloc}, allocation{a}, memory{info.deviceMemory},
|
||||
offset{info.offset}, size{info.size}, mapped_ptr{info.pMappedData} {}
|
||||
offset{info.offset}, size{info.size}, mapped_ptr{info.pMappedData} {
|
||||
// Log GPU memory allocation
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
Settings::values.gpu_log_memory_tracking.GetValue()) {
|
||||
GPU::Logging::GPULogger::GetInstance().LogMemoryAllocation(
|
||||
reinterpret_cast<uintptr_t>(memory),
|
||||
static_cast<u64>(size),
|
||||
0 // Memory property flags (not easily available from VMA)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryCommit::~MemoryCommit() { Release(); }
|
||||
|
||||
|
|
@ -166,6 +178,15 @@ namespace Vulkan {
|
|||
|
||||
void MemoryCommit::Release() {
|
||||
if (allocation && allocator) {
|
||||
// Log GPU memory deallocation
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
Settings::values.gpu_log_memory_tracking.GetValue() &&
|
||||
memory != VK_NULL_HANDLE) {
|
||||
GPU::Logging::GPULogger::GetInstance().LogMemoryDeallocation(
|
||||
reinterpret_cast<uintptr_t>(memory)
|
||||
);
|
||||
}
|
||||
|
||||
if (mapped_ptr) {
|
||||
vmaUnmapMemory(allocator, allocation);
|
||||
mapped_ptr = nullptr;
|
||||
|
|
@ -218,7 +239,19 @@ namespace Vulkan {
|
|||
|
||||
VkImage handle{};
|
||||
VmaAllocation allocation{};
|
||||
vk::Check(vmaCreateImage(allocator, &ci, &alloc_ci, &handle, &allocation, nullptr));
|
||||
VmaAllocationInfo alloc_info{};
|
||||
vk::Check(vmaCreateImage(allocator, &ci, &alloc_ci, &handle, &allocation, &alloc_info));
|
||||
|
||||
// Log GPU memory allocation for images
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
Settings::values.gpu_log_memory_tracking.GetValue()) {
|
||||
GPU::Logging::GPULogger::GetInstance().LogMemoryAllocation(
|
||||
reinterpret_cast<uintptr_t>(alloc_info.deviceMemory),
|
||||
static_cast<u64>(alloc_info.size),
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
);
|
||||
}
|
||||
|
||||
return vk::Image(handle, ci.usage, *device.GetLogical(), allocator, allocation,
|
||||
device.GetDispatchLoader());
|
||||
}
|
||||
|
|
@ -245,6 +278,16 @@ namespace Vulkan {
|
|||
vk::Check(vmaCreateBuffer(allocator, &ci, &alloc_ci, &handle, &allocation, &alloc_info));
|
||||
vmaGetAllocationMemoryProperties(allocator, allocation, &property_flags);
|
||||
|
||||
// Log GPU memory allocation for buffers
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
Settings::values.gpu_log_memory_tracking.GetValue()) {
|
||||
GPU::Logging::GPULogger::GetInstance().LogMemoryAllocation(
|
||||
reinterpret_cast<uintptr_t>(alloc_info.deviceMemory),
|
||||
static_cast<u64>(alloc_info.size),
|
||||
property_flags
|
||||
);
|
||||
}
|
||||
|
||||
u8 *data = reinterpret_cast<u8 *>(alloc_info.pMappedData);
|
||||
const std::span<u8> mapped_data = data ? std::span<u8>{data, ci.size} : std::span<u8>{};
|
||||
const bool is_coherent = (property_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue