Browse Source

vulkan: Add debug object names

rdb 4 days ago
parent
commit
2e58044823

+ 1 - 1
panda/src/display/shaderInputBinding_impls.cxx

@@ -45,7 +45,7 @@ static Texture *
 get_white_texture() {
   Texture *tex = white_texture.p();
   if (tex == nullptr) {
-    tex = new Texture;
+    tex = new Texture("<white>");
     tex->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_rgba);
     tex->set_clear_color(LVecBase4(1, 1, 1, 1));
     tex->set_minfilter(SamplerState::FT_nearest);

+ 13 - 0
panda/src/vulkandisplay/vulkanGraphicsBuffer.cxx

@@ -769,6 +769,16 @@ create_attachment(RenderTexturePlane plane, VkFormat format, Texture *texture) {
       return false;
     }
 
+#ifndef NDEBUG
+    std::string debug_name;
+    if (plane == RTP_depth || plane == RTP_stencil || plane == RTP_depth_stencil) {
+      debug_name = get_name() + ":depth-stencil";
+    } else {
+      debug_name = get_name() + ":color";
+    }
+    vkgsg->set_object_name(tc->_image, debug_name);
+#endif
+
     VkImageViewCreateInfo view_info;
     view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
     view_info.pNext = nullptr;
@@ -813,6 +823,9 @@ create_attachment(RenderTexturePlane plane, VkFormat format, Texture *texture) {
       delete tc;
       return false;
     }
+#ifndef NDEBUG
+    vkgsg->set_object_name(image_view, debug_name);
+#endif
 
     tc->_image_views.push_back(image_view);
   }

+ 1 - 1
panda/src/vulkandisplay/vulkanGraphicsPipe.h

@@ -88,9 +88,9 @@ public:
   VkDeviceSize _max_allocation_size;
   uint32_t _max_inline_uniform_block_size = 0;
 
-private:
   PFN_vkSetDebugUtilsObjectNameEXT _vkSetDebugUtilsObjectName;
 
+private:
   bool _has_surface_ext;
   pmap<std::string, uint32_t> _instance_extensions;
   pmap<std::string, uint32_t> _device_extensions;

+ 65 - 0
panda/src/vulkandisplay/vulkanGraphicsStateGuardian.I

@@ -22,3 +22,68 @@ get_frame_data() {
   }
   return *_frame_data;
 }
+
+/**
+ *
+ */
+INLINE void VulkanGraphicsStateGuardian::
+set_object_name(VkObjectType type, void *handle, const char *name) {
+#ifndef NDEBUG
+  if (_vkSetDebugUtilsObjectName != nullptr) {
+    VkDebugUtilsObjectNameInfoEXT info = {};
+    info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
+    info.objectType = type;
+    info.objectHandle = (uint64_t)handle;
+    info.pObjectName = name;
+    _vkSetDebugUtilsObjectName(_device, &info);
+  }
+#endif
+}
+
+/**
+ *
+ */
+INLINE void VulkanGraphicsStateGuardian::
+set_object_name(VkBuffer object, const std::string &name) {
+  set_object_name(VK_OBJECT_TYPE_BUFFER, object, name.c_str());
+}
+
+/**
+ *
+ */
+INLINE void VulkanGraphicsStateGuardian::
+set_object_name(VkBufferView object, const std::string &name) {
+  set_object_name(VK_OBJECT_TYPE_BUFFER_VIEW, object, name.c_str());
+}
+
+/**
+ *
+ */
+INLINE void VulkanGraphicsStateGuardian::
+set_object_name(VkDescriptorSet object, const std::string &name) {
+  set_object_name(VK_OBJECT_TYPE_DESCRIPTOR_SET, object, name.c_str());
+}
+
+/**
+ *
+ */
+INLINE void VulkanGraphicsStateGuardian::
+set_object_name(VkImage object, const std::string &name) {
+  set_object_name(VK_OBJECT_TYPE_IMAGE, object, name.c_str());
+}
+
+/**
+ *
+ */
+INLINE void VulkanGraphicsStateGuardian::
+set_object_name(VkImageView object, const std::string &name) {
+  set_object_name(VK_OBJECT_TYPE_IMAGE_VIEW, object, name.c_str());
+}
+
+/**
+ *
+ */
+INLINE void VulkanGraphicsStateGuardian::
+set_object_name(VkSampler object, const std::string &name) {
+  set_object_name(VK_OBJECT_TYPE_SAMPLER, object, name.c_str());
+}

+ 35 - 2
panda/src/vulkandisplay/vulkanGraphicsStateGuardian.cxx

@@ -114,6 +114,8 @@ reset() {
   VulkanGraphicsPipe *pipe;
   DCAST_INTO_V(pipe, get_pipe());
 
+  _vkSetDebugUtilsObjectName = pipe->_vkSetDebugUtilsObjectName;
+
   const VkPhysicalDeviceLimits &limits = pipe->_gpu_properties.limits;
   const VkPhysicalDeviceFeatures &features = pipe->_gpu_features;
 
@@ -507,6 +509,7 @@ reset() {
       vulkan_error(err, "Failed to create shadow sampler object");
       return;
     }
+    set_object_name(_shadow_sampler, "<global shadow map sampler>");
 
     VkSampler immutable_samplers[num_shadow_maps];
     for (size_t i = 0; i < num_shadow_maps; ++i) {
@@ -548,6 +551,8 @@ reset() {
       vulkan_error(err, "Failed to allocate descriptor set for empty light attribute");
       return;
     }
+
+    set_object_name(_empty_lattr_descriptor_set, "<empty light attrib>");
   }
 
   // Create a uniform buffer that we'll use for everything.
@@ -567,6 +572,8 @@ reset() {
     }
     return;
   }
+  set_object_name(_uniform_buffer, "<global uniform buffer>");
+
   _uniform_buffer_ptr = _uniform_buffer_memory.map_persistent();
   if (_uniform_buffer_ptr == nullptr) {
     vulkandisplay_cat.error()
@@ -595,6 +602,7 @@ reset() {
     if (create_buffer(staging_buffer_size, _staging_buffer, _staging_buffer_memory,
                       VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
                       (VkMemoryPropertyFlagBits)(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))) {
+      set_object_name(_staging_buffer, "<staging buffer>");
       _staging_buffer_ptr = _staging_buffer_memory.map_persistent();
       if (_staging_buffer_ptr != nullptr) {
         _staging_buffer_allocator = CircularAllocator(staging_buffer_size, limits.optimalBufferCopyOffsetAlignment);
@@ -1362,6 +1370,10 @@ create_texture(VulkanTextureContext *tc) {
                       VK_SAMPLE_COUNT_1_BIT, usage, flags)) {
       return false;
     }
+    if (texture->has_name()) {
+      set_object_name(tc->_image, texture->get_name());
+    }
+
     tc->_mipmap_begin = mipmap_begin;
     tc->_mipmap_end = mipmap_end;
     tc->_generate_mipmaps = generate_mipmaps;
@@ -1480,6 +1492,12 @@ create_texture(VulkanTextureContext *tc) {
         return false;
       }
 
+#ifndef NDEBUG
+      if (_vkSetDebugUtilsObjectName != nullptr && texture->has_name()) {
+        set_object_name(image_view, texture->get_name() + ":view#" + format_string(view));
+      }
+#endif
+
       tc->_image_views.push_back(image_view);
       view_info.subresourceRange.baseArrayLayer += num_layers_per_view;
     }
@@ -1513,6 +1531,7 @@ create_texture(VulkanTextureContext *tc) {
                        VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
       return false;
     }
+    set_object_name(buffer, texture->get_name());
 
     if (vulkandisplay_cat.is_debug()) {
       vulkandisplay_cat.debug()
@@ -1543,6 +1562,12 @@ create_texture(VulkanTextureContext *tc) {
         return false;
       }
 
+#ifndef NDEBUG
+      if (_vkSetDebugUtilsObjectName != nullptr && texture->has_name()) {
+        set_object_name(buffer_view, texture->get_name() + ":view#" + format_string(view));
+      }
+#endif
+
       buffer_views.push_back(buffer_view);
       view_info.offset += view_size;
     }
@@ -3212,7 +3237,7 @@ begin_frame(Thread *current_thread, VkSemaphore wait_for) {
 
   // Make sure we have a white texture.
   if (_white_texture.is_null()) {
-    _white_texture = new Texture();
+    _white_texture = new Texture("<white>");
     _white_texture->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_rgba8);
     _white_texture->set_clear_color(LColor(1, 1, 1, 1));
     _white_texture->prepare_now(0, get_prepared_objects(), this);
@@ -3690,7 +3715,15 @@ begin_command_buffer(VkSemaphore wait_for) {
   VkResult err;
   err = vkBeginCommandBuffer(handle, &begin_info);
   if (err == VK_SUCCESS) {
-    return VulkanCommandBuffer(handle, _next_begin_command_buffer_seq++, wait_for);
+    auto seq = _next_begin_command_buffer_seq++;
+#ifndef NDEBUG
+    if (_vkSetDebugUtilsObjectName != nullptr) {
+      char name[22];
+      snprintf(name, sizeof(name), "#%llu", (unsigned long long)seq);
+      set_object_name(VK_OBJECT_TYPE_COMMAND_BUFFER, handle, name);
+    }
+#endif
+    return VulkanCommandBuffer(handle, seq, wait_for);
   } else {
     vulkan_error(err, "Can't begin command buffer");
     return VulkanCommandBuffer();

+ 9 - 0
panda/src/vulkandisplay/vulkanGraphicsStateGuardian.h

@@ -234,6 +234,14 @@ public:
   static bool lookup_image_format(VkFormat vk_format, Texture::Format &format,
                                   Texture::ComponentType &type);
 
+  INLINE void set_object_name(VkObjectType type, void *handle, const char *name);
+  INLINE void set_object_name(VkBuffer object, const std::string &name);
+  INLINE void set_object_name(VkBufferView object, const std::string &name);
+  INLINE void set_object_name(VkDescriptorSet object, const std::string &name);
+  INLINE void set_object_name(VkImage object, const std::string &name);
+  INLINE void set_object_name(VkImageView object, const std::string &name);
+  INLINE void set_object_name(VkSampler object, const std::string &name);
+
 public:
   VkDevice _device = VK_NULL_HANDLE;
   uint32_t _graphics_queue_family_index;
@@ -389,6 +397,7 @@ private:
   PFN_vkCmdSetPrimitiveRestartEnable _vkCmdSetPrimitiveRestartEnable;
   PFN_vkCmdSetPrimitiveTopology _vkCmdSetPrimitiveTopology;
   PFN_vkCmdWriteTimestamp2 _vkCmdWriteTimestamp2;
+  PFN_vkSetDebugUtilsObjectNameEXT _vkSetDebugUtilsObjectName;
   PFN_vkUpdateDescriptorSets _vkUpdateDescriptorSets;
 
   friend class VulkanGraphicsBuffer;

+ 29 - 0
panda/src/vulkandisplay/vulkanGraphicsWindow.cxx

@@ -1089,6 +1089,15 @@ create_swapchain() {
   // Now create an image view for each image.
   for (uint32_t i = 0; i < num_images; ++i) {
     SwapBuffer &buffer = _swap_buffers[i];
+
+#ifndef NDEBUG
+    std::string debug_name;
+    if (vkgsg->_vkSetDebugUtilsObjectName != nullptr) {
+      debug_name = get_name() + ":color#" + format_string(i);
+      vkgsg->set_object_name(images[i], debug_name);
+    }
+#endif
+
     buffer._tc = new VulkanTextureContext(pgo);
     buffer._tc->_image = images[i];
     buffer._tc->_format = swapchain_info.imageFormat;
@@ -1122,6 +1131,12 @@ create_swapchain() {
       return false;
     }
 
+#ifndef NDEBUG
+    if (!debug_name.empty()) {
+      vkgsg->set_object_name(image_view, debug_name);
+    }
+#endif
+
     buffer._tc->_image_views.push_back(image_view);
 
     // Create a semaphore that is signalled when we are finished rendering,
@@ -1145,6 +1160,10 @@ create_swapchain() {
       return false;
     }
 
+#ifndef NDEBUG
+    vkgsg->set_object_name(_depth_stencil_tc->_image, get_name() + ":depth-stencil");
+#endif
+
     VkImageViewCreateInfo view_info;
     view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
     view_info.pNext = nullptr;
@@ -1172,6 +1191,10 @@ create_swapchain() {
       return false;
     }
 
+#ifndef NDEBUG
+    vkgsg->set_object_name(depth_stencil_view, get_name() + ":depth-stencil");
+#endif
+
     _depth_stencil_tc->_image_views.push_back(depth_stencil_view);
   }
 
@@ -1187,6 +1210,9 @@ create_swapchain() {
       _ms_color_tc = nullptr;
       return false;
     }
+#ifndef NDEBUG
+    vkgsg->set_object_name(_ms_color_tc->_image, get_name() + ":ms-color");
+#endif
     _ms_color_tc->_aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT;
 
     VkImageViewCreateInfo view_info;
@@ -1211,6 +1237,9 @@ create_swapchain() {
       vulkan_error(err, "Failed to create image view for multisample color");
       return false;
     }
+#ifndef NDEBUG
+    vkgsg->set_object_name(ms_color_view, get_name() + ":ms-color");
+#endif
 
     _ms_color_tc->_image_views.push_back(ms_color_view);
   }