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.
This commit is contained in:
parent
59df319f48
commit
4d9eedd0d8
|
@ -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<vk::Filter::eLinear>)},
|
||||
nearest_sampler{device.createSampler(SAMPLER_CREATE_INFO<vk::Filter::eNearest>)} {}
|
||||
nearest_sampler{device.createSampler(SAMPLER_CREATE_INFO<vk::Filter::eNearest>)} {
|
||||
|
||||
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);
|
||||
|
|
|
@ -33,4 +33,24 @@ vk::UniqueInstance CreateInstance(const Common::DynamicLibrary& library,
|
|||
|
||||
DebugCallback CreateDebugCallback(vk::Instance instance, bool& debug_utils_supported);
|
||||
|
||||
template <typename T>
|
||||
concept VulkanHandleType = vk::isVulkanHandleType<T>::value;
|
||||
|
||||
template <VulkanHandleType HandleType>
|
||||
void SetObjectName(vk::Device device, const HandleType& handle, std::string_view debug_name) {
|
||||
const vk::DebugUtilsObjectNameInfoEXT name_info = {
|
||||
.objectType = HandleType::objectType,
|
||||
.objectHandle = reinterpret_cast<u64>(static_cast<typename HandleType::NativeType>(handle)),
|
||||
.pObjectName = debug_name.data(),
|
||||
};
|
||||
device.setDebugUtilsObjectNameEXT(name_info);
|
||||
}
|
||||
|
||||
template <VulkanHandleType HandleType, typename... Args>
|
||||
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
|
||||
|
|
|
@ -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 <vk_mem_alloc.h>
|
||||
|
||||
|
@ -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); });
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -173,7 +173,7 @@ void StreamBuffer::CreateBuffers(u64 prefered_size) {
|
|||
|
||||
stream_buffer_size = static_cast<u64>(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<u8*>(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<Watch>& watches, std::size_t grow_size) {
|
||||
|
|
|
@ -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<u32>(images.size());
|
||||
|
||||
if (instance.HasDebuggingToolAttached()) {
|
||||
for (u32 i = 0; i < image_count; ++i) {
|
||||
Vulkan::SetObjectName(device, images[i], "Swapchain Image {}", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
|
@ -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<u64>(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,
|
||||
|
|
Reference in New Issue