Skip to content

Commit

Permalink
igl | vulkan | Detect leaked textures/samplers
Browse files Browse the repository at this point in the history
Summary: Detect leaked textures/samplers.

Reviewed By: EricGriffith

Differential Revision: D51226390

fbshipit-source-id: a0cc50c8fabcf0a2132c6151749c00f2722ee291
  • Loading branch information
corporateshark authored and facebook-github-bot committed Nov 15, 2023
1 parent 6bb7333 commit 36c79cf
Show file tree
Hide file tree
Showing 13 changed files with 63 additions and 3 deletions.
1 change: 1 addition & 0 deletions IGLU/imgui/Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions shell/renderSessions/ColorSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions shell/renderSessions/MRTSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -452,6 +453,7 @@ std::shared_ptr<ITexture> MRTSession::createTexture2D(const std::shared_ptr<ITex
dimensions.height,
TextureDesc::TextureUsageBits::Attachment |
TextureDesc::TextureUsageBits::Sampled);
desc.debugName = "shell/renderSessions/MRTSession.cpp:MRTSession::createTexture2D()";

return getPlatform().getDevice().createTexture(desc, nullptr);
}
Expand Down
1 change: 1 addition & 0 deletions shell/renderSessions/TQMultiRenderPassSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ void TQMultiRenderPassSession::initialize() noexcept {
// Sampler & Texture
SamplerStateDesc samplerDesc;
samplerDesc.minFilter = samplerDesc.magFilter = SamplerMinMagFilter::Linear;
samplerDesc.debugName = "Sampler: linear";
samplerState_ = device.createSamplerState(samplerDesc, nullptr);
tex0_ = getPlatform().loadTexture("igl.png");

Expand Down
1 change: 1 addition & 0 deletions shell/renderSessions/TQSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ void TQSession::initialize() noexcept {
// Sampler & Texture
SamplerStateDesc samplerDesc;
samplerDesc.minFilter = samplerDesc.magFilter = SamplerMinMagFilter::Linear;
samplerDesc.debugName = "Sampler: linear";
_samp0 = device.createSamplerState(samplerDesc, NULL);
IGL_ASSERT(_samp0 != nullptr);
_tex0 = getPlatform().loadTexture("igl.png");
Expand Down
2 changes: 2 additions & 0 deletions shell/renderSessions/Textured3DCubeSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ void Textured3DCubeSession::createSamplerAndTextures(const igl::IDevice& device)
samplerDesc.addressModeU = SamplerAddressMode::MirrorRepeat;
samplerDesc.addressModeV = SamplerAddressMode::MirrorRepeat;
samplerDesc.addressModeW = SamplerAddressMode::MirrorRepeat;
samplerDesc.debugName = "Sampler: linear (MirrorRepeat)";
samp0_ = device.createSamplerState(samplerDesc, nullptr);

uint32_t width = 256;
Expand Down Expand Up @@ -260,6 +261,7 @@ void Textured3DCubeSession::createSamplerAndTextures(const igl::IDevice& device)
height,
depth,
igl::TextureDesc::TextureUsageBits::Sampled);
texDesc.debugName = "shell/renderSessions/Textured3DCubeSession.cpp:tex0_";
tex0_ = getPlatform().getDevice().createTexture(texDesc, nullptr);
const auto range = igl::TextureRangeDesc::new3D(0, 0, 0, width, height, depth);
tex0_->upload(range, textureData.data());
Expand Down
1 change: 1 addition & 0 deletions shell/shared/platform/Platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ std::shared_ptr<ITexture> 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);
Expand Down
2 changes: 2 additions & 0 deletions src/igl/SamplerState.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ struct SamplerStateDesc {
SamplerStateDesc desc;
desc.minFilter = desc.magFilter = SamplerMinMagFilter::Linear;
desc.mipFilter = SamplerMipFilter::Disabled;
desc.debugName = "newLinear()";
return desc;
}

Expand All @@ -146,6 +147,7 @@ struct SamplerStateDesc {
SamplerStateDesc desc;
desc.minFilter = desc.magFilter = SamplerMinMagFilter::Linear;
desc.mipFilter = SamplerMipFilter::Linear;
desc.debugName = "newLinearMipmapped()";
return desc;
}

Expand Down
4 changes: 4 additions & 0 deletions src/igl/ShaderCreator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ std::shared_ptr<IShaderModule> 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);
Expand All @@ -66,6 +68,8 @@ std::unique_ptr<IShaderLibrary> 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);
Expand Down
2 changes: 1 addition & 1 deletion src/igl/vulkan/Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
37 changes: 36 additions & 1 deletion src/igl/vulkan/VulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -1266,7 +1284,8 @@ void VulkanContext::checkAndUpdateDescriptorSets() {

std::shared_ptr<VulkanTexture> VulkanContext::createTexture(
std::shared_ptr<VulkanImage> image,
std::shared_ptr<VulkanImageView> imageView) const {
std::shared_ptr<VulkanImageView> imageView,
[[maybe_unused]] const char* debugName) const {
IGL_PROFILER_FUNCTION();

auto texture = std::make_shared<VulkanTexture>(*this, std::move(image), std::move(imageView));
Expand All @@ -1283,6 +1302,14 @@ std::shared_ptr<VulkanTexture> 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;
Expand All @@ -1308,6 +1335,14 @@ std::shared_ptr<VulkanSampler> 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;
Expand Down
8 changes: 7 additions & 1 deletion src/igl/vulkan/VulkanContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ class VulkanContext final {
igl::Result* outResult,
const char* debugName = nullptr) const;
std::shared_ptr<VulkanTexture> createTexture(std::shared_ptr<VulkanImage> image,
std::shared_ptr<VulkanImageView> imageView) const;
std::shared_ptr<VulkanImageView> imageView,
const char* debugName) const;
std::shared_ptr<VulkanSampler> createSampler(const VkSamplerCreateInfo& ci,
igl::Result* outResult,
const char* debugName = nullptr) const;
Expand Down Expand Up @@ -275,6 +276,11 @@ class VulkanContext final {

VkPipelineCache pipelineCache_ = VK_NULL_HANDLE;

#if IGL_DEBUG
mutable std::vector<std::string> debugNamesTextures_;
mutable std::vector<std::string> 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
Expand Down
4 changes: 4 additions & 0 deletions src/igl/vulkan/VulkanSampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class VulkanSampler final {
return vkSampler_;
}

uint32_t getSamplerId() const {
return samplerId_;
}

public:
const VulkanContext& ctx_;
VkDevice device_ = VK_NULL_HANDLE;
Expand Down

0 comments on commit 36c79cf

Please sign in to comment.