mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	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
					
				
					 7 changed files with 91 additions and 11 deletions
				
			
		|  | @ -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, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue