aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorMrPurple666 <antoniosacramento666usa@gmail.com>2026-02-01 02:02:23 +0100
committercrueter <crueter@eden-emu.dev>2026-02-01 02:02:23 +0100
commit6637810fe6c6610f73f0b1b12e56e9b48268d0ee (patch)
tree294b8dd7efc3df043b7502634ac14d6170c911eb /src/video_core/renderer_vulkan
parent8118557c17480d2eb5f1510de841f88cde13f2be (diff)
[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>
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.cpp19
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp23
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp23
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp43
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.cpp27
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp6
6 files changed, 137 insertions, 4 deletions
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
index 2d9c5d4148..96a9fe59e7 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
@@ -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 2019 yuzu Emulator Project
@@ -8,6 +8,7 @@
#include <vector>
#include <boost/container/small_vector.hpp>
+#include <fmt/format.h>
#include "video_core/renderer_vulkan/pipeline_helper.h"
#include "video_core/renderer_vulkan/pipeline_statistics.h"
@@ -20,6 +21,8 @@
#include "video_core/shader_notify.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"
+#include "common/settings.h"
namespace Vulkan {
@@ -82,6 +85,13 @@ ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipel
},
*pipeline_cache);
+ // Log compute pipeline creation
+ if (Settings::values.gpu_logging_enabled.GetValue()) {
+ GPU::Logging::GPULogger::GetInstance().LogPipelineStateChange(
+ "ComputePipeline created"
+ );
+ }
+
if (pipeline_statistics) {
pipeline_statistics->Collect(*pipeline);
}
@@ -207,6 +217,13 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
build_condvar.wait(lock, [this] { return is_built.load(std::memory_order::relaxed); });
});
}
+
+ // Log compute pipeline binding
+ if (Settings::values.gpu_logging_enabled.GetValue() &&
+ Settings::values.gpu_log_vulkan_calls.GetValue()) {
+ GPU::Logging::GPULogger::GetInstance().LogPipelineBind(true, "compute pipeline");
+ }
+
const void* const descriptor_data{guest_descriptor_queue.UpdateData()};
const bool is_rescaling = !info.texture_descriptors.empty() || !info.image_descriptors.empty();
scheduler.Record([this, descriptor_data, is_rescaling,
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index fca235b58e..d36553da4a 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -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 2021 yuzu Emulator Project
@@ -10,6 +10,7 @@
#include <boost/container/small_vector.hpp>
#include <boost/container/static_vector.hpp>
+#include <fmt/format.h>
#include "video_core/renderer_vulkan/pipeline_helper.h"
@@ -25,6 +26,8 @@
#include "video_core/shader_notify.h"
#include "video_core/texture_cache/texture_cache.h"
#include "video_core/vulkan_common/vulkan_device.h"
+#include "video_core/gpu_logging/gpu_logging.h"
+#include "common/settings.h"
#if defined(_MSC_VER) && defined(NDEBUG)
#define LAMBDA_FORCEINLINE [[msvc::forceinline]]
@@ -513,6 +516,14 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling,
const bool is_rescaling{texture_cache.IsRescaling()};
const bool update_rescaling{scheduler.UpdateRescaling(is_rescaling)};
const bool bind_pipeline{scheduler.UpdateGraphicsPipeline(this)};
+
+ // Log graphics pipeline binding
+ if (bind_pipeline && Settings::values.gpu_logging_enabled.GetValue() &&
+ Settings::values.gpu_log_vulkan_calls.GetValue()) {
+ const std::string pipeline_info = fmt::format("hash=0x{:016x}", key.Hash());
+ GPU::Logging::GPULogger::GetInstance().LogPipelineBind(false, pipeline_info);
+ }
+
const void* const descriptor_data{guest_descriptor_queue.UpdateData()};
scheduler.Record([this, descriptor_data, bind_pipeline, rescaling_data = rescaling.Data(),
is_rescaling, update_rescaling,
@@ -954,6 +965,16 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.basePipelineIndex = 0,
},
*pipeline_cache);
+
+ // Log graphics pipeline creation
+ if (Settings::values.gpu_logging_enabled.GetValue()) {
+ const std::string pipeline_info = fmt::format(
+ "GraphicsPipeline created: stages={}, attachments={}",
+ shader_stages.size(),
+ color_blend_ci.attachmentCount
+ );
+ GPU::Logging::GPULogger::GetInstance().LogPipelineStateChange(pipeline_info);
+ }
}
void GraphicsPipeline::Validate() {
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 6207e127c1..f3dd0f90d8 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -9,6 +9,7 @@
#include <fstream>
#include <iostream>
#include <memory>
+#include <span>
#include <thread>
#include <vector>
#include <bit>
@@ -42,6 +43,7 @@
#include "video_core/surface.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"
namespace Vulkan {
@@ -724,6 +726,17 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding, this->optimize_spirv_output)};
device.SaveShader(code);
modules[stage_index] = BuildShader(device, code);
+
+ // Log shader compilation to GPU logger (with SPIR-V binary dump if enabled)
+ if (Settings::values.gpu_logging_enabled.GetValue()) {
+ static constexpr std::array stage_names{"vertex", "tess_control", "tess_eval", "geometry", "fragment"};
+ const std::string shader_name = fmt::format("shader_{:016x}_{}", key.unique_hashes[index], stage_names[stage_index]);
+ const std::string shader_info = fmt::format("SPIR-V size: {} bytes, hash: {:016x}",
+ code.size() * sizeof(u32), key.unique_hashes[index]);
+ GPU::Logging::GPULogger::GetInstance().LogShaderCompilation(shader_name, shader_info,
+ std::span<const u32>(code.data(), code.size()));
+ }
+
if (device.HasDebuggingToolAttached()) {
const std::string name{fmt::format("Shader {:016x}", key.unique_hashes[index])};
modules[stage_index].SetObjectNameEXT(name.c_str());
@@ -831,6 +844,16 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
const std::vector<u32> code{EmitSPIRV(profile, program, this->optimize_spirv_output)};
device.SaveShader(code);
vk::ShaderModule spv_module{BuildShader(device, code)};
+
+ // Log compute shader compilation to GPU logger (with SPIR-V binary dump if enabled)
+ if (Settings::values.gpu_logging_enabled.GetValue()) {
+ const std::string shader_name = fmt::format("shader_{:016x}_compute", key.unique_hash);
+ const std::string shader_info = fmt::format("SPIR-V size: {} bytes, hash: {:016x}",
+ code.size() * sizeof(u32), key.unique_hash);
+ GPU::Logging::GPULogger::GetInstance().LogShaderCompilation(shader_name, shader_info,
+ std::span<const u32>(code.data(), code.size()));
+ }
+
if (device.HasDebuggingToolAttached()) {
const auto name{fmt::format("Shader {:016x}", key.unique_hash)};
spv_module.SetObjectNameEXT(name.c_str());
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index c3a5ed391b..60b899a811 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -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 2019 yuzu Emulator Project
@@ -9,6 +9,8 @@
#include <memory>
#include <mutex>
+#include <fmt/format.h>
+
#include "video_core/renderer_vulkan/renderer_vulkan.h"
#include "common/assert.h"
@@ -16,6 +18,7 @@
#include "common/scope_exit.h"
#include "common/settings.h"
#include "video_core/buffer_cache/buffer_cache.h"
+#include "video_core/gpu_logging/gpu_logging.h"
#include "video_core/control/channel_state.h"
#include "video_core/engines/draw_manager.h"
#include "video_core/engines/kepler_compute.h"
@@ -277,6 +280,20 @@ void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) {
}
});
}
+
+ // Log draw call
+ if (Settings::values.gpu_logging_enabled.GetValue() &&
+ Settings::values.gpu_log_vulkan_calls.GetValue()) {
+ const std::string params = is_indexed ?
+ fmt::format("vertices={}, instances={}, firstIndex={}, baseVertex={}, baseInstance={}",
+ draw_params.num_vertices, draw_params.num_instances,
+ draw_params.first_index, draw_params.base_vertex, draw_params.base_instance) :
+ fmt::format("vertices={}, instances={}, firstVertex={}, firstInstance={}",
+ draw_params.num_vertices, draw_params.num_instances,
+ draw_params.base_vertex, draw_params.base_instance);
+ GPU::Logging::GPULogger::GetInstance().LogVulkanCall(
+ is_indexed ? "vkCmdDrawIndexed" : "vkCmdDraw", params, VK_SUCCESS);
+ }
});
}
@@ -324,6 +341,16 @@ void RasterizerVulkan::DrawIndirect() {
static_cast<u32>(params.stride));
}
});
+
+ // Log indirect draw call
+ if (Settings::values.gpu_logging_enabled.GetValue() &&
+ Settings::values.gpu_log_vulkan_calls.GetValue()) {
+ const std::string log_params = fmt::format("drawCount={}, stride={}",
+ params.max_draw_counts, params.stride);
+ GPU::Logging::GPULogger::GetInstance().LogVulkanCall(
+ params.is_indexed ? "vkCmdDrawIndexedIndirect" : "vkCmdDrawIndirect",
+ log_params, VK_SUCCESS);
+ }
});
buffer_cache.SetDrawIndirect(nullptr);
}
@@ -568,6 +595,15 @@ void RasterizerVulkan::DispatchCompute() {
scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0, READ_BARRIER); });
scheduler.Record([dim](vk::CommandBuffer cmdbuf) { cmdbuf.Dispatch(dim[0], dim[1], dim[2]); });
+
+ // Log compute dispatch
+ if (Settings::values.gpu_logging_enabled.GetValue() &&
+ Settings::values.gpu_log_vulkan_calls.GetValue()) {
+ const std::string params = fmt::format("groupCountX={}, groupCountY={}, groupCountZ={}",
+ dim[0], dim[1], dim[2]);
+ GPU::Logging::GPULogger::GetInstance().LogVulkanCall(
+ "vkCmdDispatch", params, VK_SUCCESS);
+ }
}
void RasterizerVulkan::ResetCounter(VideoCommon::QueryType type) {
@@ -1066,6 +1102,11 @@ void RasterizerVulkan::HandleTransformFeedback() {
query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount,
regs.transform_feedback_enabled);
if (regs.transform_feedback_enabled != 0) {
+ // Log extension usage for transform feedback
+ if (Settings::values.gpu_logging_enabled.GetValue()) {
+ GPU::Logging::GPULogger::GetInstance().LogExtensionUsage(
+ "VK_EXT_transform_feedback", "HandleTransformFeedback");
+ }
UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) ||
regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation));
}
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp
index e19029812b..e526d606dc 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.cpp
+++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp
@@ -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 2019 yuzu Emulator Project
@@ -9,9 +9,13 @@
#include <thread>
#include <utility>
+#include <fmt/format.h>
+
#include "video_core/renderer_vulkan/vk_query_cache.h"
+#include "common/settings.h"
#include "common/thread.h"
+#include "video_core/gpu_logging/gpu_logging.h"
#include "video_core/renderer_vulkan/vk_command_pool.h"
#include "video_core/renderer_vulkan/vk_graphics_pipeline.h"
#include "video_core/renderer_vulkan/vk_master_semaphore.h"
@@ -114,6 +118,15 @@ void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) {
state.framebuffer = framebuffer_handle;
state.render_area = render_area;
+ // Log render pass begin
+ if (Settings::values.gpu_logging_enabled.GetValue() &&
+ Settings::values.gpu_log_vulkan_calls.GetValue()) {
+ const std::string render_pass_info = fmt::format(
+ "renderArea={}x{}, numImages={}",
+ render_area.width, render_area.height, framebuffer->NumImages());
+ GPU::Logging::GPULogger::GetInstance().LogRenderPassBegin(render_pass_info);
+ }
+
Record([renderpass, framebuffer_handle, render_area](vk::CommandBuffer cmdbuf) {
const VkRenderPassBeginInfo renderpass_bi{
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
@@ -270,6 +283,12 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se
switch (const VkResult result = master_semaphore->SubmitQueue(
cmdbuf, upload_cmdbuf, signal_semaphore, wait_semaphore, signal_value)) {
case VK_SUCCESS:
+ // Log successful queue submission
+ if (Settings::values.gpu_logging_enabled.GetValue() &&
+ Settings::values.gpu_log_vulkan_calls.GetValue()) {
+ GPU::Logging::GPULogger::GetInstance().LogVulkanCall(
+ "vkQueueSubmit", "", VK_SUCCESS);
+ }
break;
case VK_ERROR_DEVICE_LOST:
device.ReportLoss();
@@ -305,6 +324,12 @@ void Scheduler::EndRenderPass()
return;
}
+ // Log render pass end
+ if (Settings::values.gpu_logging_enabled.GetValue() &&
+ Settings::values.gpu_log_vulkan_calls.GetValue()) {
+ GPU::Logging::GPULogger::GetInstance().LogRenderPassEnd();
+ }
+
query_cache->CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, false);
query_cache->NotifySegment(false);
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 6ce7433240..39a43d5950 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -16,6 +16,7 @@
#include "common/settings.h"
#include "video_core/renderer_vulkan/vk_texture_cache.h"
+#include "video_core/gpu_logging/gpu_logging.h"
#include "video_core/engines/fermi_2d.h"
#include "video_core/renderer_vulkan/blit_image.h"
@@ -2304,6 +2305,11 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
const void* pnext = nullptr;
if (has_custom_border_colors) {
pnext = &border_ci;
+ // Log extension usage for custom border color
+ if (Settings::values.gpu_logging_enabled.GetValue()) {
+ GPU::Logging::GPULogger::GetInstance().LogExtensionUsage(
+ "VK_EXT_custom_border_color", "Sampler::Sampler");
+ }
}
const VkSamplerReductionModeCreateInfoEXT reduction_ci{
.sType = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT,