diff --git a/IGLU/imgui/Session.cpp b/IGLU/imgui/Session.cpp index e1fb45a39d..ee69851450 100644 --- a/IGLU/imgui/Session.cpp +++ b/IGLU/imgui/Session.cpp @@ -235,6 +235,7 @@ Session::Renderer::Renderer(igl::IDevice& device) { width, height, igl::TextureDesc::TextureUsageBits::Sampled); + desc.debugName = "IGLU/imgui/Session.cpp:Session::Renderer::_fontTexture"; _fontTexture = device.createTexture(desc, nullptr); _fontTexture->upload(igl::TextureRangeDesc::new2D(0, 0, width, height), pixels); diff --git a/shell/renderSessions/ColorSession.cpp b/shell/renderSessions/ColorSession.cpp index e4ad9b5105..3c85ad3473 100644 --- a/shell/renderSessions/ColorSession.cpp +++ b/shell/renderSessions/ColorSession.cpp @@ -208,6 +208,7 @@ void ColorSession::initialize() noexcept { // Sampler & Texture SamplerStateDesc samplerDesc; samplerDesc.minFilter = samplerDesc.magFilter = SamplerMinMagFilter::Linear; + samplerDesc.debugName = "Sampler: linear"; samp0_ = device.createSamplerState(samplerDesc, nullptr); IGL_ASSERT(samp0_ != nullptr); diff --git a/shell/renderSessions/MRTSession.cpp b/shell/renderSessions/MRTSession.cpp index 82c1b56957..90cec0f458 100644 --- a/shell/renderSessions/MRTSession.cpp +++ b/shell/renderSessions/MRTSession.cpp @@ -308,6 +308,7 @@ void MRTSession::initialize() noexcept { // Sampler & Texture SamplerStateDesc samplerDesc; samplerDesc.minFilter = samplerDesc.magFilter = SamplerMinMagFilter::Linear; + samplerDesc.debugName = "Sampler: linear"; samp0_ = device.createSamplerState(samplerDesc, nullptr); tex0_ = getPlatform().loadTexture("igl.png"); @@ -452,6 +453,7 @@ std::shared_ptr MRTSession::createTexture2D(const std::shared_ptrupload(range, textureData.data()); diff --git a/shell/shared/platform/Platform.cpp b/shell/shared/platform/Platform.cpp index 300438f243..e10dd04bda 100644 --- a/shell/shared/platform/Platform.cpp +++ b/shell/shared/platform/Platform.cpp @@ -39,6 +39,7 @@ std::shared_ptr Platform::loadTexture(const char* filename, igl::TextureDesc::new2D(format, imageData.desc.width, imageData.desc.height, usage); texDesc.numMipLevels = calculateMipmapLevels ? igl::TextureDesc::calcNumMipLevels(texDesc.width, texDesc.height) : 1; + texDesc.debugName = filename; Result res; auto tex = getDevice().createTexture(texDesc, &res); diff --git a/src/igl/SamplerState.h b/src/igl/SamplerState.h index fee76370ce..3a5e350832 100644 --- a/src/igl/SamplerState.h +++ b/src/igl/SamplerState.h @@ -131,6 +131,7 @@ struct SamplerStateDesc { SamplerStateDesc desc; desc.minFilter = desc.magFilter = SamplerMinMagFilter::Linear; desc.mipFilter = SamplerMipFilter::Disabled; + desc.debugName = "newLinear()"; return desc; } @@ -146,6 +147,7 @@ struct SamplerStateDesc { SamplerStateDesc desc; desc.minFilter = desc.magFilter = SamplerMinMagFilter::Linear; desc.mipFilter = SamplerMipFilter::Linear; + desc.debugName = "newLinearMipmapped()"; return desc; } diff --git a/src/igl/ShaderCreator.cpp b/src/igl/ShaderCreator.cpp index ec37042f05..e0cd6f47c3 100644 --- a/src/igl/ShaderCreator.cpp +++ b/src/igl/ShaderCreator.cpp @@ -44,6 +44,8 @@ std::shared_ptr ShaderModuleCreator::fromBinaryInput(const IDevic std::string debugName, Result* IGL_NULLABLE outResult) { + IGL_PROFILER_FUNCTION_COLOR(IGL_PROFILER_COLOR_CREATE); + Result localResult; Result* result = outResult ? outResult : &localResult; IGL_ASSERT(result); @@ -66,6 +68,8 @@ std::unique_ptr ShaderLibraryCreator::fromStringInput( std::string fragmentEntryPoint, std::string libraryDebugName, Result* IGL_NULLABLE outResult) { + IGL_PROFILER_FUNCTION_COLOR(IGL_PROFILER_COLOR_CREATE); + Result localResult; Result* result = outResult ? outResult : &localResult; IGL_ASSERT(result); diff --git a/src/igl/vulkan/Texture.cpp b/src/igl/vulkan/Texture.cpp index 66d7e7be0d..7c26155303 100644 --- a/src/igl/vulkan/Texture.cpp +++ b/src/igl/vulkan/Texture.cpp @@ -185,7 +185,7 @@ Result Texture::create(const TextureDesc& desc) { return Result(Result::Code::InvalidOperation, "Cannot create VulkanImageView"); } - texture_ = ctx.createTexture(std::move(image), std::move(imageView)); + texture_ = ctx.createTexture(std::move(image), std::move(imageView), desc.debugName.c_str()); return Result(); } diff --git a/src/igl/vulkan/VulkanContext.cpp b/src/igl/vulkan/VulkanContext.cpp index 9fa9e9ba55..6012279469 100644 --- a/src/igl/vulkan/VulkanContext.cpp +++ b/src/igl/vulkan/VulkanContext.cpp @@ -370,6 +370,24 @@ VulkanContext::~VulkanContext() { dummyStorageBuffer_.reset(); dummyUniformBuffer_.reset(); +#if IGL_DEBUG + for (const auto& t : textures_) { + if (t.use_count() > 1) { + IGL_ASSERT_MSG(false, + "Leaked texture detected! %u %s", + t->getTextureId(), + debugNamesTextures_[t->getTextureId()].c_str()); + } + } + for (const auto& s : samplers_) { + if (s.use_count() > 1) { + IGL_ASSERT_MSG(false, + "Leaked sampler detected! %u %s", + s->getSamplerId(), + debugNamesSamplers_[s->getSamplerId()].c_str()); + } + } +#endif // IGL_DEBUG textures_.clear(); samplers_.clear(); @@ -1266,7 +1284,8 @@ void VulkanContext::checkAndUpdateDescriptorSets() { std::shared_ptr VulkanContext::createTexture( std::shared_ptr image, - std::shared_ptr imageView) const { + std::shared_ptr imageView, + [[maybe_unused]] const char* debugName) const { IGL_PROFILER_FUNCTION(); auto texture = std::make_shared(*this, std::move(image), std::move(imageView)); @@ -1283,6 +1302,14 @@ std::shared_ptr VulkanContext::createTexture( textures_.emplace_back(texture); } +#if IGL_DEBUG + const uint32_t id = texture->getTextureId(); + if (debugNamesTextures_.size() <= id) { + debugNamesTextures_.resize(id + 1); + } + debugNamesTextures_[id] = debugName; +#endif // IGL_DEBUG + awaitingCreation_ = true; return texture; @@ -1308,6 +1335,14 @@ std::shared_ptr VulkanContext::createSampler(const VkSamplerCreat samplers_.emplace_back(sampler); } +#if IGL_DEBUG + const uint32_t id = sampler->getSamplerId(); + if (debugNamesSamplers_.size() <= id) { + debugNamesSamplers_.resize(id + 1); + } + debugNamesSamplers_[id] = debugName; +#endif // IGL_DEBUG + awaitingCreation_ = true; return sampler; diff --git a/src/igl/vulkan/VulkanContext.h b/src/igl/vulkan/VulkanContext.h index 2c3d54c951..fbf2270e17 100644 --- a/src/igl/vulkan/VulkanContext.h +++ b/src/igl/vulkan/VulkanContext.h @@ -136,7 +136,8 @@ class VulkanContext final { igl::Result* outResult, const char* debugName = nullptr) const; std::shared_ptr createTexture(std::shared_ptr image, - std::shared_ptr imageView) const; + std::shared_ptr imageView, + const char* debugName) const; std::shared_ptr createSampler(const VkSamplerCreateInfo& ci, igl::Result* outResult, const char* debugName = nullptr) const; @@ -275,6 +276,11 @@ class VulkanContext final { VkPipelineCache pipelineCache_ = VK_NULL_HANDLE; +#if IGL_DEBUG + mutable std::vector debugNamesTextures_; + mutable std::vector debugNamesSamplers_; +#endif // IGL_DEBUG + // 1. Textures can be safely deleted once they are not in use by GPU, hence our Vulkan context // owns all allocated textures (images+image views). The IGL interface vulkan::Texture does not // delete the underylying VulkanTexture but instead informs the context that it should be diff --git a/src/igl/vulkan/VulkanSampler.h b/src/igl/vulkan/VulkanSampler.h index 1569d56c46..f5b5953611 100644 --- a/src/igl/vulkan/VulkanSampler.h +++ b/src/igl/vulkan/VulkanSampler.h @@ -42,6 +42,10 @@ class VulkanSampler final { return vkSampler_; } + uint32_t getSamplerId() const { + return samplerId_; + } + public: const VulkanContext& ctx_; VkDevice device_ = VK_NULL_HANDLE;