1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-08 01:54:15 +01:00

[dxvk] Add support for resource debug names

This commit is contained in:
Philip Rebohle 2025-01-07 14:10:23 +01:00 committed by Philip Rebohle
parent 7f4f927980
commit 2507820339
9 changed files with 187 additions and 27 deletions

View File

@ -19,6 +19,14 @@ namespace dxvk {
m_info (createInfo) { m_info (createInfo) {
m_allocator->registerResource(this); m_allocator->registerResource(this);
// Assign debug name to buffer
if (device->isDebugEnabled()) {
m_debugName = createDebugName(createInfo.debugName);
m_info.debugName = m_debugName.c_str();
} else {
m_info.debugName = nullptr;
}
// Create and assign actual buffer resource // Create and assign actual buffer resource
assignStorage(allocateStorage()); assignStorage(allocateStorage());
} }
@ -100,4 +108,32 @@ namespace dxvk {
return m_allocator->createBufferResource(info, allocationInfo, nullptr); return m_allocator->createBufferResource(info, allocationInfo, nullptr);
} }
void DxvkBuffer::setDebugName(const char* name) {
if (likely(!m_info.debugName))
return;
m_debugName = createDebugName(name);
m_info.debugName = m_debugName.c_str();
updateDebugName();
}
void DxvkBuffer::updateDebugName() {
if (m_storage->flags().test(DxvkAllocationFlag::OwnsBuffer)) {
VkDebugUtilsObjectNameInfoEXT nameInfo = { VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT };
nameInfo.objectType = VK_OBJECT_TYPE_BUFFER;
nameInfo.objectHandle = vk::getObjectHandle(m_bufferInfo.buffer);
nameInfo.pObjectName = m_info.debugName;
m_vkd->vkSetDebugUtilsObjectNameEXT(m_vkd->device(), &nameInfo);
}
}
std::string DxvkBuffer::createDebugName(const char* name) const {
return str::format(vk::isValidDebugName(name) ? name : "Buffer", " (", cookie(), ")");
}
} }

View File

@ -35,6 +35,9 @@ namespace dxvk {
/// Buffer create flags /// Buffer create flags
VkBufferCreateFlags flags = 0; VkBufferCreateFlags flags = 0;
/// Debug name.
const char* debugName = nullptr;
}; };
@ -341,6 +344,9 @@ namespace dxvk {
m_storage = std::move(slice); m_storage = std::move(slice);
m_bufferInfo = m_storage->getBufferInfo(); m_bufferInfo = m_storage->getBufferInfo();
if (unlikely(m_info.debugName))
updateDebugName();
// Implicitly invalidate views // Implicitly invalidate views
m_version += 1u; m_version += 1u;
return result; return result;
@ -406,6 +412,12 @@ namespace dxvk {
Rc<DxvkResourceAllocation> relocateStorage( Rc<DxvkResourceAllocation> relocateStorage(
DxvkAllocationModes mode); DxvkAllocationModes mode);
/**
* \brief Sets debug name for the backing resource
* \param [in] name New debug name
*/
void setDebugName(const char* name);
private: private:
Rc<vk::DeviceFn> m_vkd; Rc<vk::DeviceFn> m_vkd;
@ -429,6 +441,12 @@ namespace dxvk {
std::unordered_map<DxvkBufferViewKey, std::unordered_map<DxvkBufferViewKey,
DxvkBufferView, DxvkHash, DxvkEq> m_views; DxvkBufferView, DxvkHash, DxvkEq> m_views;
std::string m_debugName;
void updateDebugName();
std::string createDebugName(const char* name) const;
}; };

View File

@ -2495,6 +2495,14 @@ namespace dxvk {
} }
void DxvkContext::setDebugName(const Rc<DxvkPagedResource>& resource, const char* name) {
if (!m_device->isDebugEnabled())
return;
resource->setDebugName(name);
}
void DxvkContext::blitImageFb( void DxvkContext::blitImageFb(
Rc<DxvkImageView> dstView, Rc<DxvkImageView> dstView,
const VkOffset3D* dstOffsets, const VkOffset3D* dstOffsets,

View File

@ -1365,6 +1365,14 @@ namespace dxvk {
m_cmd->addStatCtr(counter, value); m_cmd->addStatCtr(counter, value);
} }
/**
* \brief Sets new debug name for a resource
*
* \param [in] buffer Buffer object
* \param [in] name New debug name, or \c nullptr
*/
void setDebugName(const Rc<DxvkPagedResource>& resource, const char* name);
private: private:
Rc<DxvkDevice> m_device; Rc<DxvkDevice> m_device;

View File

@ -18,6 +18,14 @@ namespace dxvk {
copyFormatList(createInfo.viewFormatCount, createInfo.viewFormats); copyFormatList(createInfo.viewFormatCount, createInfo.viewFormats);
// Assign debug name to image
if (device->isDebugEnabled()) {
m_debugName = createDebugName(createInfo.debugName);
m_info.debugName = m_debugName.c_str();
} else {
m_info.debugName = nullptr;
}
// Always enable depth-stencil attachment usage for depth-stencil // Always enable depth-stencil attachment usage for depth-stencil
// formats since some internal operations rely on it. Read-only // formats since some internal operations rely on it. Read-only
// versions of these make little sense to begin with. // versions of these make little sense to begin with.
@ -228,6 +236,9 @@ namespace dxvk {
m_info.viewFormats = m_viewFormats.data(); m_info.viewFormats = m_viewFormats.data();
} }
if (unlikely(m_info.debugName))
updateDebugName();
m_stableAddress |= usageInfo.stableGpuAddress; m_stableAddress |= usageInfo.stableGpuAddress;
return old; return old;
} }
@ -283,6 +294,34 @@ namespace dxvk {
} }
void DxvkImage::setDebugName(const char* name) {
if (likely(!m_info.debugName))
return;
m_debugName = createDebugName(name);
m_info.debugName = m_debugName.c_str();
updateDebugName();
}
void DxvkImage::updateDebugName() {
if (m_storage->flags().test(DxvkAllocationFlag::OwnsImage)) {
VkDebugUtilsObjectNameInfoEXT nameInfo = { VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT };
nameInfo.objectType = VK_OBJECT_TYPE_IMAGE;
nameInfo.objectHandle = vk::getObjectHandle(m_imageInfo.image);
nameInfo.pObjectName = m_info.debugName;
m_vkd->vkSetDebugUtilsObjectNameEXT(m_vkd->device(), &nameInfo);
}
}
std::string DxvkImage::createDebugName(const char* name) const {
return str::format(vk::isValidDebugName(name) ? name : "Image", " (", cookie(), ")");
}
VkImageCreateInfo DxvkImage::getImageCreateInfo( VkImageCreateInfo DxvkImage::getImageCreateInfo(
const DxvkImageUsageInfo& usageInfo) const { const DxvkImageUsageInfo& usageInfo) const {
VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };

View File

@ -66,6 +66,9 @@ namespace dxvk {
// Shared handle info // Shared handle info
DxvkSharedHandleInfo sharing = { }; DxvkSharedHandleInfo sharing = { };
// Debug name
const char* debugName = nullptr;
}; };
@ -601,6 +604,12 @@ namespace dxvk {
bool isInitialized( bool isInitialized(
const VkImageSubresourceRange& subresources) const; const VkImageSubresourceRange& subresources) const;
/**
* \brief Sets debug name for the backing resource
* \param [in] name New debug name
*/
void setDebugName(const char* name);
private: private:
Rc<vk::DeviceFn> m_vkd; Rc<vk::DeviceFn> m_vkd;
@ -626,6 +635,12 @@ namespace dxvk {
std::unordered_map<DxvkImageViewKey, std::unordered_map<DxvkImageViewKey,
DxvkImageView, DxvkHash, DxvkEq> m_views; DxvkImageView, DxvkHash, DxvkEq> m_views;
std::string m_debugName;
void updateDebugName();
std::string createDebugName(const char* name) const;
VkImageCreateInfo getImageCreateInfo( VkImageCreateInfo getImageCreateInfo(
const DxvkImageUsageInfo& usageInfo) const; const DxvkImageUsageInfo& usageInfo) const;

View File

@ -752,6 +752,8 @@ namespace dxvk {
memoryRequirements.memoryTypeBits = findGlobalBufferMemoryTypeMask(createInfo.usage); memoryRequirements.memoryTypeBits = findGlobalBufferMemoryTypeMask(createInfo.usage);
if (likely(memoryRequirements.memoryTypeBits)) { if (likely(memoryRequirements.memoryTypeBits)) {
bool allowSuballocation = true;
// If the given allocation cache supports the memory types and usage // If the given allocation cache supports the memory types and usage
// flags that we need, try to use it to service this allocation. // flags that we need, try to use it to service this allocation.
// Only use the allocation cache for mappable allocations since those // Only use the allocation cache for mappable allocations since those
@ -769,11 +771,16 @@ namespace dxvk {
// for any relevant memory pools as necessary. // for any relevant memory pools as necessary.
if (refillAllocationCache(allocationCache, memoryRequirements, allocationInfo.properties)) if (refillAllocationCache(allocationCache, memoryRequirements, allocationInfo.properties))
return allocationCache->allocateFromCache(createInfo.size); return allocationCache->allocateFromCache(createInfo.size);
} else {
// Do not suballocate buffers if debug mode is enabled in order
// to allow the application to set meaningful debug names.
allowSuballocation = !m_device->isDebugEnabled();
} }
// If there is at least one memory type that supports the required // If there is at least one memory type that supports the required
// buffer usage flags and requested memory properties, suballocate // buffer usage flags and requested memory properties, suballocate
// from a global buffer. // from a global buffer.
if (likely(allowSuballocation)) {
allocation = allocateMemory(memoryRequirements, allocationInfo); allocation = allocateMemory(memoryRequirements, allocationInfo);
if (likely(allocation && allocation->m_buffer)) if (likely(allocation && allocation->m_buffer))
@ -810,6 +817,7 @@ namespace dxvk {
} }
} }
} }
}
// If we can't suballocate from an existing global buffer // If we can't suballocate from an existing global buffer
// for any reason, create a dedicated buffer resource. // for any reason, create a dedicated buffer resource.

View File

@ -604,6 +604,18 @@ namespace dxvk {
virtual Rc<DxvkResourceAllocation> relocateStorage( virtual Rc<DxvkResourceAllocation> relocateStorage(
DxvkAllocationModes mode) = 0; DxvkAllocationModes mode) = 0;
/**
* \brief Sets debug name for the backing resource
*
* The caller \e must ensure that the backing resource
* is not being swapped out at the same time. This may
* also be ignored for certain types of resources for
* performance reasons, and has no effect if the device
* does not have debug layers enabled.
* \param [in] name New debug name
*/
virtual void setDebugName(const char* name) = 0;
private: private:
std::atomic<uint64_t> m_useCount = { 0u }; std::atomic<uint64_t> m_useCount = { 0u };

View File

@ -211,6 +211,22 @@ namespace dxvk::vk {
} }
} }
inline uint64_t getObjectHandle(uint64_t handle) {
return handle;
}
template<typename T>
uint64_t getObjectHandle(T* object) {
return reinterpret_cast<uintptr_t>(object);
}
inline bool isValidDebugName(const char* name) {
return name && name[0];
}
} }