From 4d9eedd0d84732e170d4a0f1891d026af2c18bea Mon Sep 17 00:00:00 2001 From: Wunk Date: Thu, 7 Dec 2023 20:58:47 -0800 Subject: [PATCH] video_core/vulkan: Add debug object names (#7233) * vk_platform: Add `SetObjectName` Creates a name-info struct and automatically deduces the object handle type using vulkan-hpp's handle trait data. Supports `string_view` and `fmt` arguments. * vk_texture_runtime: Use `SetObjectName` for surface handles Names both the image handle and the image-view. * vk_stream_buffer: Add debug object names Names the buffer and its device memory based on its size and type. * vk_swapchain: Set swapchain handle debug names Identifies the swapchain images themselves as well as the semaphores * vk_present_window: Set handle debug names * vk_resource_pool: Set debug handle names * vk_blit_helper: Set debug handle names * vk_platform: Use `VulkanHandleType` concept Use a new `concept`-type rather than `enable_if`-patterns to restrict this function to Vulkan handle-types only. --- .../renderer_vulkan/vk_blit_helper.cpp | 22 ++++++++++++++++++- src/video_core/renderer_vulkan/vk_platform.h | 20 +++++++++++++++++ .../renderer_vulkan/vk_present_window.cpp | 11 ++++++++++ .../renderer_vulkan/vk_resource_pool.cpp | 9 ++++++++ .../renderer_vulkan/vk_stream_buffer.cpp | 10 ++++++++- .../renderer_vulkan/vk_swapchain.cpp | 15 +++++++++++++ .../renderer_vulkan/vk_texture_runtime.cpp | 15 +++++-------- 7 files changed, 91 insertions(+), 11 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_blit_helper.cpp b/src/video_core/renderer_vulkan/vk_blit_helper.cpp index b9b0875dac..4af2f0accd 100644 --- a/src/video_core/renderer_vulkan/vk_blit_helper.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_helper.cpp @@ -198,7 +198,27 @@ BlitHelper::BlitHelper(const Instance& instance_, Scheduler& scheduler_, Descrip MakeComputePipeline(depth_to_buffer_comp, compute_buffer_pipeline_layout)}, depth_blit_pipeline{MakeDepthStencilBlitPipeline()}, linear_sampler{device.createSampler(SAMPLER_CREATE_INFO)}, - nearest_sampler{device.createSampler(SAMPLER_CREATE_INFO)} {} + nearest_sampler{device.createSampler(SAMPLER_CREATE_INFO)} { + + if (instance.HasDebuggingToolAttached()) { + SetObjectName(device, compute_pipeline_layout, "BlitHelper: compute_pipeline_layout"); + SetObjectName(device, compute_buffer_pipeline_layout, + "BlitHelper: compute_buffer_pipeline_layout"); + SetObjectName(device, two_textures_pipeline_layout, + "BlitHelper: two_textures_pipeline_layout"); + SetObjectName(device, full_screen_vert, "BlitHelper: full_screen_vert"); + SetObjectName(device, d24s8_to_rgba8_comp, "BlitHelper: d24s8_to_rgba8_comp"); + SetObjectName(device, depth_to_buffer_comp, "BlitHelper: depth_to_buffer_comp"); + SetObjectName(device, blit_depth_stencil_frag, "BlitHelper: blit_depth_stencil_frag"); + SetObjectName(device, d24s8_to_rgba8_pipeline, "BlitHelper: d24s8_to_rgba8_pipeline"); + SetObjectName(device, depth_to_buffer_pipeline, "BlitHelper: depth_to_buffer_pipeline"); + if (depth_blit_pipeline) { + SetObjectName(device, depth_blit_pipeline, "BlitHelper: depth_blit_pipeline"); + } + SetObjectName(device, linear_sampler, "BlitHelper: linear_sampler"); + SetObjectName(device, nearest_sampler, "BlitHelper: nearest_sampler"); + } +} BlitHelper::~BlitHelper() { device.destroyPipelineLayout(compute_pipeline_layout); diff --git a/src/video_core/renderer_vulkan/vk_platform.h b/src/video_core/renderer_vulkan/vk_platform.h index 48ebcc90d2..20e9ebb0de 100644 --- a/src/video_core/renderer_vulkan/vk_platform.h +++ b/src/video_core/renderer_vulkan/vk_platform.h @@ -33,4 +33,24 @@ vk::UniqueInstance CreateInstance(const Common::DynamicLibrary& library, DebugCallback CreateDebugCallback(vk::Instance instance, bool& debug_utils_supported); +template +concept VulkanHandleType = vk::isVulkanHandleType::value; + +template +void SetObjectName(vk::Device device, const HandleType& handle, std::string_view debug_name) { + const vk::DebugUtilsObjectNameInfoEXT name_info = { + .objectType = HandleType::objectType, + .objectHandle = reinterpret_cast(static_cast(handle)), + .pObjectName = debug_name.data(), + }; + device.setDebugUtilsObjectNameEXT(name_info); +} + +template +void SetObjectName(vk::Device device, const HandleType& handle, const char* format, + const Args&... args) { + const std::string debug_name = fmt::vformat(format, fmt::make_format_args(args...)); + SetObjectName(device, handle, debug_name); +} + } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_present_window.cpp b/src/video_core/renderer_vulkan/vk_present_window.cpp index 82111d0b0a..273b20e8e9 100644 --- a/src/video_core/renderer_vulkan/vk_present_window.cpp +++ b/src/video_core/renderer_vulkan/vk_present_window.cpp @@ -11,6 +11,7 @@ #include "video_core/renderer_vulkan/vk_present_window.h" #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_swapchain.h" +#include "vk_platform.h" #include @@ -135,6 +136,16 @@ PresentWindow::PresentWindow(Frontend::EmuWindow& emu_window_, const Instance& i free_queue.push(&frame); } + if (instance.HasDebuggingToolAttached()) { + for (u32 i = 0; i < num_images; ++i) { + Vulkan::SetObjectName(device, swap_chain[i].cmdbuf, "Swapchain Command Buffer {}", i); + Vulkan::SetObjectName(device, swap_chain[i].render_ready, + "Swapchain Semaphore: render_ready {}", i); + Vulkan::SetObjectName(device, swap_chain[i].present_done, + "Swapchain Fence: present_done {}", i); + } + } + if (use_present_thread) { present_thread = std::jthread([this](std::stop_token token) { PresentThread(token); }); } diff --git a/src/video_core/renderer_vulkan/vk_resource_pool.cpp b/src/video_core/renderer_vulkan/vk_resource_pool.cpp index 02a5e22b7f..d74c4edc76 100644 --- a/src/video_core/renderer_vulkan/vk_resource_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_resource_pool.cpp @@ -101,6 +101,15 @@ void CommandPool::Allocate(std::size_t begin, std::size_t end) { auto buffers = device.allocateCommandBuffers(buffer_alloc_info); std::copy(buffers.begin(), buffers.end(), pool.cmdbufs.begin()); + + if (instance.HasDebuggingToolAttached()) { + Vulkan::SetObjectName(device, pool.handle, "CommandPool: Pool({})", + COMMAND_BUFFER_POOL_SIZE); + + for (u32 i = 0; i < pool.cmdbufs.size(); ++i) { + Vulkan::SetObjectName(device, pool.cmdbufs[i], "CommandPool: Command Buffer {}", i); + } + } } vk::CommandBuffer CommandPool::Commit() { diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp index 4690e69bfc..3ca77b1f85 100644 --- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp +++ b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp @@ -173,7 +173,7 @@ void StreamBuffer::CreateBuffers(u64 prefered_size) { stream_buffer_size = static_cast(requirements.memoryRequirements.size); - LOG_INFO(Render_Vulkan, "Creating {} buffer with size {} KB with flags {}", + LOG_INFO(Render_Vulkan, "Creating {} buffer with size {} KiB with flags {}", BufferTypeName(type), stream_buffer_size / 1024, vk::to_string(mem_type.propertyFlags)); @@ -198,6 +198,14 @@ void StreamBuffer::CreateBuffers(u64 prefered_size) { device.bindBufferMemory(buffer, memory, 0); mapped = reinterpret_cast(device.mapMemory(memory, 0, VK_WHOLE_SIZE)); + + if (instance.HasDebuggingToolAttached()) { + Vulkan::SetObjectName(device, buffer, "StreamBuffer({}): {} KiB {}", BufferTypeName(type), + stream_buffer_size / 1024, vk::to_string(mem_type.propertyFlags)); + Vulkan::SetObjectName(device, memory, "StreamBufferMemory({}): {} Kib {}", + BufferTypeName(type), stream_buffer_size / 1024, + vk::to_string(mem_type.propertyFlags)); + } } void StreamBuffer::ReserveWatches(std::vector& watches, std::size_t grow_size) { diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index ee83e03784..5e725be1ed 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -247,12 +247,27 @@ void Swapchain::RefreshSemaphores() { for (vk::Semaphore& semaphore : present_ready) { semaphore = device.createSemaphore({}); } + + if (instance.HasDebuggingToolAttached()) { + for (u32 i = 0; i < image_count; ++i) { + Vulkan::SetObjectName(device, image_acquired[i], + "Swapchain Semaphore: image_acquired {}", i); + Vulkan::SetObjectName(device, present_ready[i], "Swapchain Semaphore: present_ready {}", + i); + } + } } void Swapchain::SetupImages() { vk::Device device = instance.GetDevice(); images = device.getSwapchainImagesKHR(swapchain); image_count = static_cast(images.size()); + + if (instance.HasDebuggingToolAttached()) { + for (u32 i = 0; i < image_count; ++i) { + Vulkan::SetObjectName(device, images[i], "Swapchain Image {}", i); + } + } } } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp index 79458a70c1..8f2b3b93e1 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp @@ -189,15 +189,6 @@ Handle MakeHandle(const Instance* instance, u32 width, u32 height, u32 levels, T UNREACHABLE(); } - if (!debug_name.empty() && instance->HasDebuggingToolAttached()) { - const vk::DebugUtilsObjectNameInfoEXT name_info = { - .objectType = vk::ObjectType::eImage, - .objectHandle = reinterpret_cast(unsafe_image), - .pObjectName = debug_name.data(), - }; - instance->GetDevice().setDebugUtilsObjectNameEXT(name_info); - } - const vk::Image image{unsafe_image}; const vk::ImageViewCreateInfo view_info = { .image = image, @@ -214,6 +205,12 @@ Handle MakeHandle(const Instance* instance, u32 width, u32 height, u32 levels, T }; vk::UniqueImageView image_view = instance->GetDevice().createImageViewUnique(view_info); + if (!debug_name.empty() && instance->HasDebuggingToolAttached()) { + Vulkan::SetObjectName(instance->GetDevice(), image, debug_name); + Vulkan::SetObjectName(instance->GetDevice(), image_view.get(), "{} View({})", debug_name, + vk::to_string(aspect)); + } + return Handle{ .alloc = allocation, .image = image,