diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 2d6978f2fa..7d483f11ad 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -1391,7 +1391,7 @@ void VulkanDeleteList::PerformDeletes(VkDevice device) { } void VulkanContext::GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation) { - if (DeviceExtensions().KHR_dedicated_allocation) { + if (Extensions().KHR_dedicated_allocation) { VkImageMemoryRequirementsInfo2KHR memReqInfo2{VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR}; memReqInfo2.image = image; diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index 553580334d..a10692b88f 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -167,8 +167,6 @@ public: void BeginFrame(); void EndFrame(); - void SetDebugNameImpl(uint64_t handle, VkObjectType type, const char *name); - // Simple workaround for the casting warning. template void SetDebugName(T handle, VkObjectType type, const char *name) { @@ -177,6 +175,17 @@ public: } } + // Shorthand for the above, the most common types we want to tag. + void SetDebugName(VkImage image, const char *name) { + SetDebugName(image, VK_OBJECT_TYPE_IMAGE, name); + } + void SetDebugName(VkFramebuffer framebuf, const char *name) { + SetDebugName(framebuf, VK_OBJECT_TYPE_FRAMEBUFFER, name); + } + void SetDebugName(VkSampler sampler, const char *name) { + SetDebugName(sampler, VK_OBJECT_TYPE_SAMPLER, name); + } + bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex); VkPhysicalDevice GetPhysicalDevice(int n) const { @@ -277,13 +286,15 @@ public: MAX_INFLIGHT_FRAMES = 3, }; - const VulkanDeviceExtensions &DeviceExtensions() { return extensionsLookup_; } + const VulkanExtensions &Extensions() { return extensionsLookup_; } void GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation); private: bool ChooseQueue(); + void SetDebugNameImpl(uint64_t handle, VkObjectType type, const char *name); + VkResult InitDebugUtilsCallback(); // A layer can expose extensions, keep track of those extensions here. @@ -317,7 +328,7 @@ private: std::vector device_extensions_enabled_; std::vector device_extension_properties_; - VulkanDeviceExtensions extensionsLookup_{}; + VulkanExtensions extensionsLookup_{}; std::vector physical_devices_; diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp index 43298ec9c4..59b3fb5bd3 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/Vulkan/VulkanLoader.cpp @@ -489,7 +489,7 @@ bool VulkanLoad() { } } -void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensions &enabledExtensions) { +void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &enabledExtensions) { // OK, let's use the above functions to get the rest. LOAD_INSTANCE_FUNC(instance, vkDestroyInstance); LOAD_INSTANCE_FUNC(instance, vkEnumeratePhysicalDevices); @@ -554,7 +554,7 @@ void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensio // On some implementations, loading functions (that have Device as their first parameter) via vkGetDeviceProcAddr may // increase performance - but then these function pointers will only work on that specific device. Thus, this loader is not very // good for multi-device - not likely we'll ever try that anyway though. -void VulkanLoadDeviceFunctions(VkDevice device, const VulkanDeviceExtensions &enabledExtensions) { +void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions) { WLOG("Vulkan device functions loaded."); LOAD_DEVICE_FUNC(device, vkQueueSubmit); diff --git a/Common/Vulkan/VulkanLoader.h b/Common/Vulkan/VulkanLoader.h index e9c7f96156..c91ad6296c 100644 --- a/Common/Vulkan/VulkanLoader.h +++ b/Common/Vulkan/VulkanLoader.h @@ -215,7 +215,7 @@ extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; // For fast extension-enabled checks. -struct VulkanDeviceExtensions { +struct VulkanExtensions { bool EXT_debug_utils; bool KHR_maintenance1; // required for KHR_create_renderpass2 bool KHR_maintenance2; @@ -236,6 +236,6 @@ bool VulkanMayBeAvailable(); void VulkanSetAvailable(bool available); bool VulkanLoad(); -void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensions &enabledExtensions); -void VulkanLoadDeviceFunctions(VkDevice device, const VulkanDeviceExtensions &enabledExtensions); +void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &enabledExtensions); +void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions); void VulkanFree(); diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index b79459f769..b9f9b8966a 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -92,7 +92,7 @@ static bool LoadTextureLevels(const uint8_t *data, size_t size, ImageFileType ty return *num_levels > 0; } -bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type, bool generateMips) { +bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type, bool generateMips, const char *name) { generateMips_ = generateMips; using namespace Draw; @@ -131,7 +131,7 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag desc.depth = 1; desc.mipLevels = generateMips ? potentialLevels : num_levels; desc.generateMips = generateMips && potentialLevels > num_levels; - desc.tag = "LoadedFileData"; + desc.tag = name; for (int i = 0; i < num_levels; i++) { desc.initData.push_back(image[i]); } @@ -152,7 +152,7 @@ bool ManagedTexture::LoadFromFile(const std::string &filename, ImageFileType typ ELOG("Failed to read file '%s'", filename.c_str()); return false; } - bool retval = LoadFromFileData(buffer, fileSize, type, generateMips); + bool retval = LoadFromFileData(buffer, fileSize, type, generateMips, filename.c_str()); if (retval) { filename_ = filename; } else { @@ -206,7 +206,7 @@ std::unique_ptr CreateTextureFromFileData(Draw::DrawContext *dra if (!draw) return std::unique_ptr(); ManagedTexture *mtex = new ManagedTexture(draw); - if (mtex->LoadFromFileData(data, size, type, generateMips)) { + if (mtex->LoadFromFileData(data, size, type, generateMips, nullptr)) { return std::unique_ptr(mtex); } else { // Best to return a null pointer if we fail! diff --git a/UI/TextureUtil.h b/UI/TextureUtil.h index 6a93f4809b..61abbfc2c8 100644 --- a/UI/TextureUtil.h +++ b/UI/TextureUtil.h @@ -23,7 +23,7 @@ public: } bool LoadFromFile(const std::string &filename, ImageFileType type = ImageFileType::DETECT, bool generateMips = false); - bool LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type = ImageFileType::DETECT, bool generateMips = false); + bool LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type, bool generateMips, const char *name); Draw::Texture *GetTexture(); // For immediate use, don't store. int Width() const { return texture_->Width(); } int Height() const { return texture_->Height(); } diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 088af77b01..c1e2d34f00 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -447,7 +447,7 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &st } } - bool emitLabels = vulkan_->DeviceExtensions().EXT_debug_utils; + bool emitLabels = vulkan_->Extensions().EXT_debug_utils; for (size_t i = 0; i < steps.size(); i++) { const VKRStep &step = *steps[i]; diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 9f3c08a7d3..0122dc488e 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -11,6 +11,7 @@ #include #include "base/display.h" +#include "base/stringutil.h" #include "Common/Vulkan/VulkanContext.h" #include "math/dataconv.h" #include "math/math_util.h" @@ -30,19 +31,13 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int class VKRFramebuffer { public: - VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRenderPass renderPass, int _width, int _height) : vulkan_(vk) { + VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRenderPass renderPass, int _width, int _height, const char *tag) : vulkan_(vk) { width = _width; height = _height; CreateImage(vulkan_, initCmd, color, width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true); CreateImage(vulkan_, initCmd, depth, width, height, vulkan_->GetDeviceInfo().preferredDepthStencilFormat, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false); - vk->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, "fb_color"); - vk->SetDebugName(color.imageView, VK_OBJECT_TYPE_IMAGE_VIEW, "fb_color_view"); - - vk->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, "fb_depth"); - vk->SetDebugName(depth.imageView, VK_OBJECT_TYPE_IMAGE_VIEW, "fb_depth_view"); - VkFramebufferCreateInfo fbci{ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO }; VkImageView views[2]{}; @@ -56,6 +51,11 @@ public: fbci.layers = 1; vkCreateFramebuffer(vulkan_->GetDevice(), &fbci, nullptr, &framebuf); + if (vk->Extensions().EXT_debug_utils) { + vk->SetDebugName(color.image, StringFromFormat("fb_color_%s", tag).c_str()); + vk->SetDebugName(depth.image, StringFromFormat("fb_depth_%s", tag).c_str()); + vk->SetDebugName(framebuf, VK_OBJECT_TYPE_FRAMEBUFFER, StringFromFormat("fb_%s", tag).c_str()); + } } ~VKRFramebuffer() { diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 2ead85c2e4..d3ae7c20d4 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -311,6 +311,7 @@ struct FramebufferDesc { int numColorAttachments; bool z_stencil; FBColorDepth colorDepth; + const char *tag; // For graphics debuggers }; // Binary compatible with D3D11 viewport. @@ -536,7 +537,7 @@ struct TextureDesc { int depth; int mipLevels; bool generateMips; - // Optional, for tracking memory usage. + // Optional, for tracking memory usage and graphcis debuggers. std::string tag; // Does not take ownership over pointed-to data. std::vector initData; diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index a0b3a5f1d4..3c90511893 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -1462,7 +1462,7 @@ private: Framebuffer *VKContext::CreateFramebuffer(const FramebufferDesc &desc) { VkCommandBuffer cmd = renderManager_.GetInitCmd(); - VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetFramebufferRenderPass(), desc.width, desc.height); + VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetFramebufferRenderPass(), desc.width, desc.height, desc.tag); return new VKFramebuffer(vkrfb); }